{"id":21556950,"url":"https://github.com/undercloud/psr18","last_synced_at":"2025-03-18T03:22:38.578Z","repository":{"id":57075265,"uuid":"174827620","full_name":"undercloud/psr18","owner":"undercloud","description":"PSR-18 Http Client","archived":false,"fork":false,"pushed_at":"2021-10-16T19:31:53.000Z","size":45,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-26T23:51:26.554Z","etag":null,"topics":["http-client","php","php-fig","php7","psr-7","psr18"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/undercloud.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-10T13:30:54.000Z","updated_at":"2022-02-12T13:57:33.000Z","dependencies_parsed_at":"2022-08-24T14:40:32.310Z","dependency_job_id":null,"html_url":"https://github.com/undercloud/psr18","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/undercloud%2Fpsr18","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/undercloud%2Fpsr18/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/undercloud%2Fpsr18/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/undercloud%2Fpsr18/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/undercloud","download_url":"https://codeload.github.com/undercloud/psr18/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244147764,"owners_count":20406047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["http-client","php","php-fig","php7","psr-7","psr18"],"created_at":"2024-11-24T08:10:26.913Z","updated_at":"2025-03-18T03:22:38.556Z","avatar_url":"https://github.com/undercloud.png","language":"PHP","readme":"# PSR-18 HTTP Client\r\n\r\n[![Build Status](https://travis-ci.org/undercloud/psr18.svg?branch=master)](https://travis-ci.org/undercloud/psr18)\r\n\r\nImplementation of https://www.php-fig.org/psr/psr-18/\r\n\r\n## Features\r\n* PSR-18 compatible\r\n* Supports of any type of HTTP requests\r\n* JSON requests\r\n* Body with multipart/form-data\r\n* Upload / Download huge files\r\n* SSL / TLS\r\n* Proxy\r\n\r\n## Requirements\r\nPHP 7.1+\r\n\r\n## License\r\nMIT\r\n\r\n## Install\r\n`composer require undercloud/psr18`\r\n\r\n## Usage\r\n\r\n```php\r\n$responsePrototype = new Zend\\Diactoros\\Response;\r\n\r\n$httpClient = new Undercloud\\Psr18\\HttpClient($responsePrototype, [\r\n    'timeout' =\u003e 10,\r\n    'ssl' =\u003e [\r\n        'verifyPeer' =\u003e false,\r\n        'verifyPeerName' =\u003e false\r\n    ]\r\n]);\r\n\r\n$requestPrototype = new Zend\\Diactoros\\Request('https://your-domain-name.com/post-data','POST');\r\n\r\n$body = new Undercloud\\Psr18\\Streams\\JsonStream([\r\n    'foo' =\u003e 'bar'\r\n]);\r\n// or\r\n$body = new Undercloud\\Psr18\\Streams\\MultipartStream([\r\n    'title' =\u003e 'Summer 69',\r\n    'description' =\u003e 'Hey check it out...',\r\n    'tags =\u003e ['summer','beach','sea'],\r\n    'photo' =\u003e new Undercloud\\Psr18\\Streams\\FileStream(\r\n        $pathToFile\r\n    )\r\n]);\r\n\r\n$requestPrototype = $requestPrototype-\u003ewithBody($body);\r\n\r\n$responsePrototype = $httpClient-\u003esendRequest($requestPrototype);\r\n```\r\n\r\n## Streams\r\n\r\n### TextStream\r\n```php\r\n// simple text stream\r\nnew Undercloud\\Psr18\\Streams\\TextStream('PHP7 is Awesome')\r\n\r\n// with options\r\n$base64 = base64_encode('PHP7 is Awesome');\r\n\r\nnew Undercloud\\Psr18\\Streams\\TextStream($base64, [\r\n    'mime' =\u003e 'text/plain'\r\n    'encoding' =\u003e 'base64'\r\n])\r\n\r\n// URL encode\r\n$urlencode = urlencode('PHP7 is Awesome');\r\n\r\nnew Undercloud\\Psr18\\Streams\\TextStream($urlencode);\r\n```\r\n\r\n### JsonStream\r\n\r\n```php\r\n\u003ccode\u003e\r\n  JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_UNESCAPED_SLASHES\r\n\u003c/code\u003e\r\n\r\n$data = [\r\n    'foo' =\u003e 'bar'  \r\n];\r\n\r\n$jsonStream = new Undercloud\\Psr18\\Streams\\JsonStream($data, $encodingOptions = 79)\r\n\r\n// {\"foo\":\"bar\"}\r\n$jsonStream-\u003egetContents();\r\n```\r\n\r\n### SocketStream\r\n```php\r\n// fopen\r\n// stream_socket_client\r\n\r\nnew Undercloud\\Psr18\\Streams\\SocketStream($resource);\r\n```\r\n\r\n### MultipartStream\r\n\r\n```php\r\nnew Undercloud\\Psr18\\Streams\\MultipartStream([\r\n    'simple' =\u003e 'text',\r\n    'array' =\u003e ['foo','bar','baz'],\r\n    'base64' =\u003e =\u003e new Undercloud\\Psr18\\Streams\\TextStream(\r\n        'iVBORw0KGgoAAAA...', [\r\n            'mime' =\u003e 'image/png',\r\n            'encoding' =\u003e 'base64'\r\n        ]\r\n    ),\r\n    'json' =\u003e new Undercloud\\Psr18\\Streams\\JsonStream([\r\n        'foo' =\u003e 'bar\r\n    ]),\r\n    'photos' =\u003e [\r\n        new Undercloud\\Psr18\\Streams\\FileStream('/path/to/01.jpg'),\r\n        new Undercloud\\Psr18\\Streams\\FileStream('/path/to/02.jpg'),\r\n        new Undercloud\\Psr18\\Streams\\FileStream('/path/to/03.jpg'),\r\n        ...\r\n    ]\r\n])\r\n```\r\n\r\n### FileStream\r\n\r\n```php\r\nnew Undercloud\\Psr18\\Streams\\FileStream($path, $filename = '')\r\n```\r\n\r\n### WrapStream\r\n```php\r\n// Third party stream\r\n\r\nnew Undercloud\\Psr18\\Streams\\WrapStream(\r\n    Psr\\Http\\Message\\StreamInterface $stream\r\n);\r\n```\r\n\r\n## Extra Multipart Headers\r\n\r\nAll kind of streams:\r\n - TextStream\r\n - JsonStream\r\n - SocketStream\r\n - MultipartStream\r\n - FileStream\r\n - WrapStream  \r\n \r\nsupports additional headers in multipart context\r\n```php\r\nnew Undercloud\\Psr18\\Streams\\MultipartStream([\r\n    'photo' =\u003e new Undercloud\\Psr18\\Streams\\FileStream($path)\r\n        -\u003ewithHeader('Content-Transfer-Encoding', '8bit')   \r\n])\r\n```\r\n\r\n## Options\r\n\r\n - **timeout** *(boolean)*  \r\n  Number of seconds until the connect() system call should timeout.\r\n  Defaults to 30.\r\n  \r\n - **followLocation** *(boolean)*  \r\n  Follow Location header redirects. Set to false to disable.\r\n  Defaults to true. \r\n \r\n - **maxRedirects** *(integer)*  \r\n The max number of redirects to follow. Value 1 or less means that no redirects are followed.\r\n Defaults to 5.\r\n\r\n - **waitResponse** *(boolean)*  \r\n Defaults to TRUE.\r\n \r\n - **requestFullUri** *(boolean)*  \r\n When set to TRUE, the entire URI will be used when constructing the request. (i.e. GET http://www.example.com/path/to/file.html HTTP/1.0). While this is a non-standard request format, some proxy servers require it.\r\n Defaults to FALSE.\r\n \r\n - **proxy** *(string)*  \r\n URI specifying address of proxy server. (e.g. tcp://proxy.example.com:5100).\r\n\r\n \r\n - **sslProtocol** *(string)*  \r\n One of `ssl`, `tls`, `tlsv1.0`, `tlsv1.1`, `tlsv1.2`\r\n Defaults to max TLS version defined in **stream_get_transports**\r\n \r\n - **ssl** *(array)*  \r\n SSL context options\r\n\r\n### SSL Context Options\r\n\r\n - **peerName** *(string)*  \r\nPeer name to be used. If this value is not set, then the name is guessed based on the hostname used when opening the stream.\r\n\r\n - **verifyPeer** *(boolean)*  \r\nRequire verification of SSL certificate used.  \r\nDefaults to TRUE.\r\n\r\n - **verifyPeerName** *(boolean)*  \r\nRequire verification of peer name.  \r\nDefaults to TRUE.\r\n\r\n - **allowSelfSigned** *(boolean)*  \r\nAllow self-signed certificates. Requires **verifyPeer**.  \r\nDefaults to FALSE\r\n\r\n - **cafile** *(string)*\r\nLocation of Certificate Authority file on local filesystem which should be used with the **verifyPeer** context option to authenticate the identity of the remote peer.\r\n\r\n - **capath** *(string)*  \r\nIf cafile is not specified or if the certificate is not found there, the directory pointed to by capath is searched for a suitable certificate. capath must be a correctly hashed certificate directory.\r\n\r\n - **localCert** *(string)*  \r\nPath to local certificate file on filesystem. It must be a PEM encoded file which contains your certificate and private key. It can optionally contain the certificate chain of issuers. The private key also may be contained in a separate file specified by **localPk**.\r\n\r\n - **localPk** *(string)*  \r\nPath to local private key file on filesystem in case of separate files for certificate (**localCert**) and private key.\r\n\r\n - **passphrase** *(string)*  \r\nPassphrase with which your **localCert** file was encoded.\r\n\r\n - **CNMatch** *(string)*  \r\nCommon Name we are expecting. PHP will perform limited wildcard matching. If the Common Name does not match this, the connection attempt will fail.  \r\nNote: This option is deprecated, in favour of **peerName**, as of PHP 5.6.0.\r\n\r\n - **verifyDepth** *(integer)*  \r\nAbort if the certificate chain is too deep.  \r\nDefaults to no verification.\r\n\r\n - **ciphers** *(string)*  \r\nSets the list of available ciphers. The format of the string is described in https://www.openssl.org/docs/manmaster/man1/ciphers.html#CIPHER-LIST-FORMAT. \r\nDefaults to DEFAULT.\r\n\r\n - **capturePeerCert** *(boolean)*  \r\nIf set to TRUE a peer_certificate context option will be created containing the peer certificate.\r\n\r\n - **capturePeerCertChain** *(boolean)*  \r\nIf set to TRUE a **peerCertificateChain** context option will be created containing the certificate chain.\r\n\r\n - **SNIEnabled** *(boolean)*\r\nIf set to TRUE server name indication will be enabled. Enabling SNI allows multiple certificates on the same IP address.\r\n\r\n - **SNIServerName** *(string)*  \r\nIf set, then this value will be used as server name for server name indication. If this value is not set, then the server name is guessed based on the hostname used when opening the stream.  \r\nNote: This option is deprecated, in favour of **peerName**, as of PHP 5.6.0.\r\n\r\n - **disableCompression** *(boolean)*  \r\nIf set, disable TLS compression. This can help mitigate the CRIME attack vector.\r\n\r\n - **peerFingerprint** *(string | array)*  \r\nAborts when the remote certificate digest doesn't match the specified hash.\r\nWhen a string is used, the length will determine which hashing algorithm is applied, either \"md5\" (32) or \"sha1\" (40).\r\nWhen an array is used, the keys indicate the hashing algorithm name and each corresponding value is the expected digest.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fundercloud%2Fpsr18","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fundercloud%2Fpsr18","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fundercloud%2Fpsr18/lists"}