From 7aa258bd7177feae959437e62e4177259cd2473f Mon Sep 17 00:00:00 2001 From: smiley Date: Sun, 10 Mar 2024 19:56:35 +0100 Subject: [PATCH] :octocat: --- README.md | 137 +++++++++++++++++++++++++++++++++++++++++++++++++- composer.json | 3 ++ 2 files changed, 139 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index af2eda9b..c8653c20 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ A [PSR-7](https://www.php-fig.org/psr/psr-7/)/[PSR-17](https://www.php-fig.org/p # Documentation -See [the wiki](https://github.com/chillerlan/php-httpinterface/wiki) for advanced documentation. An API documentation created with [phpDocumentor](https://www.phpdoc.org/) can be found at https://chillerlan.github.io/php-httpinterface/ (WIP). @@ -59,6 +58,142 @@ In case you want to keep using `dev-main`, specify the hash of a commit to avoid Profit! +## Quickstart + +The HTTP clients `CurlClient` and `StreamClient` are invoked with a `ResponseFactoryInterface` instance +as the first parameter, followed by optional `HTTPOptions` and PSR-3 `LoggerInterface` instances. +You can then send a request via the implemented PSR-18 method `ClientInterface::sendRequest()`, +using a PSR-7 `RequestInterface` and expect a PSR-7 `ResponseInterface`. + +### `CurlClient`, `StreamClient` + +```php +$options = new HTTPOptions; +$options->ca_info = '/path/to/cacert.pem'; +$options->user_agent = 'my cool user agent 1.0'; + +$httpClient = new CurlClient($responseFactory, $options, $logger); +$request = $requestFactory->createRequest('GET', 'https://www.example.com?foo=bar'); + +$httpClient->sendRequest($request); +``` + + +### `CurlMultiClient` + +The `CurlMultiClient` client implements asynchronous multi requests (["rolling-curl"](https://code.google.com/archive/p/rolling-curl/)). +It needs a `MultiResponseHandlerInterface` that parses the incoming responses, the callback may return a failed request to the stack: + +```php +$handler = new class () implements MultiResponseHandlerInterface{ + + public function handleResponse( + ResponseInterface $response, // the incoming response + RequestInterface $request, // the corresponding request + int $id, // the request id + array $curl_info , // the curl_getinfo() result for this request + ):RequestInterface|null{ + + if($response->getStatusCode() !== 200){ + // return the failed request back to the stack + return $request; + } + + try{ + $body = $response->getBody(); + + // the response body is empty for some reason, we pretend that's fine and exit + if($body->getSize() === 0){ + return null; + } + + // parse the response body, store the result etc. + $data = $body->getContents(); + + // save data to file, database or whatever... + // ... + + } + catch(Throwable){ + // something went wrong, return the request to the stack for another try + return $request; + } + + // everything ok, nothing to return + return null; + } + +}; +``` + +You can then invoke the multi request client - the `MultiResponseHandlerInterface` and `ResponseFactoryInterface` are mandatory, +`HTTPOptions` and `LoggerInterface` are optional: + +```php +$options = new HTTPOptions; +$options->ca_info = '/path/to/cacert.pem'; +$options->user_agent = 'my cool user agent 1.0'; +$options->sleep = 750000; // microseconds, see usleep() +$options->window_size = 5; +$options->retries = 1; + +$multiClient = new CurlMultiClient($handler, $responseFactory, $options, $logger); + +// create and add the requests +foreach(['..', '...', '....'] as $item){ + $multiClient->addRequest($factory->createRequest('GET', $endpoint.'/'.$item)); +} + +// process the queue +$multiClient->process(); +``` + + +### `URLExtractor` + +The `URLExtractor` wraps a PSR-18 `ClientInterface` to extract and follow shortened URLs to their original location. + +```php +$urlExtractor = new URLExtractor($httpClient, $responseFactory); + +$request = $factory->createRequest('GET', 'https://t.co/ZSS6nVOcVp'); + +$urlExtractor->sendRequest($request); // -> response from the final location + +// you can retrieve an array with all followed locations afterwards +$responses = $this->http->getResponses(); // -> ResponseInterface[] + +// if you just want the URL of the final location, you can use the extract method: +$url = $this->http->extract('https://t.co/ZSS6nVOcVp'); // -> https://api.guildwars2.com/v2/build +``` + + +### `LoggingClient` + +The `LoggingClient` wraps a `ClientInterface` and outputs the HTTP messages in a readable way through a `LoggerInterface` (do NOT use in production!). + +```php +$loggingClient = new LoggingClient($httpClient, $logger); + +$loggingClient->sendRequest($request); // -> log to output given via logger +``` + + +### Auto generated API documentation + +The API documentation can be auto generated with [phpDocumentor](https://www.phpdoc.org/). +There 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. + +Locally created docs will appear in the directory `.build/phpdocs/`. If you'd like to create local docs, please follow these steps: + +- [download phpDocumentor](https://github.com/phpDocumentor/phpDocumentor/releases) v3+ as .phar archive +- run it in the repository root directory: + - on Windows `c:\path\to\php.exe c:\path\to\phpDocumentor.phar --config=phpdoc.xml` + - on Linux just `php /path/to/phpDocumentor.phar --config=phpdoc.xml` +- open [index.html](./.build/phpdocs/index.html) in a browser +- profit! + + ## Disclaimer Use at your own risk! diff --git a/composer.json b/composer.json index 465ab49f..744ab998 100644 --- a/composer.json +++ b/composer.json @@ -45,6 +45,9 @@ "phpunit/phpunit": "^10.5", "squizlabs/php_codesniffer": "^3.9" }, + "suggest": { + "chillerlan/php-oauth": "A PSR-7 OAuth client/handler that also acts as PSR-18 HTTP client" + }, "autoload": { "psr-4": { "chillerlan\\HTTP\\": "src/"