Index

Curl

MMO\core\server · 1 symbol · generated 5 Oct 2026

class

Curl

Curl.php:24

A curl extension wrapper: builds up request options fluently (setHeaders/setCookies/...), then

class MMO\core\server\Curl implements MMO\core\interfaces\iLogEmitter use MMO\core\classes\tLogEmitter, MMO\core\classes\tWithOptions
Namespace
MMO\core\server
Implements
iLogEmitter
Uses traits
tLogEmitter, tWithOptions
See
exec's them into a StreamResponse -- one instance handles one request at a time (exec throws on a second concurrent call, though a new call after a previous one finished is fine, since exec closes its handle before returning).
$curl = new Curl(); $curl->setUserAgent('MyApp/1.0'); $response = $curl->exec('https://example.com/api', ['name' => 'bar']); // POST, urlencoded by default $response->getStatusCode(); // 200 $response->render(); // the response body

Index

OPTIONS_TEXT
cookies
handle
headers
opts
responses
stream
verbosity
accept($accept)Set the Accept header, replacing any previous one set via this method (addHeaders would add a duplicate instead).
addHeaders($headers)
addOptions($opts, $appendList)Merge $opts into the existing options (through merge), rather than replacing them wholesale like setOptions.
alert($message, $context)Action must be taken immediately.
backtraces($message, $context)Force-log a message at INFO level together with a full stack trace/memory snapshot (iLogLevel::BACKTRACE), bypassing the verbosity mask entirely (any non-zero verbosity is enough to trigger it).
clearOptions()Empty the options bag.
close()Release the current curl handle, if any (exec calls this itself once done).
critical($message, $context)Critical conditions. No-op if CRITICAL is currently filtered out by the verbosity mask.
debug($message, $context)Detailed debug information.
debugName()Human-readable identifier used as the default {origin} in this instance's log messages.
DebugOptions($opts) staticConvert a raw curl_setopt-ready options array (CURLOPT_* constant => value) into a human-readable one ('CURLOPT_*' name => value, per OPTIONS_TEXT), additionally decoding CURLOPT_HTTPHEADE…
emergency($message, $context)System is unusable. No-op if EMERGENCY is currently filtered out by the verbosity mask.
error($message, $context)Runtime errors that do not require immediate action but should typically be logged and monitored.
exec($url, $post, $opts)Execute a CURL request and return the response
execHead($url, $post, $opts)Execute a curl request as HEAD (no body for response) -- the response's body ends up containing the raw header text instead (curl's CURLOPT_HEADER effect), since no actual body is fetched (CURLOPT_…
execOrThrow($url, $post, $opts)Same as exec, but throws if the response's status isn't a 2xx (iResponse::isOk).
FromString($curl, $debug) staticParse a curl ... shell command (e.g.
getCookies()
getFollowRedirection()
getHeaders()
getOption($key, $default)
getOptions()
getResponse()
getResponses()
getUserAgent()
getVerbosity()
handleCurlHeader($handle, $header)CURLOPT_HEADERFUNCTION callback (set by exec) -- curl calls this once per response header line, accumulating them into $headers, extracting cookies into $cookies, and (once the bla…
info($message, $context)Interesting events. No-op if INFO is currently filtered out by the verbosity mask.
log($level, $message, $context)Logs with an arbitrary level.
notice($message, $context)Normal but significant events.
setCookies($readFrom, $writeTo)Set filenames for the cookies
setFollowRedirection($follow)
setHeaders($headers)
setOption($key, $value)Set (or, with a null $value, remove) a single option.
setOptions($opts)Replace the whole options bag.
setReferer($referer)
setUserAgent($value)
setVerbosity($verb)Set the current verbosity mask, replacing whatever it was before.
testVerbosity($level)Test whether a given level (or set of levels) is currently enabled by this instance's verbosity mask.
warning($message, $context)Exceptional occurrences that are not errors.
__construct()

Constants1

OPTIONS_TEXT

const OPTIONS_TEXT = […169 items]
See
DebugOptions -- maps every known CURLOPT_* constant back to its own name, for human-readable debug output.

Properties7

cookies

#[MMO\core\attributes\Serialize(false)] protected array $cookies = []
Type
array

handle

#[MMO\core\attributes\Serialize(false)] protected $handle = null

headers

#[MMO\core\attributes\Serialize(false)] protected array $headers = []
Type
array

opts

protected array $opts = []
Type
array

responses

#[MMO\core\attributes\Serialize(false)] protected array $responses = []
Type
array

stream

#[MMO\core\attributes\Serialize(false)] protected ?MMO\core\server\Stream $stream
Type
null | Stream

verbosity

#[MMO\core\attributes\Serialize(order: -1000)] protected int $verbosity = 31
Type
int

Methods41

accept($accept)

Curl.php:177

Set the Accept header, replacing any previous one set via this method (addHeaders would add a duplicate instead).

function accept(string $accept): self
$acceptstringe.g. 'application/json'.
returnsself

addHeaders($headers)

Curl.php:142
function addHeaders(array $headers): self
$headersarrayeither ['Name' => 'value', ...] (or ['Name' => ['v1', 'v2']], joined with ;), or a plain list of already-formatted "Name: value" lines.
returnsself
$curl->addHeaders(['Content-Type' => 'application/json', 'X-Foo: bar']);

addOptions($opts, $appendList)

tWithOptions.php:65

Merge $opts into the existing options (through merge), rather than replacing them wholesale like setOptions.

function addOptions(array $opts, bool $appendList = false): void
$optsarraythe options to merge in
$appendList = falseboolif true, a list-valued option is appended to (rather than replaced by) the corresponding list in $opts -- see \MMO\core\arrays\merge for the exact semantics
returnsvoid
$t->setOptions(['a' => 1, 'tags' => ['x']]); $t->addOptions(['b' => 2, 'tags' => ['y']]); $t->getOptions(); // ['a' => 1, 'tags' => ['y'], 'b' => 2] -- 'tags' is replaced, not appended ($appendList=false)

alert($message, $context)

tLogEmitter.php:121

Action must be taken immediately.

function alert(Stringable|string $message, array $context = []): voidExample: Entire website down, database unavailable, etc. This should trigger the SMS alerts and wake you up.
$messageStringable | string
$context = []array
returnsvoid
$this->alert('payment gateway unreachable for 5 minutes.');

backtraces($message, $context)

tLogEmitter.php:234

Force-log a message at INFO level together with a full stack trace/memory snapshot (iLogLevel::BACKTRACE), bypassing the verbosity mask entirely (any non-zero verbosity is enough to trigger it).

function backtraces(string $message = ' -- TRACES -- ', array $context = []): void
$message = ' -- TRACES -- 'string
$context = []array
returnsvoid
$this->backtraces('unexpected state reached in {method}.', ['method' => __METHOD__]);

clearOptions()

tWithOptions.php:39

Empty the options bag.

function clearOptions(): void
returnsvoid
$t->clearOptions(); // getOptions() === []

close()

Curl.php:388

Release the current curl handle, if any (exec calls this itself once done).

function close(): void
returnsvoid

critical($message, $context)

tLogEmitter.php:138

Critical conditions. No-op if CRITICAL is currently filtered out by the verbosity mask.

function critical(Stringable|string $message, array $context = []): voidExample : Application component unavailable, unexpected exception.
$messageStringable | string
$context = []array
returnsvoid
$this->critical('unexpected {exception}.', ['exception' => $e]);

debug($message, $context)

tLogEmitter.php:219

Detailed debug information. No-op if DEBUG is currently filtered out by the verbosity mask.

function debug(Stringable|string $message, array $context = []): void
$messageStringable | string
$context = []array
returnsvoid
$this->debug('set stream [{stream}].', ['stream' => $stream]);

debugName()

tLogEmitter.php:30

Human-readable identifier used as the default {origin} in this instance's log messages.

function debugName(): stringOverride this in a class using the trait to show something more specific than the bare classname.
returnsstring

DebugOptions($opts)

staticCurl.php:424

Convert a raw curl_setopt-ready options array (CURLOPT_* constant => value) into a human-readable one ('CURLOPT_*' name => value, per OPTIONS_TEXT), additionally decoding CURLOPT_HTTPHEADER, CURLOPT_COOKIE, and CURLOPT_POSTFIELDS into associative arrays where possible.

static function DebugOptions(array $opts): array
$optsarrayNOTE: a CURLOPT_* constant not listed in OPTIONS_TEXT silently produces a ''-keyed entry (PHP raises an "Undefined array key" warning, not an error, and the lookup evaluates to null -> '' as an array key) rather than being reported or skipped.
returnsarray
Curl::DebugOptions([CURLOPT_HTTPHEADER => ['X-Foo: bar']]); // ['CURLOPT_HTTPHEADER' => ['X-Foo' => 'bar']]

emergency($message, $context)

tLogEmitter.php:103

System is unusable. No-op if EMERGENCY is currently filtered out by the verbosity mask.

function emergency(Stringable|string $message, array $context = []): void
$messageStringable | string
$context = []array
returnsvoid
$this->emergency('database connection lost.');

error($message, $context)

tLogEmitter.php:154

Runtime errors that do not require immediate action but should typically be logged and monitored.

function error(Stringable|string $message, array $context = []): voidNo-op if ERROR is currently filtered out by the verbosity mask.
$messageStringable | string
$context = []array
returnsvoid
$this->error('failed to write [{file}].', ['file' => $filename]);

exec($url, $post, $opts)

Curl.php:291

Execute a CURL request and return the response

function exec(string $url, array|string|null $post = null, array $opts = []): MMO\core\server\StreamResponseNOTE: If post is an array, add `Content-Type` header so the post parameters can be encoded the right way NOTE: if no content type is defined, post data are encoded as `application/x-www-form-urlencoded`
See
setHeaders/setCookies/... and tWithOptions's generic option setters.
$urlstring
$post = nullarray | string | nullif non-null, sends a POST with this as the body (a string is sent as-is; an array is form-encoded per the NOTEs above).
$opts = []arraycurl options, merged over (and taking priority over) the options already set via
returnsStreamResponsethe LAST response received (getResponses for the full chain when redirects were followed).
throwsif called while a previous exec on this instance hasn't finished (close), or the request itself fails.
$opts = [\CURLOPT_HTTPHEADER => ['Content-Type: application/json']]

execHead($url, $post, $opts)

Curl.php:266

Execute a curl request as HEAD (no body for response) -- the response's body ends up containing the raw header text instead (curl's CURLOPT_HEADER effect), since no actual body is fetched (CURLOPT_NOBODY).

function execHead(string $url, $post = null, array $opts = []): MMO\core\server\StreamResponseAutomatically follows up to 10 redirects.
$urlstring
$post = null
$opts = []arraycurl options
returnsStreamResponse

execOrThrow($url, $post, $opts)

Curl.php:379

Same as exec, but throws if the response's status isn't a 2xx (iResponse::isOk).

function execOrThrow(string $url, array|string|null $post = null, array $opts = []): MMO\core\server\StreamResponse
$urlstring
$post = nullarray | string | null
$opts = []array
returnsStreamResponse
throwsif the response isn't OK, or (via exec) the request itself fails.

FromString($curl, $debug)

staticCurl.php:58

Parse a curl ... shell command (e.g. copy-pasted from a browser's "Copy as cURL") into options usable with exec. Only recognizes a subset of curl's flags (the switch cases below); anything else is collected into the 4th return value instead of being silently dropped.

static function FromString(string $curl, bool $debug = false): array
$curlstring
$debug = falseboolif true, run the parsed options through DebugOptions (human-readable names/values) instead of returning raw curl_setopt-ready ones.
returnsarray[url, data (currently always null -- POST data is folded into $opts[CURLOPT_POSTFIELDS] instead), options, ignored arguments]
Curl::FromString("curl 'https://example.com' -H 'X-Foo: bar' --data-raw '{\"a\":1}'"); // ['https://example.com', null, [CURLOPT_HTTPHEADER => ['X-Foo: bar'], CURLOPT_POSTFIELDS => '{"a":1}'], []]

getCookies()

Curl.php:406
function getCookies()
returnsname => value, every cookie set by the server during the current/last exec.

getOption($key, $default)

tWithOptions.php:49
function getOption(string $key, mixed $default = null): mixed
$keystring
$default = nullmixedreturned if $key is not set
returnsmixed
$t->getOption('a', 'fallback'); // the current value of 'a', or 'fallback' if not set

getOptions()

tWithOptions.php:20
function getOptions(): array
returnsarrayevery option currently set
$t->getOptions(); // ['a' => 1, 'tags' => ['x']]

getResponse()

Curl.php:396
function getResponse(): ?MMO\core\server\StreamResponse
returnsnull | StreamResponsethe last response from the current/last exec (getResponses for the full redirect chain), or null before any request has run.

getResponses()

Curl.php:401
function getResponses(): array
returnsarrayevery response from the current/last exec, in order (more than one when redirects were followed).

getUserAgent()

Curl.php:195
function getUserAgent(): ?string
returnsnull | stringthe User-Agent that will be sent, or null if unset (curl's own default applies).

getVerbosity()

tLogEmitter.php:38
function getVerbosity(): int
returnsintthe current verbosity, as a bitmask of iLogLevel::* constants
$this->getVerbosity() === (iLogLevel::ERROR_PLUS); // true if only errors/critical/alert/emergency are enabled

handleCurlHeader($handle, $header)

Curl.php:230

CURLOPT_HEADERFUNCTION callback (set by exec) -- curl calls this once per response header line, accumulating them into $headers, extracting cookies into $cookies, and (once the blank line ending the header block arrives) creating the StreamResponse for getResponse/getResponses -- called once per response actually received, so a redirect chain (setFollowRedirection) produces one StreamResponse per hop.

function handleCurlHeader($handle, $header): int
$handlethe curl handle.
$headerone raw header line, including its trailing "\r\n".
returnsintmust return strlen($header) -- curl aborts the transfer if this doesn't match.

info($message, $context)

tLogEmitter.php:204

Interesting events. No-op if INFO is currently filtered out by the verbosity mask.

function info(Stringable|string $message, array $context = []): voidExample: User logs in, SQL logs.
$messageStringable | string
$context = []array
returnsvoid
$this->info('routing [{request}] ...', ['request' => $request]);

log($level, $message, $context)

tLogEmitter.php:81

Logs with an arbitrary level.

function log($level, Stringable|string $message, array $context = []): voidNOTE: $level is filtered against the current [`setVerbosity()`](https://mcp.mmoframework.fr/documentation/mmo.core/php/server/Curl.md#curl-setverbosity): if the level is masked out, nothing is logged/dispatched at all. Return type is `void` (not the dispatched Log) to satisfy \Psr\Log\LoggerInterface.
$level
$messageStringable | string
$context = []arrayignored if $message is a Log
returnsvoid
$this->log(self::ERROR, 'disk usage at {percent}%.', ['percent' => 92]); $this->log('error', $caughtException); //string levels are resolved through \MMO\core\debug\flags()

notice($message, $context)

tLogEmitter.php:187

Normal but significant events. No-op if NOTICE is currently filtered out by the verbosity mask.

function notice(Stringable|string $message, array $context = []): void
$messageStringable | string
$context = []array
returnsvoid
$this->notice('-- START -- ({mode}): {time}', ['mode' => MMO_MODE, 'time' => date('r')]);

setCookies($readFrom, $writeTo)

Curl.php:165

Set filenames for the cookies

function setCookies(string $readFrom, ?string $writeTo = null): self
$readFromstringthe file to read from
$writeTo = nullnull | stringthe file to write into
returnsself

setFollowRedirection($follow)

Curl.php:212
function setFollowRedirection(bool $follow): self
$followboolalso toggles auto-updating the Referer header across redirects (CURLOPT_AUTOREFERER).
returnsself

setHeaders($headers)

Curl.php:131
function setHeaders(array $headers): self
$headersarrayreplaces every request header (addHeaders for the accepted shapes).
returnsself

setOption($key, $value)

tWithOptions.php:77

Set (or, with a null $value, remove) a single option.

function setOption(string $key, mixed $value): void
$keystring
$valuemixedif null, the option is unset entirely rather than being set to null
returnsvoid
$t->setOption('a', 1);$t->setOption('a', null); // removes 'a' from getOptions()

setOptions($opts)

tWithOptions.php:30

Replace the whole options bag.

function setOptions(array $opts): void
$optsarray
returnsvoid
$t->setOptions(['a' => 1]);

setReferer($referer)

Curl.php:153
function setReferer(?string $referer): self
$referernull | stringthe Referer header to send (null removes it).
returnsself

setUserAgent($value)

Curl.php:200
function setUserAgent(?string $value): self
$valuenull | stringnull removes it (falling back to curl's own default).
returnsself

setVerbosity($verb)

tLogEmitter.php:64

Set the current verbosity mask, replacing whatever it was before.

function setVerbosity(string|int|null $verb = null): void
$verb = nullstring | int | nulla bitmask of iLogLevel::* constants, or a level name/expression resolved through \MMO\core\debug\flags() (e.g. 'error+' for iLogLevel::ERROR_PLUS)
returnsvoid
$this->setVerbosity(iLogLevel::WARNING_PLUS); // only log warnings and above $this->setVerbosity('all'); // log everything

testVerbosity($level)

tLogEmitter.php:50

Test whether a given level (or set of levels) is currently enabled by this instance's verbosity mask.

function testVerbosity(string|int $level): int
$levelstring | inta iLogLevel::* constant/bitmask, or a level name resolved through \MMO\core\debug\flags()
returnsintthe bits of $level that are currently enabled (0 if none of them are)
$this->testVerbosity(self::DEBUG); // non-zero if debug-level logging is currently enabled $this->testVerbosity('error'); // same, using the string form

warning($message, $context)

tLogEmitter.php:172

Exceptional occurrences that are not errors. No-op if WARNING is currently filtered out by the verbosity mask.

function warning(Stringable|string $message, array $context = []): voidExample: Use of deprecated APIs, poor use of an API, undesirable things that are not necessarily wrong.
$messageStringable | string
$context = []array
returnsvoid
$this->warning('{count} logs were dropped.', ['count' => 3]);
Inherited members (19)
ConstantsDeclared byDescription
ALERTiLogLevelAlert: Action must be taken immediately.
ALLiLogLevelMask for all
ALL_PLUSiLogLeveldebug everything
BACKTRACEiLogLevel
CRITICALiLogLevelCritical: Critical conditions.
DEBUGiLogLevelDebug: Detailed debug information.
DEEPiLogLeveldebug everything with arguments
EMERGENCYiLogLevelEmergency: System is unusable.
ERRORiLogLevelError: Runtime errors that do not require immediate action but should typically be logged and monitored.
ERROR_PLUSiLogLevelMask for all error
FATALiLogLevelMask for all fatal error
INFOiLogLevelInfo: Interesting events.
INFO_PLUSiLogLevelMask for all errors/warning/notices/info
MEMORYiLogLevelinclude backtrace object
NOTICEiLogLevelNotice: Normal but significant events.
NOTICE_PLUSiLogLevelMask for all errors/warning/notices/info
TRACEiLogLevelinclude backtrace as origins
WARNINGiLogLevelWarning: Exceptional occurrences that are not errors.
WARNING_PLUSiLogLevelMask for all errors and warnings