123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846 |
- <?php
- /**
- * A simple PHP library for doing RESTful HTTP stuff. Does *not* require the curl extension.
- * @link https://github.com/fictivekin/resty.php
- */
- class Resty
- {
- /**
- * The version of this lib
- */
- const VERSION = '0.3.8';
- const DEFAULT_TIMEOUT = 240;
- /**
- * @var bool enables debugging output
- */
- protected $debug = false;
- /**
- * logging function (should be a Closure)
- * @var Closure
- */
- protected $logger = null;
- /**
- * @var bool whether or not to auto-parse the response body as JSON or XML
- */
- protected $parse_body = true;
- /**
- * @var string
- * @see Resty::getUserAgent()
- */
- protected $user_agent = null;
- /**
- * @var string
- */
- protected $base_url;
- /**
- * Stores the last request hash
- * @var array
- */
- protected $last_request;
- /**
- * Stores the last response hash
- * @var array
- */
- protected $last_response;
- /**
- * stores anon func callbacks (because you can't store them as obj props
- * @var array
- */
- protected $callbacks = array();
- /**
- * username for basic auth
- * @var string
- */
- protected $username;
- /**
- * password for basic auth
- * @var string
- */
- protected $password;
- /**
- * by default, silence the fopen warning if we can't open the stream
- */
- protected $silence_fopen_warning = true;
- /**
- * by default, don't raise an exception if fopen() fails
- * @var boolean
- */
- protected $raise_fopen_exception = false;
- /**
- * content-types that will trigger JSON parsing of body
- * @var array
- */
- public static $JSON_TYPES = array(
- 'application/json',
- 'text/json',
- 'text/x-json',
- );
- /**
- * content-types that will trigger XML parsing
- * @var array
- */
- public static $XML_TYPES = array(
- 'application/xml',
- 'text/xml',
- 'application/rss+xml',
- 'application/xhtml+xml',
- 'application/atom+xml',
- 'application/xslt+xml',
- 'application/mathml+xml',
- );
- /**
- * Passed opts can include
- * $opts['onRequestLog'] - an anonymous function that takes the Resty::last_request property as arg
- * $opts['onResponseLog'] - an anonymous function that takes the Resty::last_response property as arg
- *
- * @see Resty::last_request
- * @see Resty::last_response
- * @see Resty::sendRequest()
- * @param array $opts OPTIONAL array of options
- */
- function __construct($opts=null) {
- if (!empty($opts['onRequestLog']) && ($opts['onRequestLog'] instanceof Closure)) {
- $this->callbacks['onRequestLog'] = $opts['onRequestLog'];
- }
- if (!empty($opts['onResponseLog']) && ($opts['onResponseLog'] instanceof Closure)) {
- $this->callbacks['onResponseLog'] = $opts['onResponseLog'];
- }
- if (isset($opts['silence_fopen_warning'])) {
- $this->silenceFopenWarning((bool)$opts['silence_fopen_warning']);
- }
- if (isset($opts['raise_fopen_exception'])) {
- $this->raiseFopenException((bool)$opts['raise_fopen_exception']);
- }
- }
- /**
- * retrieve the last request we sent
- *
- * valid keys are ['url', 'method', 'querydata', 'headers', 'options', 'opts']
- *
- * @param string $key just retrieve a given field from the hash
- * @return mixed
- */
- public function getLastRequest($key=null) {
- if (!isset($key)) {
- return $this->last_request;
- }
- return $this->last_request[$key];
- }
- /**
- * retrieve the last response we got
- *
- * valid keys are ['meta', 'status', 'headers', 'body']
- *
- * @param string $key just retrieve a given field from the hash
- * @return mixed
- */
- public function getLastResponse($key=null) {
- if (!isset($key)) {
- return $this->last_response;
- }
- return $this->last_response[$key];
- }
- /**
- * make a GET request
- *
- * @param string the URL. This will be appended to the base_url, if any set
- * @param array $querydata hash of key/val pairs
- * @param array $headers hash of key/val pairs
- * @param array $options hash of key/val pairs ('timeout')
- * @return array the response hash
- * @see Resty::sendRequest()
- */
- public function get($url, $querydata=null, $headers=null, $options=null) {
- return $this->sendRequest($url, 'GET', $querydata, $headers, $options);
- }
- /**
- * make a POST request
- *
- * @param string the URL. This will be appended to the base_url, if any set
- * @param array $querydata hash of key/val pairs
- * @param array $headers hash of key/val pairs
- * @param array $options hash of key/val pairs ('timeout')
- * @return array the response hash
- * @see Resty::sendRequest()
- */
- public function post($url, $querydata=null, $headers=null, $options=null) {
- return $this->sendRequest($url, 'POST', $querydata, $headers, $options);
- }
- /**
- * make a PUT request
- *
- * @param string the URL. This will be appended to the base_url, if any set
- * @param array $querydata hash of key/val pairs
- * @param array $headers hash of key/val pairs
- * @param array $options hash of key/val pairs ('timeout')
- * @return array the response hash
- * @see Resty::sendRequest()
- */
- public function put($url, $querydata=null, $headers=null, $options=null) {
- return $this->sendRequest($url, 'PUT', $querydata, $headers, $options);
- }
- /**
- * make a DELETE request
- *
- * @param string the URL. This will be appended to the base_url, if any set
- * @param array $querydata hash of key/val pairs
- * @param array $headers hash of key/val pairs
- * @param array $options hash of key/val pairs ('timeout')
- * @return array the response hash
- * @see Resty::sendRequest()
- */
- public function delete($url, $querydata=null, $headers=null, $options=null) {
- return $this->sendRequest($url, 'DELETE', $querydata, $headers, $options);
- }
- /**
- * @param string $url
- * @param array $files
- * @param array $params
- * @param array $headers
- * @param array $options
- *
- * The $files array should be a set of key/val pairs, with the key being
- * the field name, and the val the file path. ex:
- * $files['avatar'] = '/path/to/file.jpg';
- * $files['background'] = '/path/to/file2.jpg';
- *
- */
- public function postFiles($url, $files, $params=null, $headers=null, $options=null) {
- $datastr = "";
- $boundary = "---------------------".substr(md5(rand(0,32000)), 0, 10);
- // build params
- if (isset($params)) {
- foreach($params as $key => $val) {
- $datastr .= "--$boundary\n";
- $datastr .= "Content-Disposition: form-data; name=\"".$key."\"\n\n".$val."\n";
- }
- }
- $datastr .= "--$boundary\n";
- // build files
- foreach($files as $key => $file)
- {
- $filename = pathinfo($file, PATHINFO_BASENAME);
- $content_type = $this->getMimeType($file);
- $fileContents = file_get_contents($file);
- $datastr .= "Content-Disposition: form-data; name=\"{$key}\"; filename=\"{$filename}\"\n";
- $datastr .= "Content-Type: {$content_type}\n";
- $datastr .= "Content-Transfer-Encoding: binary\n\n";
- $datastr .= $fileContents."\n";
- $datastr .= "--$boundary\n";
- }
- if (!isset($headers)) {
- $headers = array();
- }
- $headers['Content-Type'] = 'multipart/form-data; boundary='.$boundary;
- return $this->post($url, $datastr, $headers, $options);
- }
- /**
- * @param string $url
- * @param array $binary_data
- * @param array $params
- * @param array $headers
- * @param array $options
- *
- * The $binary_data array should be a set of key/val pairs, with the key being
- * the field name, and the val the binary data. ex:
- * $files['avatar'] = <BINARY>;
- * $files['background'] = <BINARY>;
- *
- * with that data, a multipart POST body is created, identical to a file
- * upload, just without reading the data from a file
- *
- */
- public function postBinary($url, $binary_data, $params=null, $headers=null, $options=null) {
- $datastr = "";
- $boundary = "---------------------".substr(md5(rand(0,32000)), 0, 10);
- // build params
- if (isset($params)) {
- foreach($params as $key => $val) {
- $datastr .= "--$boundary\n";
- $datastr .= "Content-Disposition: form-data; name=\"".$key."\"\n\n".$val."\n";
- }
- }
- $datastr .= "--$boundary\n";
- // build files
- foreach($binary_data as $key => $bdata)
- {
- $filename = 'bdata';
- $content_type = 'application/octet-stream';
- $datastr .= "Content-Disposition: form-data; name=\"{$key}\"; filename=\"{$filename}\"\n";
- $datastr .= "Content-Type: {$content_type}\n";
- $datastr .= "Content-Transfer-Encoding: binary\n\n";
- $datastr .= $bdata."\n";
- $datastr .= "--$boundary\n";
- }
- if (!isset($headers)) {
- $headers = array();
- }
- $headers['Content-Type'] = 'multipart/form-data; boundary='.$boundary;
- return $this->post($url, $datastr, $headers, $options);
- }
- /**
- * @see Resty::postFiles()
- *
- * Stole this from the Amazon S3 class:
- *
- * Copyright (c) 2008, Donovan Schönknecht. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
- *
- */
- protected function getMimeType($filepath) {
- if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) &&
- ($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false) {
- if (($type = finfo_file($finfo, $filepath)) !== false) {
- // Remove the charset and grab the last content-type
- $type = explode(' ', str_replace('; charset=', ';charset=', $type));
- $type = array_pop($type);
- $type = explode(';', $type);
- $type = trim(array_shift($type));
- }
- finfo_close($finfo);
- // If anyone is still using mime_content_type()
- } elseif (function_exists('mime_content_type')) {
- $type = trim(mime_content_type($filepath));
- }
- if ($type !== false && strlen($type) > 0) { return $type; }
- // Otherwise do it the old fashioned way
- static $exts = array(
- 'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png',
- 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon',
- 'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf',
- 'zip' => 'application/zip', 'gz' => 'application/x-gzip',
- 'tar' => 'application/x-tar', 'bz' => 'application/x-bzip',
- 'bz2' => 'application/x-bzip2', 'txt' => 'text/plain',
- 'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html',
- 'css' => 'text/css', 'js' => 'text/javascript',
- 'xml' => 'text/xml', 'xsl' => 'application/xsl+xml',
- 'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav',
- 'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
- 'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php'
- );
- $ext = strtolower(pathInfo($filepath, PATHINFO_EXTENSION));
- return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream';
- }
- /**
- * bc wrapper
- */
- public function enableDebugging($state=false) {
- $this->debug($state);
- }
- /**
- * enable or disable debugging. If no arg passed, just returns current state
- * @param bool $state=null if not passed, state not changed
- * @return boolean the current state
- */
- public function debug($state=null) {
- if (isset($state)) {
- $this->debug = (bool)$state;
- }
- return $this->debug;
- }
- /**
- * raise an exception from fopen if trying to open stream fails
- * @param boolean $state=null optional, set the state
- * @return boolean the current state
- */
- public function raiseFopenException($state=null) {
- if (isset($state)) {
- $this->raise_fopen_exception = (bool)$state;
- }
- return $this->raise_fopen_exception;
- }
- /**
- * silence warnings from fopen when trying to open stream
- * @param boolean $state=null optional, set the state
- * @return boolean the current state
- */
- public function silenceFopenWarning($state=null) {
- if (isset($state)) {
- $this->silence_fopen_warning = (bool)$state;
- }
- return $this->silence_fopen_warning;
- }
- /**
- * sets an alternate logging method
- * @param Closure $logger
- */
- public function setLogger(Closure $logger) {
- $this->logger = $logger;
- }
- /**
- * enable or disable automatic parsing of body. default is true
- * @param bool $state default TRUE
- */
- public function parseBody($state=true) {
- $state = (bool)$state;
- $this->parse_body = $state;
- }
- /**
- * Sets the base URL for all subsequent requests
- * @param string $base_url
- */
- public function setBaseURL($base_url) {
- $this->base_url = $base_url;
- }
- /**
- * retrieves the current Resty::$base_url
- * @return string
- */
- public function getBaseURL() {
- return $this->base_url;
- }
- /**
- * Sets the user-agent
- * @param string $user_agent
- */
- public function setUserAgent($user_agent) {
- $this->user_agent = $user_agent;
- }
- /**
- * Gets the current user agent. if Resty::$user_agent is not set, uses a default
- * @return string
- */
- public function getUserAgent() {
- if (empty($this->user_agent)) {
- $this->user_agent = 'Resty ' . static::VERSION;
- }
- return $this->user_agent;
- }
- /**
- * Sets credentials for http basic auth
- * @param string $username
- * @param string $password
- */
- public function setCredentials($username, $password) {
- $this->username = $username;
- $this->password = $password;
- }
- /**
- * removes current credentials
- */
- public function clearCredentials() {
- $this->username = null;
- $this->password = null;
- }
- /**
- * takes a set of key/val pairs and builds an array of raw header strings
- *
- * @param string $headers
- * @return void
- * @author Ed Finkler
- */
- protected function buildHeadersArray($headers) {
- $str_headers = array();
- foreach ($headers as $key => $value) {
- $str_headers[] = "{$key}: {$value}";
- }
- return $str_headers;
- }
- /**
- * Extracts the headers of a response from the stream's meta data
- * @param array $meta
- * @return array
- */
- protected function metaToHeaders($meta) {
- $headers = array();
- if (!isset($meta['wrapper_data'])) {
- return $headers;
- }
- foreach ($meta['wrapper_data'] as $value) {
- if (strpos($value, 'HTTP') !== 0) {
- preg_match("|^([^:]+):\s?(.+)$|", $value, $matches);
- if (is_array($matches) && isset($matches[2])) {
- $headers[trim($matches[1])] = trim($matches[2], " \t\n\r\0\x0B\"");
- }
- }
- }
- return $headers;
- }
- /**
- * extracts the status code from the stream meta data
- * @param array $meta
- * @return integer
- */
- protected function getStatusCode($meta) {
- $matches = array();
- $status = 0;
- preg_match("|\s(\d\d\d)\s?|", $meta['wrapper_data'][0], $matches);
- if (is_array($matches) && isset($matches[1])) {
- $status = (int)trim($matches[1]);
- }
- return $status;
- }
- /**
- * Sends the HTTP request and retrieves/parses the response
- *
- * @param string $url
- * @param string $method
- * @param array $querydata OPTIONAL
- * @param array $headers OPTIONAL
- * @param array $options OPTIONAL
- * @return array
- * @author Ed Finkler
- */
- public function sendRequest($url, $method='GET', $querydata=null, $headers=null, $options=null) {
- $resp = array();
- if ($this->base_url) {
- $url = $this->base_url.$url;
- }
- // we need to supply a default content-type
- if (!isset($headers['Content-Type'])) {
- $headers['Content-Type'] = 'application/x-www-form-urlencoded';
- }
- // by default, pass the header "Connection: close"
- if (!isset($headers['Connection'])) {
- $headers['Connection'] = 'close';
- }
- // if we have a username and password, use it
- if (isset($this->username) && isset($this->password) && !isset($headers['Authorization'])) {
- $this->log("{$this->username}:{$this->password}");
- $headers['Authorization'] = 'Basic '.base64_encode("{$this->username}:{$this->password}");
- }
- // default timeout
- $timeout = isset($options['timeout']) ? $options['timeout'] : static::DEFAULT_TIMEOUT;
- $content = null;
- // if querydata is a string, just pass it as-is
- if (isset($querydata) && is_string($querydata)) {
- $content = $querydata;
- // else if it's an array, make an http query
- } elseif (isset($querydata) && is_array($querydata)) {
- $content = http_build_query($querydata);
- }
- // create an array of header strings from the hash
- $headerarr = isset($headers) ? $this->buildHeadersArray($headers) : array();
- // GET and DELETE should use the URL to pass data
- $urlcontent = ('GET' === $method || 'DELETE' === $method);
- // if this is a GET or DELETE and we have some $content, append to URL
- if ($urlcontent && isset($content)) {
- $url .= '?'.$content;
- }
- $opts = array(
- 'http'=>array(
- 'timeout'=>$timeout,
- 'method'=>$method,
- 'content'=> (!$urlcontent) ? $content : null,
- 'user_agent'=>$this->getUserAgent(),
- 'header'=>$headerarr,
- 'ignore_errors'=>1
- )
- );
- $this->log('URL =================');
- $this->log($url);
- $this->log('METHOD =================');
- $this->log($method);
- $this->log('QUERYDATA =================');
- $this->log($querydata);
- $this->log('HEADERS =================');
- $this->log($headers);
- $this->log('OPTIONS =================');
- $this->log($options);
- $this->log('OPTS =================');
- $this->log($opts);
- $this->last_request = compact('url', 'method', 'querydata', 'headers', 'options', 'opts');
- // call custom req log callback
- if (!empty($this->callbacks['onRequestLog'])) {
- $this->callbacks['onRequestLog']($this->last_request);
- }
- $resp_data = $this->makeStreamRequest($url, $opts);
- $resp['meta'] = $resp_data['meta'];
- $resp['body'] = $resp_data['body'];
- $resp['error'] = $resp_data['error'];
- $resp['error_msg'] = $resp_data['error_msg'];
- $resp['status'] = $this->getStatusCode($resp['meta']);
- $resp['headers'] = $this->metaToHeaders($resp['meta']);
- $this->log($resp);
- $this->log("Processing response body…");
- $resp = $this->processResponseBody($resp);
- $this->log($resp['body']);
- $this->last_response = $resp;
- // call custom resp log callback
- if (!empty($this->callbacks['onResponseLog'])) {
- $this->callbacks['onResponseLog']($this->last_response);
- }
- return $resp;
- }
- /**
- * opens an http stream, sends the request, and returns result
- * @param [type] $url [description]
- * @param [type] $opts [description]
- * @return [type] [description]
- */
- protected function makeStreamRequest($url, $opts) {
- $resp_data = array(
- 'meta' => null,
- 'body' => null,
- 'error' => true,
- 'error_msg' => null,
- );
- $context = stream_context_create($opts);
- $this->log("Sending…");
- $start_time = microtime(true);
- $this->log("Opening stream…");
- if ($this->silence_fopen_warning) {
- $stream = @fopen($url, 'r', false, $context);
- } else {
- $stream = fopen($url, 'r', false, $context);
- }
- if (!$stream) {
- $req_time = static::calc_time_passed($start_time);
- $opts_json = !empty($opts) ? json_encode($opts) : 'null';
- $msg = "Stream open failed for '{$url}'; req_time: {$req_time}; opts: {$opts_json}";
- $this->log($msg);
- if ($this->raise_fopen_exception) {
- throw new Exception($msg);
- } else {
- $resp_data['error'] = true;
- $resp_data['error_msg'] = $msg;
- }
- } else {
- $this->log("Getting metadata…");
- $resp_data['meta'] = stream_get_meta_data($stream);
- $this->log("Getting response…");
- $resp_data['body'] = stream_get_contents($stream);
- $this->log("Closing stream…");
- fclose($stream);
- }
- if ($this->debug) {
- $req_time = static::calc_time_passed($start_time);
- $this->log(sprintf("Request time for \"%s %s\": %f", $opts['http']['method'], $url, $req_time));
- }
- return $resp_data;
- }
- /**
- * If we get back something that claims to be XML or JSON, parse it as such and assign to $resp['body']
- *
- * @param string $resp
- * @return string|object
- * @see Resty::$JSON_TYPES
- * @see Resty::$XML_TYPES
- */
- protected function processResponseBody($resp) {
- if ($this->parse_body === true) {
- $header_content_type = isset($resp['headers']['Content-Type']) ? $resp['headers']['Content-Type'] : null;
- $content_type = preg_split('/[;\s]+/', $header_content_type);
- $content_type = $content_type[0];
- if (in_array($content_type, static::$JSON_TYPES)) {
- $this->log("Response body is JSON");
- $resp['body_raw'] = $resp['body'];
- $resp['body'] = json_decode($resp['body']);
- return $resp;
- } elseif (in_array($content_type, static::$XML_TYPES)) {
- $this->log("Response body is XML");
- $resp['body_raw'] = $resp['body'];
- $resp['body'] = new \SimpleXMLElement($resp['body']);
- return $resp;
- }
- }
- $this->log("Response body not parsed");
- return $resp;
- }
- /**
- * calculate time passed in microtime
- * @param float $start_time should be result of microtime(true)
- * @return float the diff between passed microtime and current microtime
- */
- protected static function calc_time_passed($start_time) {
- $stop_time = microtime(true);
- $req_time = $stop_time - $start_time;
- return $req_time;
- }
- protected function log($msg) {
- if (!$this->debug) { return; }
- if (is_callable($this->logger)) {
- $logger = $this->logger;
- return $logger($msg);
- }
- return $this->default_logger($msg);
- }
- /**
- * logging helper
- *
- * @param mixed $msg
- */
- protected function default_logger($msg) {
- $line = date(\DateTime::RFC822) . " :: ";
- if (is_string($msg)) {
- $line .= "{$msg}\n";
- } else {
- ob_start();
- var_dump($msg);
- $line = ob_get_clean();
- $line .= "\n";
- }
- if (PHP_SAPI !== 'cli') {
- $line = "<pre>$line</pre>\n";
- }
- return error_log($line);
- }
- }
|