Skip to content

Commit 51df86b

Browse files
committed
1 parent 3196ca5 commit 51df86b

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

examples/curl_multi.php

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
/**
3+
* cURL multi example, fetch data from the GUildWars2 items API
4+
* @link https://wiki.guildwars2.com/wiki/API:2/items
5+
*
6+
* @filesource curl_multi.php
7+
* @created 08.11.2019
8+
* @author smiley <smiley@chillerlan.net>
9+
* @copyright 2019 smiley
10+
* @license MIT
11+
*/
12+
13+
use chillerlan\HTTP\CurlUtils\{CurlMultiClient, MultiResponseHandlerInterface};
14+
use chillerlan\HTTP\HTTPOptions;
15+
use chillerlan\HTTP\Psr18\CurlClient;
16+
use chillerlan\HTTP\Psr7\Request;
17+
use Psr\Http\Message\{RequestInterface, ResponseInterface};
18+
use function chillerlan\HTTP\Psr7\{build_http_query, get_json};
19+
20+
require_once __DIR__.'/../vendor/autoload.php';
21+
22+
23+
// invoke the http clients
24+
$options = new HTTPOptions([
25+
'ca_info' => __DIR__.'/cacert.pem',
26+
'sleep' => 60 / 300 * 1000000, // GW2 API limit: 300 requests/minute
27+
# 'user_agent' => 'my fancy http client',
28+
]);
29+
30+
$client = new CurlClient($options);
31+
$multiClient = new CurlMultiClient($options);
32+
33+
34+
// request the list of item ids
35+
$endpoint = 'https://api.guildwars2.com/v2/items';
36+
$itemResponse = $client->sendRequest(new Request('GET', $endpoint));
37+
38+
if($itemResponse->getStatusCode() !== 200){
39+
exit('/v2/items fetch error');
40+
}
41+
42+
43+
// chunk the response into arrays of 200 ids each (API limit) and create Request objects for each desired language
44+
$languages = ['de', 'en', 'es'];//, 'fr', 'zh'
45+
$requests = [];
46+
47+
foreach(array_chunk(get_json($itemResponse), 200) as $chunk){
48+
foreach($languages as $lang){
49+
$requests[] = new Request('GET', $endpoint.'?'.build_http_query(['lang' => $lang, 'ids' => implode(',', $chunk)]));
50+
}
51+
}
52+
53+
54+
// create directories for each language to dump the item responses into
55+
foreach($languages as $lang){
56+
$dir = __DIR__.'/'.$lang;
57+
58+
if(!file_exists($dir)){
59+
mkdir($dir);
60+
}
61+
}
62+
63+
64+
// the multi request handler
65+
$handler = new class() implements MultiResponseHandlerInterface{
66+
67+
public function handleResponse(ResponseInterface $response, RequestInterface $request, int $id, array $curl_info):?RequestInterface{
68+
69+
// the API returns either 200 or 206 on OK responses
70+
// https://gitter.im/arenanet/api-cdi?at=5738e2c0ae26c1967f9eb4a0
71+
if(in_array($response->getStatusCode(), [200, 206], true)){
72+
$lang = $response->getHeaderLine('content-language');
73+
74+
// create a file for each item in the response (ofc you'd rather put this in a DB)
75+
foreach(get_json($response) as $item){
76+
$file = $lang.'/'.$item->id;
77+
file_put_contents(__DIR__.'/'.$file.'.json', json_encode($item, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
78+
79+
echo $file.PHP_EOL;
80+
}
81+
82+
// response ok, nothing to return
83+
return null;
84+
}
85+
86+
// return the failed request back to the stack
87+
return $request;
88+
}
89+
90+
};
91+
92+
93+
// run the whole thing
94+
$multiClient
95+
->setMultiResponseHandler($handler)
96+
->addRequests($requests)
97+
->process()
98+
;
99+

0 commit comments

Comments
 (0)