diff --git a/.gitignore b/.gitignore index 7b39a0b..5cbf483 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ vendor downloads .idea/* tests/.phpunit.result.cache +/rector.php +/.vs diff --git a/downloads/httpful.phar b/downloads/httpful.phar new file mode 100644 index 0000000..5e0d600 Binary files /dev/null and b/downloads/httpful.phar differ diff --git a/src/Httpful/Bootstrap.php b/src/Httpful/Bootstrap.php index 9974bcf..6665fd5 100644 --- a/src/Httpful/Bootstrap.php +++ b/src/Httpful/Bootstrap.php @@ -11,8 +11,8 @@ class Bootstrap { - const DIR_GLUE = DIRECTORY_SEPARATOR; - const NS_GLUE = '\\'; + public const DIR_GLUE = DIRECTORY_SEPARATOR; + public const NS_GLUE = '\\'; public static $registered = false; @@ -21,7 +21,7 @@ class Bootstrap */ public static function init() { - spl_autoload_register(array('\Httpful\Bootstrap', 'autoload')); + spl_autoload_register(['\\' . \Httpful\Bootstrap::class, 'autoload']); self::registerHandlers(); } @@ -32,7 +32,7 @@ public static function init() */ public static function autoload($classname) { - self::_autoload(dirname(dirname(__FILE__)), $classname); + self::_autoload(dirname(__FILE__,2), $classname); } /** @@ -40,7 +40,7 @@ public static function autoload($classname) */ public static function pharInit() { - spl_autoload_register(array('\Httpful\Bootstrap', 'pharAutoload')); + spl_autoload_register(['\\' . \Httpful\Bootstrap::class, 'pharAutoload']); self::registerHandlers(); } @@ -78,12 +78,12 @@ public static function registerHandlers() // @todo check a conf file to load from that instead of // hardcoding into the library? - $handlers = array( + $handlers = [ \Httpful\Mime::JSON => new \Httpful\Handlers\JsonHandler(), \Httpful\Mime::XML => new \Httpful\Handlers\XmlHandler(), \Httpful\Mime::FORM => new \Httpful\Handlers\FormHandler(), \Httpful\Mime::CSV => new \Httpful\Handlers\CsvHandler(), - ); + ]; foreach ($handlers as $mime => $handler) { // Don't overwrite if the handler has already been registered diff --git a/src/Httpful/Handlers/CsvHandler.php b/src/Httpful/Handlers/CsvHandler.php index de7b15b..69c79d0 100644 --- a/src/Httpful/Handlers/CsvHandler.php +++ b/src/Httpful/Handlers/CsvHandler.php @@ -18,13 +18,13 @@ public function parse($body) if (empty($body)) return null; - $parsed = array(); + $parsed = []; $fp = fopen('data://text/plain;base64,' . base64_encode($body), 'r'); while (($r = fgetcsv($fp)) !== FALSE) { $parsed[] = $r; } - if (empty($parsed)) + if ($parsed === []) throw new \Exception("Unable to parse response as CSV"); return $parsed; } @@ -33,7 +33,7 @@ public function parse($body) * @param mixed $payload * @return string */ - public function serialize($payload) + public function serialize($payload): string { $fp = fopen('php://temp/maxmemory:'. (6*1024*1024), 'r+'); $i = 0; diff --git a/src/Httpful/Handlers/FormHandler.php b/src/Httpful/Handlers/FormHandler.php index fea1c37..0ff05a8 100644 --- a/src/Httpful/Handlers/FormHandler.php +++ b/src/Httpful/Handlers/FormHandler.php @@ -14,7 +14,7 @@ class FormHandler extends MimeHandlerAdapter */ public function parse($body) { - $parsed = array(); + $parsed = []; parse_str($body, $parsed); return $parsed; } @@ -23,7 +23,7 @@ public function parse($body) * @param mixed $payload * @return string */ - public function serialize($payload) + public function serialize($payload): string { return http_build_query($payload, null, '&'); } diff --git a/src/Httpful/Handlers/JsonHandler.php b/src/Httpful/Handlers/JsonHandler.php index 6166283..414a728 100644 --- a/src/Httpful/Handlers/JsonHandler.php +++ b/src/Httpful/Handlers/JsonHandler.php @@ -14,7 +14,7 @@ class JsonHandler extends MimeHandlerAdapter public function init(array $args) { - $this->decode_as_array = !!(array_key_exists('decode_as_array', $args) ? $args['decode_as_array'] : false); + $this->decode_as_array = (bool) ($args['decode_as_array'] ?? false); } /** @@ -37,7 +37,7 @@ public function parse($body) * @param mixed $payload * @return string */ - public function serialize($payload) + public function serialize($payload): string { return json_encode($payload); } diff --git a/src/Httpful/Handlers/MimeHandlerAdapter.php b/src/Httpful/Handlers/MimeHandlerAdapter.php index e57ebb0..53e04ad 100644 --- a/src/Httpful/Handlers/MimeHandlerAdapter.php +++ b/src/Httpful/Handlers/MimeHandlerAdapter.php @@ -10,7 +10,7 @@ class MimeHandlerAdapter { - public function __construct(array $args = array()) + public function __construct(array $args = []) { $this->init($args); } @@ -36,18 +36,18 @@ public function parse($body) * @param mixed $payload * @return string */ - function serialize($payload) + function serialize($payload): string { return (string) $payload; } - protected function stripBom($body) + protected function stripBom($body): string { if ( substr($body,0,3) === "\xef\xbb\xbf" ) // UTF-8 $body = substr($body,3); - else if ( substr($body,0,4) === "\xff\xfe\x00\x00" || substr($body,0,4) === "\x00\x00\xfe\xff" ) // UTF-32 + elseif ( substr($body,0,4) === "\xff\xfe\x00\x00" || substr($body,0,4) === "\x00\x00\xfe\xff" ) // UTF-32 $body = substr($body,4); - else if ( substr($body,0,2) === "\xff\xfe" || substr($body,0,2) === "\xfe\xff" ) // UTF-16 + elseif ( substr($body,0,2) === "\xff\xfe" || substr($body,0,2) === "\xfe\xff" ) // UTF-16 $body = substr($body,2); return $body; } diff --git a/src/Httpful/Handlers/XmlHandler.php b/src/Httpful/Handlers/XmlHandler.php index 9298a1f..fb8d2b2 100644 --- a/src/Httpful/Handlers/XmlHandler.php +++ b/src/Httpful/Handlers/XmlHandler.php @@ -23,10 +23,10 @@ class XmlHandler extends MimeHandlerAdapter /** * @param array $conf sets configuration options */ - public function __construct(array $conf = array()) + public function __construct(array $conf = []) { - $this->namespace = isset($conf['namespace']) ? $conf['namespace'] : ''; - $this->libxml_opts = isset($conf['libxml_opts']) ? $conf['libxml_opts'] : 0; + $this->namespace = $conf['namespace'] ?? ''; + $this->libxml_opts = $conf['libxml_opts'] ?? 0; } /** @@ -50,9 +50,9 @@ public function parse($body) * @return string * @throws \Exception if unable to serialize */ - public function serialize($payload) + public function serialize($payload): string { - list($_, $dom) = $this->_future_serializeAsXml($payload); + [$_, $dom] = $this->_future_serializeAsXml($payload); return $dom->saveXml(); } @@ -61,7 +61,7 @@ public function serialize($payload) * @return string * @author Ted Zellers */ - public function serialize_clean($payload) + public function serialize_clean($payload): string { $xml = new \XMLWriter; $xml->openMemory(); @@ -75,7 +75,7 @@ public function serialize_clean($payload) * @param mixed $node to serialize * @author Ted Zellers */ - public function serialize_node(&$xmlw, $node){ + public function serialize_node(&$xmlw, $node) { if (!is_array($node)){ $xmlw->text($node); } else { @@ -90,7 +90,7 @@ public function serialize_node(&$xmlw, $node){ /** * @author Zack Douglas */ - private function _future_serializeAsXml($value, $node = null, $dom = null) + private function _future_serializeAsXml($value, $node = null, $dom = null): array { if (!$dom) { $dom = new \DOMDocument; @@ -107,21 +107,21 @@ private function _future_serializeAsXml($value, $node = null, $dom = null) $objNode = $dom->createElement(get_class($value)); $node->appendChild($objNode); $this->_future_serializeObjectAsXml($value, $objNode, $dom); - } else if (is_array($value)) { + } elseif (is_array($value)) { $arrNode = $dom->createElement('array'); $node->appendChild($arrNode); $this->_future_serializeArrayAsXml($value, $arrNode, $dom); - } else if (is_bool($value)) { + } elseif (is_bool($value)) { $node->appendChild($dom->createTextNode($value?'TRUE':'FALSE')); } else { $node->appendChild($dom->createTextNode($value)); } - return array($node, $dom); + return [$node, $dom]; } /** * @author Zack Douglas */ - private function _future_serializeArrayAsXml($value, &$parent, &$dom) + private function _future_serializeArrayAsXml($value, &$parent, &$dom): array { foreach ($value as $k => &$v) { $n = $k; @@ -132,12 +132,12 @@ private function _future_serializeArrayAsXml($value, &$parent, &$dom) $parent->appendChild($el); $this->_future_serializeAsXml($v, $el, $dom); } - return array($parent, $dom); + return [$parent, $dom]; } /** * @author Zack Douglas */ - private function _future_serializeObjectAsXml($value, &$parent, &$dom) + private function _future_serializeObjectAsXml($value, &$parent, &$dom): array { $refl = new \ReflectionObject($value); foreach ($refl->getProperties() as $pr) { @@ -147,6 +147,6 @@ private function _future_serializeObjectAsXml($value, &$parent, &$dom) $this->_future_serializeAsXml($pr->getValue($value), $el, $dom); } } - return array($parent, $dom); + return [$parent, $dom]; } } \ No newline at end of file diff --git a/src/Httpful/Http.php b/src/Httpful/Http.php index 1c9aa0d..c56ab93 100644 --- a/src/Httpful/Http.php +++ b/src/Httpful/Http.php @@ -7,28 +7,28 @@ */ class Http { - const HEAD = 'HEAD'; - const GET = 'GET'; - const POST = 'POST'; - const PUT = 'PUT'; - const DELETE = 'DELETE'; - const PATCH = 'PATCH'; - const OPTIONS = 'OPTIONS'; - const TRACE = 'TRACE'; + public const HEAD = 'HEAD'; + public const GET = 'GET'; + public const POST = 'POST'; + public const PUT = 'PUT'; + public const DELETE = 'DELETE'; + public const PATCH = 'PATCH'; + public const OPTIONS = 'OPTIONS'; + public const TRACE = 'TRACE'; /** * @return array of HTTP method strings */ - public static function safeMethods() + public static function safeMethods(): array { - return array(self::HEAD, self::GET, self::OPTIONS, self::TRACE); + return [self::HEAD, self::GET, self::OPTIONS, self::TRACE]; } /** * @param string HTTP method * @return bool */ - public static function isSafeMethod($method) + public static function isSafeMethod($method): bool { return in_array($method, self::safeMethods()); } @@ -37,7 +37,7 @@ public static function isSafeMethod($method) * @param string HTTP method * @return bool */ - public static function isUnsafeMethod($method) + public static function isUnsafeMethod($method): bool { return !in_array($method, self::safeMethods()); } @@ -45,19 +45,19 @@ public static function isUnsafeMethod($method) /** * @return array list of (always) idempotent HTTP methods */ - public static function idempotentMethods() + public static function idempotentMethods(): array { // Though it is possible to be idempotent, POST // is not guarunteed to be, and more often than // not, it is not. - return array(self::HEAD, self::GET, self::PUT, self::DELETE, self::OPTIONS, self::TRACE, self::PATCH); + return [self::HEAD, self::GET, self::PUT, self::DELETE, self::OPTIONS, self::TRACE, self::PATCH]; } /** * @param string HTTP method * @return bool */ - public static function isIdempotent($method) + public static function isIdempotent($method): bool { return in_array($method, self::safeidempotentMethodsMethods()); } @@ -66,7 +66,7 @@ public static function isIdempotent($method) * @param string HTTP method * @return bool */ - public static function isNotIdempotent($method) + public static function isNotIdempotent($method): bool { return !in_array($method, self::idempotentMethods()); } @@ -78,9 +78,9 @@ public static function isNotIdempotent($method) * * @return array of HTTP method strings */ - public static function canHaveBody() + public static function canHaveBody(): array { - return array(self::POST, self::PUT, self::PATCH, self::OPTIONS); + return [self::POST, self::PUT, self::PATCH, self::OPTIONS]; } } \ No newline at end of file diff --git a/src/Httpful/Httpful.php b/src/Httpful/Httpful.php index e235fa3..98d49b7 100644 --- a/src/Httpful/Httpful.php +++ b/src/Httpful/Httpful.php @@ -3,9 +3,9 @@ namespace Httpful; class Httpful { - const VERSION = '0.3.0'; + public const VERSION = '0.3.0'; - private static $mimeRegistrar = array(); + private static $mimeRegistrar = []; private static $default = null; /** @@ -40,7 +40,7 @@ public static function get($mimeType = null) * @param string $mimeType * @return bool */ - public static function hasParserRegistered($mimeType) + public static function hasParserRegistered($mimeType): bool { return isset(self::$mimeRegistrar[$mimeType]); } diff --git a/src/Httpful/Mime.php b/src/Httpful/Mime.php index 930b6e3..bd72396 100644 --- a/src/Httpful/Mime.php +++ b/src/Httpful/Mime.php @@ -8,35 +8,35 @@ */ class Mime { - const JSON = 'application/json'; - const XML = 'application/xml'; - const XHTML = 'application/html+xml'; - const FORM = 'application/x-www-form-urlencoded'; - const UPLOAD = 'multipart/form-data'; - const PLAIN = 'text/plain'; - const JS = 'text/javascript'; - const HTML = 'text/html'; - const YAML = 'application/x-yaml'; - const CSV = 'text/csv'; + public const JSON = 'application/json'; + public const XML = 'application/xml'; + public const XHTML = 'application/html+xml'; + public const FORM = 'application/x-www-form-urlencoded'; + public const UPLOAD = 'multipart/form-data'; + public const PLAIN = 'text/plain'; + public const JS = 'text/javascript'; + public const HTML = 'text/html'; + public const YAML = 'application/x-yaml'; + public const CSV = 'text/csv'; /** * Map short name for a mime type * to a full proper mime type */ - public static $mimes = array( + public static $mimes = [ 'json' => self::JSON, 'xml' => self::XML, 'form' => self::FORM, 'plain' => self::PLAIN, 'text' => self::PLAIN, - 'upload' => self::UPLOAD, + 'upload' => self::UPLOAD, 'html' => self::HTML, 'xhtml' => self::XHTML, 'js' => self::JS, 'javascript'=> self::JS, 'yaml' => self::YAML, 'csv' => self::CSV, - ); + ]; /** * Get the full Mime Type name from a "short name". @@ -44,16 +44,16 @@ class Mime * @param string $short_name common name for mime type (e.g. json) * @return string full mime type (e.g. application/json) */ - public static function getFullMime($short_name) - { - return array_key_exists($short_name, self::$mimes) ? self::$mimes[$short_name] : $short_name; + public static function getFullMime(string $short_name): string + { + return self::$mimes[$short_name] ?? $short_name; } /** * @param string $short_name * @return bool */ - public static function supportsMimeType($short_name) + public static function supportsMimeType(string $short_name): bool { return array_key_exists($short_name, self::$mimes); } diff --git a/src/Httpful/Proxy.php b/src/Httpful/Proxy.php index 4ab9ea6..611f017 100644 --- a/src/Httpful/Proxy.php +++ b/src/Httpful/Proxy.php @@ -10,7 +10,7 @@ */ class Proxy { - const HTTP = CURLPROXY_HTTP; - const SOCKS4 = CURLPROXY_SOCKS4; - const SOCKS5 = CURLPROXY_SOCKS5; + public const HTTP = CURLPROXY_HTTP; + public const SOCKS4 = CURLPROXY_SOCKS4; + public const SOCKS5 = CURLPROXY_SOCKS5; } diff --git a/src/Httpful/Request.php b/src/Httpful/Request.php index c04d230..e7b91c8 100644 --- a/src/Httpful/Request.php +++ b/src/Httpful/Request.php @@ -1,5 +1,4 @@ $value) { - $this->$attr = $value; + if (property_exists($this, $attr)) + $this->$attr = $value; } } @@ -146,33 +151,33 @@ public static function d($attr) /** * @return bool does the request have a timeout? */ - public function hasTimeout() + public function hasTimeout(): bool { - return isset($this->timeout); + return $this->timeout !== null; } /** * @return bool has the internal curl request been initialized? */ - public function hasBeenInitialized() + public function hasBeenInitialized(): bool { - return isset($this->_ch); + return $this->_ch !== null; } /** * @return bool Is this request setup for basic auth? */ - public function hasBasicAuth() + public function hasBasicAuth(): bool { - return isset($this->password) && isset($this->username); + return $this->password !== null && $this->username !== null; } /** * @return bool Is this request setup for digest auth? */ - public function hasDigestAuth() + public function hasDigestAuth(): bool { - return isset($this->password) && isset($this->username) && $this->additional_curl_opts[CURLOPT_HTTPAUTH] == CURLAUTH_DIGEST; + return $this->password !== null && $this->username !== null && $this->additional_curl_opts[CURLOPT_HTTPAUTH] == CURLAUTH_DIGEST; } /** @@ -307,9 +312,9 @@ public function authenticateWithDigest($username, $password) /** * @return bool is this request setup for client side cert? */ - public function hasClientSideCert() + public function hasClientSideCert(): bool { - return isset($this->client_cert) && isset($this->client_key); + return $this->client_cert !== null && $this->client_key !==null; } /** @@ -395,14 +400,15 @@ public function method($method) * @param string $mime * @return Request */ - public function expects($mime) + public function expects(?string $mime) { if (empty($mime)) return $this; $this->expected_type = Mime::getFullMime($mime); + return $this; } // @alias of expects - public function expectsType($mime) + public function expectsType(?string $mime) { return $this->expects($mime); } @@ -481,7 +487,7 @@ public function useProxy($proxy_host, $proxy_port = 80, $auth_type = null, $auth { $this->addOnCurlOption(CURLOPT_PROXY, "{$proxy_host}:{$proxy_port}"); $this->addOnCurlOption(CURLOPT_PROXYTYPE, $proxy_type); - if (in_array($auth_type, array(CURLAUTH_BASIC,CURLAUTH_NTLM))) { + if (in_array($auth_type, [CURLAUTH_BASIC,CURLAUTH_NTLM])) { $this->addOnCurlOption(CURLOPT_PROXYAUTH, $auth_type) ->addOnCurlOption(CURLOPT_PROXYUSERPWD, "{$auth_username}:{$auth_password}"); } @@ -511,7 +517,7 @@ public function useSocks5Proxy($proxy_host, $proxy_port = 80, $auth_type = null, /** * @return bool is this request setup for using proxy? */ - public function hasProxy() + public function hasProxy(): bool { /* We must be aware that proxy variables could come from environment also. In curl extension, http proxy can be specified not only via CURLOPT_PROXY option, @@ -743,6 +749,7 @@ public function __call($method, $args) // throw new \Exception("Unsupported Content-Type $mime"); // } } + if (substr($method, 0, 7) === 'expects') { $mime = strtolower(substr($method, 7)); if (Mime::supportsMimeType($mime)) { @@ -756,7 +763,7 @@ public function __call($method, $args) // This method also adds the custom header support as described in the // method comments - if (count($args) === 0) + if ($args === []) return; // Strip the sugar. If it leads with "with", strip. @@ -791,7 +798,7 @@ private static function _initializeDefaults() // recusion. Do not use this syntax elsewhere. // It goes against the whole readability // and transparency idea. - self::$_template = new Request(array('method' => Http::GET)); + self::$_template = new Request(['method' => Http::GET]); // This is more like it... self::$_template @@ -818,7 +825,7 @@ private function _error($error) { // TODO add in support for various Loggers that follow // PSR 3 https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md - if (isset($this->error_callback)) { + if ($this->error_callback !== null) { $this->error_callback->__invoke($error); } else { error_log($error); @@ -860,14 +867,14 @@ public static function init($method = null, $mime = null) public function _curlPrep() { // Check for required stuff - if (!isset($this->uri)) + if ($this->uri === null) throw new \Exception('Attempting to send a request before defining a URI endpoint.'); - if (isset($this->payload)) { + if ($this->payload !== null) { $this->serialized_payload = $this->_serializePayload($this->payload); } - if (isset($this->send_callback)) { + if ($this->send_callback !== null) { call_user_func($this->send_callback, $this); } @@ -921,7 +928,7 @@ public function _curlPrep() // https://github.com/nategood/httpful/issues/84 // set Content-Length to the size of the payload if present - if (isset($this->payload)) { + if ($this->payload !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, $this->serialized_payload); if (!$this->isUpload()) { $this->headers['Content-Length'] = @@ -929,7 +936,7 @@ public function _curlPrep() } } - $headers = array(); + $headers = []; // https://github.com/nategood/httpful/issues/37 // Except header removes any HTTP 1.1 Continue from response headers $headers[] = 'Expect:'; @@ -962,9 +969,9 @@ public function _curlPrep() } $url = \parse_url($this->uri); - $path = (isset($url['path']) ? $url['path'] : '/').(isset($url['query']) ? '?'.$url['query'] : ''); + $path = ($url['path'] ?? '/').(isset($url['query']) ? '?'.$url['query'] : ''); $this->raw_headers = "{$this->method} $path HTTP/1.1\r\n"; - $host = (isset($url['host']) ? $url['host'] : 'localhost').(isset($url['port']) ? ':'.$url['port'] : ''); + $host = ($url['host'] ?? 'localhost').(isset($url['port']) ? ':'.$url['port'] : ''); $this->raw_headers .= "Host: $host\r\n"; $this->raw_headers .= \implode("\r\n", $headers); $this->raw_headers .= "\r\n"; @@ -1004,7 +1011,7 @@ public function _determineLength($str) /** * @return bool */ - public function isUpload() + public function isUpload(): bool { return Mime::UPLOAD == $this->content_type; } @@ -1012,7 +1019,7 @@ public function isUpload() /** * @return string */ - public function buildUserAgent() + public function buildUserAgent(): string { $user_agent = 'User-Agent: Httpful/' . Httpful::VERSION . ' (cURL/'; $curl = \curl_version(); @@ -1042,9 +1049,7 @@ public function buildUserAgent() $user_agent .= " {$_SERVER['HTTP_USER_AGENT']}"; } - $user_agent .= ')'; - - return $user_agent; + return $user_agent . ')'; } /** @@ -1053,7 +1058,7 @@ public function buildUserAgent() */ public function buildResponse($result) { if ($result === false) { - if ($curlErrorNumber = curl_errno($this->_ch)) { + if (($curlErrorNumber = curl_errno($this->_ch)) !== 0) { $curlErrorString = curl_error($this->_ch); $this->_error($curlErrorString); @@ -1082,7 +1087,7 @@ public function buildResponse($result) { $body = array_pop($response); $headers = array_pop($response); - + return new Response($body, $headers, $this, $info); } diff --git a/src/Httpful/Response.php b/src/Httpful/Response.php index 09996b6..2e1d204 100644 --- a/src/Httpful/Response.php +++ b/src/Httpful/Response.php @@ -9,7 +9,6 @@ */ class Response { - public $body, $raw_body, $headers, @@ -18,7 +17,7 @@ class Response $code = 0, $content_type, $parent_type, - $charset, + $charset = null, $meta_data, $is_mime_vendor_specific = false, $is_mime_personal = false; @@ -31,7 +30,7 @@ class Response * @param Request $request * @param array $meta_data */ - public function __construct($body, $headers, Request $request, array $meta_data = array()) + public function __construct(string $body, string $headers, Request $request, array $meta_data = []) { $this->request = $request; $this->raw_headers = $headers; @@ -59,7 +58,7 @@ public function __construct($body, $headers, Request $request, array $meta_data * * @return bool Did we receive a 4xx or 5xx? */ - public function hasErrors() + public function hasErrors(): bool { return $this->code >= 400; } @@ -67,7 +66,7 @@ public function hasErrors() /** * @return bool */ - public function hasBody() + public function hasBody(): bool { return !empty($this->body); } @@ -77,9 +76,9 @@ public function hasBody() * (most often an associative array) based on the expected * Mime type. * @param string Http response body - * @return array|string|object the response parse accordingly + * @return mixed (array|string|object) the response parse accordingly */ - public function _parse($body) + public function _parse(string $body) { // If the user decided to forgo the automatic // smart parsing, short circuit. @@ -98,13 +97,13 @@ public function _parse($body) // 3. If provided, use the "parent type" of the mime type from the response // 4. Default to the content-type provided in the response $parse_with = $this->request->expected_type; + if (empty($this->request->expected_type)) { $parse_with = Httpful::hasParserRegistered($this->content_type) ? $this->content_type : $this->parent_type; } - - return Httpful::get($parse_with)->parse($body); + return Httpful::get($parse_with)->parse($body); } /** @@ -113,12 +112,12 @@ public function _parse($body) * @param string $headers raw headers * @return array parse headers */ - public function _parseHeaders($headers) + public function _parseHeaders(string $headers): array { return Response\Headers::fromString($headers)->toArray(); } - public function _parseCode($headers) + public function _parseCode(string $headers): int { $end = strpos($headers, "\r\n"); if ($end === false) $end = strlen($headers); @@ -126,7 +125,7 @@ public function _parseCode($headers) if (count($parts) < 2 || !is_numeric($parts[1])) { throw new \Exception("Unable to parse response code from HTTP response due to malformed response"); } - return intval($parts[1]); + return (int) $parts[1]; } /** @@ -136,12 +135,12 @@ public function _parseCode($headers) public function _interpretHeaders() { // Parse the Content-Type and charset - $content_type = isset($this->headers['Content-Type']) ? $this->headers['Content-Type'] : ''; + $content_type = $this->headers['Content-Type'] ?? ''; $content_type = explode(';', $content_type); $this->content_type = $content_type[0]; if (count($content_type) == 2 && strpos($content_type[1], '=') !== false) { - list($nill, $this->charset) = explode('=', $content_type[1]); + [$nill, $this->charset] = explode('=', $content_type[1]); } // RFC 2616 states "text/*" Content-Types should have a default @@ -149,13 +148,13 @@ public function _interpretHeaders() // are assumed to have UTF-8 unless otherwise specified. // http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1 // http://www.w3.org/International/O-HTTP-charset.en.php - if (!isset($this->charset)) { + if ($this->charset === null ) { $this->charset = substr($this->content_type, 5) === 'text/' ? 'iso-8859-1' : 'utf-8'; } // Is vendor type? Is personal type? if (strpos($this->content_type, '/') !== false) { - list($type, $sub_type) = explode('/', $this->content_type); + [$type, $sub_type] = explode('/', $this->content_type); $this->is_mime_vendor_specific = substr($sub_type, 0, 4) === 'vnd.'; $this->is_mime_personal = substr($sub_type, 0, 4) === 'prs.'; } @@ -163,7 +162,7 @@ public function _interpretHeaders() // Parent type (e.g. xml for application/vnd.github.message+xml) $this->parent_type = $this->content_type; if (strpos($this->content_type, '+') !== false) { - list($vendor, $this->parent_type) = explode('+', $this->content_type, 2); + [$vendor, $this->parent_type] = explode('+', $this->content_type, 2); $this->parent_type = Mime::getFullMime($this->parent_type); } } @@ -171,7 +170,7 @@ public function _interpretHeaders() /** * @return string */ - public function __toString() + public function __toString(): string { return $this->raw_body; } diff --git a/src/Httpful/Response/Headers.php b/src/Httpful/Response/Headers.php index 8e8a8cd..32438b7 100644 --- a/src/Httpful/Response/Headers.php +++ b/src/Httpful/Response/Headers.php @@ -15,15 +15,16 @@ private function __construct($headers) } /** - * @param string $string + * @param string $string * @return Headers */ public static function fromString($string) { $headers = preg_split("/(\r|\n)+/", $string, -1, \PREG_SPLIT_NO_EMPTY); - $parse_headers = array(); - for ($i = 1; $i < count($headers); $i++) { - list($key, $raw_value) = explode(':', $headers[$i], 2); + $parse_headers = []; + $headersCount = count($headers); + for ($i = 1; $i < $headersCount; $i++) { + [$key, $raw_value] = explode(':', $headers[$i], 2); $key = trim($key); $value = trim($raw_value); if (array_key_exists($key, $parse_headers)) { @@ -42,17 +43,17 @@ public static function fromString($string) /** * @param string $offset - * @return bool */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return $this->getCaseInsensitive($offset) !== null; } /** - * @param string $offset + * @param mixed $offset * @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->getCaseInsensitive($offset); @@ -62,7 +63,9 @@ public function offsetGet($offset) * @param string $offset * @param string $value * @throws \Exception + * @return never */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { throw new \Exception("Headers are read-only."); @@ -71,7 +74,9 @@ public function offsetSet($offset, $value) /** * @param string $offset * @throws \Exception + * @return never */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { throw new \Exception("Headers are read-only."); @@ -80,7 +85,7 @@ public function offsetUnset($offset) /** * @return int */ - public function count() + public function count(): int { return count($this->headers); } diff --git a/tests/Httpful/HttpfulTest.php b/tests/Httpful/HttpfulTest.php index 062973e..3b8787f 100644 --- a/tests/Httpful/HttpfulTest.php +++ b/tests/Httpful/HttpfulTest.php @@ -9,7 +9,7 @@ */ namespace Httpful\Test; -require(dirname(dirname(dirname(__FILE__))) . '/bootstrap.php'); +require(dirname(__FILE__),3) . '/bootstrap.php'); \Httpful\Bootstrap::init(); use Httpful\Httpful; @@ -23,16 +23,16 @@ class HttpfulTest extends \PHPUnit\Framework\TestCase { - const TEST_SERVER = TEST_SERVER; - const TEST_URL = 'http://127.0.0.1:8008'; - const TEST_URL_400 = 'http://127.0.0.1:8008/400'; + public const TEST_SERVER = TEST_SERVER; + public const TEST_URL = 'http://127.0.0.1:8008'; + public const TEST_URL_400 = 'http://127.0.0.1:8008/400'; - const SAMPLE_JSON_HEADER = + public const SAMPLE_JSON_HEADER = "HTTP/1.1 200 OK Content-Type: application/json Connection: keep-alive Transfer-Encoding: chunked\r\n"; - const SAMPLE_JSON_HEADER_LOWERCASE = + public const SAMPLE_JSON_HEADER_LOWERCASE = "HTTP/2 200 date: Tue, 07 Jan 2020 09:11:21 GMT content-type: application/json @@ -41,29 +41,29 @@ class HttpfulTest extends \PHPUnit\Framework\TestCase access-control-allow-methods: GET, POST, PUT, PATCH, DELETE access-control-allow-headers: Authorization, Content-Type, Accept-Encoding, Cache-Control, DNT cache-control: private, must-revalidate\r\n"; - const SAMPLE_JSON_RESPONSE = '{"key":"value","object":{"key":"value"},"array":[1,2,3,4]}'; - const SAMPLE_CSV_HEADER = + public const SAMPLE_JSON_RESPONSE = '{"key":"value","object":{"key":"value"},"array":[1,2,3,4]}'; + public const SAMPLE_CSV_HEADER = "HTTP/1.1 200 OK Content-Type: text/csv Connection: keep-alive Transfer-Encoding: chunked\r\n"; - const SAMPLE_CSV_RESPONSE = + public const SAMPLE_CSV_RESPONSE = "Key1,Key2 Value1,Value2 \"40.0\",\"Forty\""; - const SAMPLE_XML_RESPONSE = '2a stringTRUE'; - const SAMPLE_XML_HEADER = + public const SAMPLE_XML_RESPONSE = '2a stringTRUE'; + public const SAMPLE_XML_HEADER = "HTTP/1.1 200 OK Content-Type: application/xml Connection: keep-alive Transfer-Encoding: chunked\r\n"; - const SAMPLE_VENDOR_HEADER = + public const SAMPLE_VENDOR_HEADER = "HTTP/1.1 200 OK Content-Type: application/vnd.nategood.message+xml Connection: keep-alive Transfer-Encoding: chunked\r\n"; - const SAMPLE_VENDOR_TYPE = "application/vnd.nategood.message+xml"; - const SAMPLE_MULTI_HEADER = + public const SAMPLE_VENDOR_TYPE = "application/vnd.nategood.message+xml"; + public const SAMPLE_MULTI_HEADER = "HTTP/1.1 200 OK Content-Type: application/json Connection: keep-alive @@ -74,8 +74,8 @@ class HttpfulTest extends \PHPUnit\Framework\TestCase function testInit() { $r = Request::init(); - // Did we get a 'Request' object? - $this->assertEquals('Httpful\Request', get_class($r)); + // Did we get a 'Request' object? + $this->assertEquals(\Httpful\Request::class, get_class($r)); } function testDetermineLength() @@ -90,11 +90,11 @@ function testDetermineLength() function testMethods() { - $valid_methods = array('get', 'post', 'delete', 'put', 'options', 'head'); + $valid_methods = ['get', 'post', 'delete', 'put', 'options', 'head']; $url = 'http://example.com/'; - foreach ($valid_methods as $method) { - $r = call_user_func(array('Httpful\Request', $method), $url); - $this->assertEquals('Httpful\Request', get_class($r)); + foreach ($valid_methods as $method) { + $r = call_user_func([\Httpful\Request::class, $method], $url); + $this->assertEquals(\Httpful\Request::class, get_class($r)); $this->assertEquals(strtoupper($method), $r->method); } } @@ -344,10 +344,10 @@ function testParsingContentTypeUpload() } function testAttach() { - $req = Request::init(); - $testsPath = realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..'); - $filename = $testsPath . DIRECTORY_SEPARATOR . 'test_image.jpg'; - $req->attach(array('index' => $filename)); + $req = Request::init(); + $testsPath = realpath(__DIR__ . DIRECTORY_SEPARATOR . '..'); + $filename = $testsPath . DIRECTORY_SEPARATOR . 'test_image.jpg'; + $req->attach(['index' => $filename]); $payload = $req->payload['index']; // PHP 5.5 + will take advantage of CURLFile while previous // versions just use the string syntax @@ -558,7 +558,7 @@ public function testOverrideXmlHandler() // Lazy test... $prev = \Httpful\Httpful::get(\Httpful\Mime::XML); $this->assertEquals($prev, new \Httpful\Handlers\XmlHandler()); - $conf = array('namespace' => 'http://example.com'); + $conf = ['namespace' => 'http://example.com']; \Httpful\Httpful::register(\Httpful\Mime::XML, new \Httpful\Handlers\XmlHandler($conf)); $new = \Httpful\Httpful::get(\Httpful\Mime::XML); $this->assertNotEquals($prev, $new); @@ -589,12 +589,12 @@ public function testParseJSON() { $handler = new JsonHandler(); - $bodies = array( + $bodies = [ 'foo', - array(), - array('foo', 'bar'), + [], + ['foo', 'bar'], null - ); + ]; foreach ($bodies as $body) { $this->assertEquals($body, $handler->parse(json_encode($body))); } diff --git a/tests/bootstrap-server.php b/tests/bootstrap-server.php index 1c27bd9..1ac0dad 100644 --- a/tests/bootstrap-server.php +++ b/tests/bootstrap-server.php @@ -1,7 +1,7 @@ ./server.log 2>&1 & echo $!', WEB_SERVER_HOST, WEB_SERVER_PORT, WEB_SERVER_DOCROOT); // Execute the command and store the process ID - $output = array(); + $output = []; exec($command, $output, $exit_code); // sleep for a second to let server come up