{"id":18321781,"url":"https://github.com/chillerlan/php-httpinterface","last_synced_at":"2025-04-05T22:32:28.665Z","repository":{"id":62501787,"uuid":"118588984","full_name":"chillerlan/php-httpinterface","owner":"chillerlan","description":"A http client wrapper/PSR-7/PSR-17/PSR-18 implementation for PHP 7.4+.","archived":false,"fork":false,"pushed_at":"2024-03-15T22:36:54.000Z","size":5474,"stargazers_count":12,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-21T13:21:44.514Z","etag":null,"topics":["curl","http","let-php5-die","php","php-http","php-http-client","php5-is-dead","php7-is-dead","php8","psr-17","psr-18","psr-7"],"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/chillerlan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"ko_fi":"codemasher"}},"created_at":"2018-01-23T09:36:29.000Z","updated_at":"2024-12-17T17:44:38.000Z","dependencies_parsed_at":"2024-03-13T14:48:39.867Z","dependency_job_id":"121d973a-7532-49a2-97cd-0f6bbcc24e25","html_url":"https://github.com/chillerlan/php-httpinterface","commit_stats":{"total_commits":407,"total_committers":2,"mean_commits":203.5,"dds":0.144963144963145,"last_synced_commit":"80a45c4e76345ae864f752c9e6297892efae8983"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chillerlan%2Fphp-httpinterface","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chillerlan%2Fphp-httpinterface/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chillerlan%2Fphp-httpinterface/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chillerlan%2Fphp-httpinterface/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chillerlan","download_url":"https://codeload.github.com/chillerlan/php-httpinterface/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247411234,"owners_count":20934650,"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":["curl","http","let-php5-die","php","php-http","php-http-client","php5-is-dead","php7-is-dead","php8","psr-17","psr-18","psr-7"],"created_at":"2024-11-05T18:21:29.384Z","updated_at":"2025-04-05T22:32:28.389Z","avatar_url":"https://github.com/chillerlan.png","language":"PHP","readme":"# chillerlan/php-httpinterface\n\nA [PSR-7](https://www.php-fig.org/psr/psr-7/)/[PSR-17](https://www.php-fig.org/psr/psr-17/)/[PSR-18](https://www.php-fig.org/psr/psr-18/) HTTP message/client implementation.\n\n[![PHP Version Support][php-badge]][php]\n[![version][packagist-badge]][packagist]\n[![license][license-badge]][license]\n[![Continuous Integration][gh-action-badge]][gh-action]\n[![Coverage][coverage-badge]][coverage]\n[![Codacy][codacy-badge]][codacy]\n[![Packagist downloads][downloads-badge]][downloads]\n\n[php-badge]: https://img.shields.io/packagist/php-v/chillerlan/php-httpinterface?logo=php\u0026color=8892BF\n[php]: https://www.php.net/supported-versions.php\n[packagist-badge]: https://img.shields.io/packagist/v/chillerlan/php-httpinterface.svg?logo=packagist\n[packagist]: https://packagist.org/packages/chillerlan/php-httpinterface\n[license-badge]: https://img.shields.io/github/license/chillerlan/php-httpinterface.svg\n[license]: https://github.com/chillerlan/php-httpinterface/blob/main/LICENSE\n[gh-action-badge]: https://img.shields.io/github/actions/workflow/status/chillerlan/php-httpinterface/ci.yml?branch=main\u0026logo=github\n[gh-action]: https://github.com/chillerlan/php-httpinterface/actions/workflows/ci.yml?query=branch%3Amain\n[coverage-badge]: https://img.shields.io/codecov/c/github/chillerlan/php-httpinterface.svg?logo=codecov\n[coverage]: https://codecov.io/github/chillerlan/php-httpinterface\n[codacy-badge]: https://img.shields.io/codacy/grade/0ad3a5f9abe547cca5d5b3dff0ba3383?logo=codacy\n[codacy]: https://app.codacy.com/gh/chillerlan/php-httpinterface/dashboard\n[downloads-badge]: https://img.shields.io/packagist/dt/chillerlan/php-httpinterface.svg?logo=packagist\n[downloads]: https://packagist.org/packages/chillerlan/php-httpinterface/stats\n\n\n# Documentation\n\nAn API documentation created with [phpDocumentor](https://www.phpdoc.org/) can be found at https://chillerlan.github.io/php-httpinterface/ (WIP).\n\n\n## Requirements\n- PHP 8.1+\n  - [`ext-curl`](https://www.php.net/manual/book.curl.php)\n  - from dependencies:\n    - [`ext-fileinfo`](https://www.php.net/manual/book.fileinfo.php)\n    - [`ext-intl`](https://www.php.net/manual/book.intl.php)\n    - [`ext-json`](https://www.php.net/manual/book.json.php)\n    - [`ext-mbstring`](https://www.php.net/manual/book.mbstring.php)\n    - [`ext-simplexml`](https://www.php.net/manual/book.simplexml.php)\n    - [`ext-zlib`](https://www.php.net/manual/book.zlib.php)\n\n\n## Installation with [composer](https://getcomposer.org)\n\n### Terminal\n\n```\ncomposer require chillerlan/php-httpinterface\n```\n\n### composer.json\n\n```json\n{\n\t\"require\": {\n\t\t\"php\": \"^8.1\",\n\t\t\"chillerlan/php-httpinterface\": \"dev-main#\u003ccommit_hash\u003e\"\n\t}\n}\n```\nNote: replace `dev-main` with a [version constraint](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints), e.g. `^6.0` - see [releases](https://github.com/chillerlan/php-httpinterface/releases) for valid versions.\n\nProfit!\n\n\n## Quickstart\n\nThe HTTP clients `CurlClient` and `StreamClient` are invoked with a `ResponseFactoryInterface` instance \nas the first parameter, followed by optional `HTTPOptions` and PSR-3 `LoggerInterface` instances.\nYou can then send a request via the implemented PSR-18 method `ClientInterface::sendRequest()`,\nusing a PSR-7 `RequestInterface` and expect a PSR-7 `ResponseInterface`.\n\n\n### `CurlClient`, `StreamClient`\n\n```php\n$options                 = new HTTPOptions;\n$options-\u003eca_info        = '/path/to/cacert.pem';\n$options-\u003euser_agent     = 'my cool user agent 1.0';\n$options-\u003edns_over_https = 'https://cloudflare-dns.com/dns-query';\n\n$httpClient = new CurlClient($responseFactory, $options, $logger);\n$request    = $requestFactory-\u003ecreateRequest('GET', 'https://www.example.com?foo=bar');\n\n$httpClient-\u003esendRequest($request);\n```\n\n\n### `CurlMultiClient`\n\nThe `CurlMultiClient` client implements asynchronous multi requests ([\"rolling-curl\"](https://code.google.com/archive/p/rolling-curl/)).\nIt needs a `MultiResponseHandlerInterface` that parses the incoming responses, the callback may return a failed request to the stack:\n\n```php\n$handler = new class () implements MultiResponseHandlerInterface{\n\n\tpublic function handleResponse(\n\t\tResponseInterface $response,  // the incoming response\n\t\tRequestInterface  $request,   // the corresponding request\n\t\tint               $id,        // the request id\n\t\tarray|null        $curl_info, // the curl_getinfo() result for this request\n\t):RequestInterface|null{\n\t\n\t\tif($response-\u003egetStatusCode() !== 200){\n\t\t\t// return the failed request back to the stack\n\t\t\treturn $request;\n\t\t}\n\t\t\n\t\ttry{\n\t\t\t$body = $response-\u003egetBody();\n\t\t\t\n\t\t\t// the response body is empty for some reason, we pretend that's fine and exit\n\t\t\tif($body-\u003egetSize() === 0){\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t\n\t\t\t// parse the response body, store the result etc.\n\t\t\t$data = $body-\u003egetContents();\n\t\t\t\n\t\t\t// save data to file, database or whatever...\n\t\t\t// ...\n\t\n\t\t}\n\t\tcatch(Throwable){\n\t\t\t// something went wrong, return the request to the stack for another try\n\t\t\treturn $request;\n\t\t}\n\t\t\n\t\t// everything ok, nothing to return\n\t\treturn null;\n\t}\n\n};\n```\n\nYou can then invoke the multi request client - the `MultiResponseHandlerInterface` and `ResponseFactoryInterface` are mandatory, \n`HTTPOptions` and `LoggerInterface` are optional:\n\n```php\n$options              = new HTTPOptions;\n$options-\u003eca_info     = '/path/to/cacert.pem';\n$options-\u003euser_agent  = 'my cool user agent 1.0';\n$options-\u003esleep       = 750000; // microseconds, see usleep()\n$options-\u003ewindow_size = 5;\n$options-\u003eretries     = 1;\n\n$multiClient = new CurlMultiClient($handler, $responseFactory, $options, $logger);\n\n// create and add the requests\nforeach(['..', '...', '....'] as $item){\n\t$multiClient-\u003eaddRequest($factory-\u003ecreateRequest('GET', $endpoint.'/'.$item));\n}\n\n// process the queue\n$multiClient-\u003eprocess();\n```\n\n\n### `URLExtractor`\n\nThe `URLExtractor` wraps a PSR-18 `ClientInterface` to extract and follow shortened URLs to their original location.\n\n```php\n$options                 = new HTTPOptions;\n$options-\u003euser_agent     = 'my cool user agent 1.0';\n$options-\u003essl_verifypeer = false;\n$options-\u003ecurl_options   = [\n\tCURLOPT_FOLLOWLOCATION =\u003e false,\n\tCURLOPT_MAXREDIRS      =\u003e 25,\n];\n\n$httpClient   = new CurlClient($responseFactory, $options, $logger);\n$urlExtractor = new URLExtractor($httpClient, $responseFactory);\n\n$request = $factory-\u003ecreateRequest('GET', 'https://t.co/ZSS6nVOcVp');\n\n$urlExtractor-\u003esendRequest($request); // -\u003e response from the final location\n\n// you can retrieve an array with all followed locations afterwards\n$responses = $this-\u003ehttp-\u003egetResponses(); // -\u003e ResponseInterface[]\n\n// if you just want the URL of the final location, you can use the extract method: \n$url = $this-\u003ehttp-\u003eextract('https://t.co/ZSS6nVOcVp'); // -\u003e https://api.guildwars2.com/v2/build\n```\n\n\n### `LoggingClient`\n \nThe `LoggingClient` wraps a `ClientInterface` and outputs the HTTP messages in a readable way through a `LoggerInterface` (do NOT use in production!).\n\n```php\n$loggingClient = new LoggingClient($httpClient, $logger);\n\n$loggingClient-\u003esendRequest($request); // -\u003e log to output given via logger\n```\n\n\n### Auto generated API documentation\n\nThe API documentation can be auto generated with [phpDocumentor](https://www.phpdoc.org/).\nThere is an [online version available](https://chillerlan.github.io/php-httpinterface/) via the [gh-pages branch](https://github.com/chillerlan/php-httpinterface/tree/gh-pages) that is [automatically deployed](https://github.com/chillerlan/php-httpinterface/deployments) on each push to main.\n\nLocally created docs will appear in the directory `.build/phpdocs/`. If you'd like to create local docs, please follow these steps:\n\n- [download phpDocumentor](https://github.com/phpDocumentor/phpDocumentor/releases) v3+ as .phar archive\n- run it in the repository root directory:\n\t- on Windows `c:\\path\\to\\php.exe c:\\path\\to\\phpDocumentor.phar --config=phpdoc.xml`\n\t- on Linux just `php /path/to/phpDocumentor.phar --config=phpdoc.xml`\n- open [index.html](./.build/phpdocs/index.html) in a browser\n- profit!\n\n\n## Disclaimer\n\nUse at your own risk!\n","funding_links":["https://ko-fi.com/codemasher"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchillerlan%2Fphp-httpinterface","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchillerlan%2Fphp-httpinterface","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchillerlan%2Fphp-httpinterface/lists"}