Skip to content

Commit 8ffb3c2

Browse files
committed
Made the SDK Client immutable
1 parent 57874f5 commit 8ffb3c2

File tree

2 files changed

+54
-202
lines changed

2 files changed

+54
-202
lines changed

README.md

Lines changed: 24 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,6 @@ require '/path/to/you/vendor/autoload.php';
2424
//Create and configure a new SDK client
2525
$sdk = new Client('YOU_TOKEN');
2626

27-
//Setup ScraperAPI parameters according to the documentation
28-
$sdk
29-
->setCountryCode('us')
30-
->setDeviceType('desktop')
31-
->setKeepHeaders(true)
32-
->addHeader('Accept', 'application/json');
33-
3427
//Send request
3528
$response = $sdk->get('https://example.com');
3629

@@ -43,6 +36,8 @@ echo $response->getBody()->getContents();
4336
The client is configured through the constructor parameters:
4437

4538
* ```$apiKey``` (required) - your API key from [ScraperAPI dashboard](https://dashboard.scraperapi.com/dashboard).
39+
* ```$defaultApiParams``` - default API parameters for requests
40+
* ```$defaultHeaders``` - default HTTP headers
4641
* ```$timeout``` (default ```60```) - request timeout.
4742
* ```$tries``` (default ```3```) - number of request attempts.
4843
* ```$delayMultiplier``` (default ```1```) - delay multiplier before new request attempt in seconds. Multiplier 3 means
@@ -61,67 +56,44 @@ The client is configured through the constructor parameters:
6156
### API parameters
6257

6358
Configuring default API functionality according to [ScraperAPI documentation](https://www.scraperapi.com/documentation/)
64-
. The default settings apply to all requests, unless they are overridden at the request level. All parameters are set
65-
using fluent setters:
59+
. The default settings apply to all requests, unless they are overridden at the request level. You can set the default
60+
options only from constructor (SDK client is immutable), using the second parameter:
6661

6762
```php
68-
$sdk
69-
->setCountryCode('us') //activate country geotargetting
70-
->setRender(true) //activate javascript rendering
71-
->setPremium(false) //activate premium residential and mobile IPs
72-
->setSessionNumber(123) //reuse the same proxy
73-
->setKeepHeaders(true) //use your own custom headers
74-
->setDeviceType('mobile') //set mobile or desktop user agents
75-
->setAutoparse(false); //activate auto parsing for select websites
76-
```
77-
78-
Or you can set all parameters in single ```setParams()``` method using an array. This method erases all previously set
79-
parameters.
80-
81-
```php
82-
$sdk->setParams([
83-
'country_code' => 'us',
84-
'render' => true,
85-
'premium' => false,
86-
'session_number' => 123,
87-
'keep_headers' => true,
88-
'device_type' => 'mobile',
89-
'autoparse' => 'false',
90-
]);
63+
$defaultApiParams = [
64+
'country_code' => 'us', //activate country geotargetting
65+
'render' => true, //activate javascript rendering
66+
'premium' => false, //activate premium residential and mobile IPs
67+
'session_number' => 123, //reuse the same proxy
68+
'keep_headers' => true, //use your own custom headers
69+
'device_type' => 'mobile', //set mobile or desktop user agents
70+
'autoparse' => 'false', //activate auto parsing for select websites
71+
];
72+
$sdk = new Client('YOU_TOKEN', $defaultApiParams);
9173
```
9274

9375
### Headers
9476

95-
You can add default headers by ```addHeader()``` method. Don't forget to enable ```keep_headers``` to allow your headers
96-
to be used!
77+
You can add default headers with the third parameter of the constructor. Don't forget to enable ```keep_headers``` to
78+
allow your headers to be used!
9779

9880
```php
99-
$sdk
100-
->setKeepHeaders(true)
101-
->addHeader('Referer', 'https://example.com/')
102-
->addHeader('Accept', 'application/json');
103-
```
104-
105-
Or set headers in one step by ```setHeaders()``` method. This method erases all previously set headers.
106-
107-
```php
108-
$sdk
109-
->setKeepHeaders(true)
110-
->setHeaders([
111-
'Referer' => 'https://example.com/',
112-
'Accept' => 'application/json',
113-
]);
81+
$defaultHeaders = [
82+
'Referer' => 'https://example.com/',
83+
'Accept' => 'application/json',
84+
];
85+
$sdk = new Client('YOU_TOKEN', ['keep_headers' => true], $defaultHeaders);
11486
```
11587

11688
## Requests
11789

11890
SDK supports ```GET```, ```POST``` and ```PUT``` HTTP methods. Standard parameters of each request methods:
11991

12092
1. ```$url``` (required) - url of scrapped resource.
121-
2. ```$apiParams``` (default ```null```) - to set the API settings for the request. They will override the defaults set
122-
in the SDK Client object (only those that overlap).
93+
2. ```$apiParams``` (default ```null```) - to set the API settings for the request. They will override the defaults from
94+
the SDK Client (only those that overlap).
12395
3. ```$headers``` (default ```null```) - to set headers for the request. Just like ```$apiParams```, they will override
124-
the defaults set in the SDK Client object (only those that overlap).
96+
the defaults from the SDK Client (only those that overlap).
12597

12698
### Synchronous
12799

src/Client.php

Lines changed: 30 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -18,59 +18,43 @@
1818

1919
/**
2020
* ScraperAPI documentation - https://www.scraperapi.com/documentation/
21-
*
22-
* @method Client setCountryCode($value) Activate country geotargetting ('us' for example)
23-
* @method Client setRender($value) Activate javascript rendering (true/false)
24-
* @method Client setPremium($value) Activate premium residential and mobile IPs (true/false)
25-
* @method Client setSessionNumber($value) Reuse the same proxy (123 for example)
26-
* @method Client setKeepHeaders($value) Use your own custom headers (true/false)
27-
* @method Client setDeviceType($value) Set your requests to use mobile or desktop user agents (desktop/mobile)
28-
* @method Client setAutoparse($value) Activate auto parsing for select websites (true/false)
2921
*/
3022
class Client
3123
{
3224
/**
3325
* ScraperAPI endpoint url
3426
*/
3527
private const API = 'https://api.scraperapi.com';
36-
37-
/**
38-
* ScraperAPI available query params
39-
*/
40-
private const PARAMS_LIST = [
41-
'country_code',
42-
'render',
43-
'premium',
44-
'session_number',
45-
'keep_headers',
46-
'device_type',
47-
'autoparse'
48-
];
49-
5028
/**
5129
* ScraperAPI API key
5230
* @var string
5331
*/
5432
private $apiKey;
55-
33+
/**
34+
* ScraperAPI default request params
35+
* @var array
36+
*/
37+
private $defaultApiParams;
38+
/**
39+
* Default headers
40+
* @var array
41+
*/
42+
private $defaultHeaders;
5643
/**
5744
* If true, debug statement sent to the output. Useful for debugging async requests
5845
* @var bool
5946
*/
6047
private $printDebugInfo;
61-
6248
/**
6349
* If false, API key in debug statement will be replaced by 'API_KEY' string
6450
* @var bool
6551
*/
6652
private $showApiKey;
67-
6853
/**
6954
* Guzzle client
7055
* @var Guzzle
7156
*/
7257
private $guzzle;
73-
7458
/**
7559
* Optional PSR-3 logger for debug
7660
* @var LoggerInterface|null
@@ -81,19 +65,6 @@ class Client
8165
* @var mixed
8266
*/
8367
private $logLevel;
84-
85-
/**
86-
* ScraperAPI default request params
87-
* @var array
88-
*/
89-
private $params = [];
90-
91-
/**
92-
* Default headers
93-
* @var array
94-
*/
95-
private $headers = [];
96-
9768
/**
9869
* Total promises in a bunch (for debug statements)
9970
* @var int
@@ -105,13 +76,12 @@ class Client
10576
*/
10677
private $fulfilledPromises = 0;
10778

108-
/** @var array */
109-
private $paramsList;
110-
11179
/**
11280
* ScraperAPI documentation - https://www.scraperapi.com/documentation/
11381
*
11482
* @param string $apiKey ScraperAPI API key
83+
* @param array|null $defaultApiParams Default api parameters for requests
84+
* @param array|null $defaultHeaders Default headers for requests
11585
* @param int $timeout Request timeout
11686
* @param int $tries Number of request attempts
11787
* @param int $delayMultiplier Delay multiplier before new request attempt in seconds
@@ -123,6 +93,8 @@ class Client
12393
*/
12494
public function __construct(
12595
string $apiKey,
96+
?array $defaultApiParams = [],
97+
?array $defaultHeaders = [],
12698
int $timeout = 60,
12799
int $tries = 3,
128100
int $delayMultiplier = 1,
@@ -134,13 +106,25 @@ public function __construct(
134106
)
135107
{
136108
$this->apiKey = $apiKey;
109+
$this->defaultApiParams = $defaultApiParams ?? [];
110+
$this->defaultHeaders = $defaultHeaders ?? [];
137111
$this->printDebugInfo = $printDebugInfo;
138112
$this->showApiKey = $showApiKey;
139113
$this->logger = $logger;
140114
$this->logLevel = $logLevel;
141115

142-
$this->paramsList = array_flip(static::PARAMS_LIST);
116+
$this->guzzle = $this->createGuzzleClient($timeout, $tries, $delayMultiplier, $maxExceptionsLength);
117+
}
143118

119+
/**
120+
* @param int $timeout
121+
* @param int $tries
122+
* @param int $delayMultiplier
123+
* @param int $maxExceptionsLength
124+
* @return Guzzle
125+
*/
126+
private function createGuzzleClient(int $timeout, int $tries, int $delayMultiplier, int $maxExceptionsLength): Guzzle
127+
{
144128
$handlerStack = HandlerStack::create();
145129
$handlerStack->push(Middleware::retry(
146130
function (
@@ -176,113 +160,9 @@ function ($try) use ($delayMultiplier) {
176160
));
177161
$handlerStack->push(Middleware::httpErrors(new BodySummarizer($maxExceptionsLength)), 'http_errors');
178162

179-
$this->guzzle = new Guzzle(['base_uri' => static::API, 'timeout' => $timeout, 'handler' => $handlerStack]);
180-
}
181-
182-
183-
/**
184-
* Caller for Client default query params setters
185-
*
186-
* @param string $name
187-
* @param array $arguments
188-
* @return $this
189-
* @throws Exception
190-
*/
191-
public function __call(string $name, array $arguments)
192-
{
193-
194-
if (strpos($name, 'set') === 0) {
195-
$this->setter($name, $arguments);
196-
return $this;
197-
}
198-
199-
throw new Exception("Unknown method '$name'.");
163+
return new Guzzle(['base_uri' => static::API, 'timeout' => $timeout, 'handler' => $handlerStack]);
200164
}
201165

202-
/**
203-
* @param string $name
204-
* @param array $arguments
205-
*/
206-
private function setter(string $name, array $arguments): void
207-
{
208-
$paramName = $this->parseParamName($name);
209-
if (array_key_exists($paramName, $this->paramsList)) {
210-
$this->setParam($paramName, $arguments);
211-
}
212-
}
213-
214-
/**
215-
* @param string $name
216-
* @param array $arguments
217-
*/
218-
private function setParam(string $name, array $arguments): void
219-
{
220-
$paramValue = $arguments[0] ?? null;
221-
if ((!is_string($paramValue) && !is_bool($paramValue))) {
222-
$paramValue = (string)$paramValue;
223-
}
224-
if (is_bool($paramValue)) {
225-
$paramValue = $paramValue ? 'true' : 'false';
226-
}
227-
$this->params[$name] = $paramValue;
228-
}
229-
230-
/**
231-
* @param string $name
232-
* @return string
233-
*/
234-
private function parseParamName(string $name): string
235-
{
236-
$words = preg_split('/(?=[A-Z])/', substr($name, 3));
237-
if (!$words) {
238-
return '';
239-
}
240-
241-
return (string)array_reduce($words, static function ($carry, $item) {
242-
if ($item === '') {
243-
return $carry;
244-
}
245-
return ($carry === '' || $carry === null) ? strtolower($item) : "{$carry}_" . strtolower($item);
246-
});
247-
248-
}
249-
250-
/**
251-
* Set Client default query params in one step from array, replacing existing ones
252-
*
253-
* @param array $params
254-
* @return Client
255-
*/
256-
public function setParams(array $params): Client
257-
{
258-
$this->params = $params;
259-
return $this;
260-
}
261-
262-
/**
263-
* Add default header to Client
264-
* @param string $header
265-
* @param array|string $value
266-
* @return $this
267-
*/
268-
public function addHeader(string $header, $value): Client
269-
{
270-
$this->headers[$header] = $value;
271-
return $this;
272-
}
273-
274-
/**
275-
* Set default Client headers in one step from array, replacing existing ones
276-
* @param array $headers
277-
* @return $this
278-
*/
279-
public function setHeaders(array $headers): Client
280-
{
281-
$this->headers = $headers;
282-
return $this;
283-
}
284-
285-
286166
/**
287167
* Get info about ScraperAPI account
288168
*
@@ -415,14 +295,14 @@ private function prepareQueryParams(
415295
?array $json
416296
): array
417297
{
418-
$params = $this->params;
298+
$params = $this->defaultApiParams;
419299
if (is_array($apiParams)) {
420300
foreach ($apiParams as $param => $value) {
421301
$params[$param] = $value;
422302
}
423303
}
424304

425-
$resultHeaders = $this->headers;
305+
$resultHeaders = $this->defaultHeaders;
426306
if (is_array($headers)) {
427307
foreach ($headers as $param => $value) {
428308
$resultHeaders[$param] = $value;

0 commit comments

Comments
 (0)