{{ message }}
Repository navigation
Expand file tree
/
Copy pathREADME.md.erb
More file actions
589 lines (408 loc) · 18.4 KB
/
Copy pathREADME.md.erb
File metadata and controls
589 lines (408 loc) · 18.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
<%-
def snippet(path, property = nil)
source = File.read(path)
params_match = source.match(/\$this->searchParams\s*=\s*(\[.*?\]);/m)
raise "Could not find $this->searchParams in #{path}" unless params_match
raw_params = params_match[1]
# Re-indent: keep opening/closing bracket at column 0, indent inner lines by 2 spaces
raw_lines = raw_params.lines.map { |l| l.strip }
params = raw_lines.each_with_index.map { |l, i|
(i == 0 || i == raw_lines.length - 1) ? l : " #{l}"
}.join("\n")
property ||= source[/assertResponseHasProperty\(\s*\$response,\s*'([^']+)'/, 1] || 'organic_results'
code = "use SerpApi\\Client;\n\n"
code += "$client = new Client(getenv('SERPAPI_KEY'));\n"
code += "$results = $client->search(#{params});\n\n"
code += "print_r($results->#{property});\n"
"```php\n#{code}```\n\n * source: [#{path}](https://github.com/serpapi/serpapi-php/blob/master/#{path})"
end
-%>
# SerpApi PHP Library
[](https://packagist.org/packages/serpapi/serpapi-php)
[](https://www.php.net)
[](https://github.com/serpapi/serpapi-php/blob/master/MIT-LICENSE.txt)
Integrate search data into your PHP application. This library is the official wrapper for [SerpApi](https://serpapi.com).
SerpApi supports Google, Google Maps, Google Shopping, Baidu, Yandex, Yahoo, eBay, App Stores, and [more](https://serpapi.com).
This is the new library provided by SerpApi as a replacement for our old library that can be found [here](https://github.com/serpapi/google-search-results-php). Feel free to contact us if you need any help: contact@serpapi.com
[The full documentation is available here.](https://serpapi.com/search-api)
The following services are provided:
* [Search API](https://serpapi.com/search-api)
* [Location API](https://serpapi.com/locations-api)
* [Search Archive API](https://serpapi.com/search-archive-api)
* [Account API](https://serpapi.com/account-api)
* [Image API](https://serpapi.com/image-api)
SerpApi provides a [script builder](https://serpapi.com/playground) to get you started quickly.
## Installation
PHP 7.2+ with `ext-curl` and `ext-json` must be installed along with the [Composer](https://getcomposer.org/) dependency management tool.
Tested PHP versions:
* 7.2
* 7.3
* 7.4
* 8.0
* 8.1
* 8.2
* 8.3
* 8.4
* 8.5
Package available from [packagist](https://packagist.org/packages/serpapi/serpapi-php).
## Quick start
```bash
composer require serpapi/serpapi-php
```
## Simple usage
```php
require 'vendor/autoload.php';
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'));
$results = $client->search([
'q' => 'coffee',
]);
print_r($results->organic_results);
```
This example runs a search for "coffee" on Google. It returns the results as a PHP object decoded from JSON.
See the [playground](https://serpapi.com/playground) to generate your own code.
## Response formats
Use `search` for structured results decoded into a PHP object:
```php
$results = $client->search(['q' => 'coffee']);
echo $results->organic_results[0]->title;
```
Use `searchArray` for the same results as an associative array:
```php
$results = $client->searchArray(['q' => 'coffee']);
echo $results['organic_results'][0]['title'];
```
Use `md` for a token-efficient Markdown string optimized for LLMs and AI agents:
```php
$markdown = $client->md(['q' => 'coffee']);
```
Use `html` when you need the raw search-engine response:
```php
$html = $client->html(['q' => 'coffee']);
```
Archived results are also available as Markdown with `$client->searchArchive($searchId, 'md')`.
Learn more about [SerpApi Markdown output](https://serpapi.com/markdown-output).
## Configuration
### API key
The API key can be set in the constructor or later via `setApiKey`:
```php
use SerpApi\Client;
// via constructor
$client = new Client('Your Private Key');
// or later
$client = new Client();
$client->setApiKey('Your Private Key');
```
Get your API key from [serpapi.com/dashboard](https://serpapi.com/dashboard).
### Engine
The default engine is `google`. You can change it via the second constructor parameter:
```php
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'), 'bing');
$results = $client->search(['q' => 'coffee']);
```
### Timeout
The default request timeout is 120 seconds. Customize it via the third constructor parameter:
```php
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'), 'google', 30);
```
Or for a single request:
```php
$results = $client->search(['q' => 'coffee', 'timeout' => 10]);
```
### Default search parameters
The constructor also accepts a single array. `api_key`, `engine`, `timeout`, and `persistent` configure the client; every other key becomes a default search parameter sent with every request:
```php
use SerpApi\Client;
$client = new Client([
'api_key' => getenv('SERPAPI_KEY'),
'engine' => 'google',
'hl' => 'en',
'gl' => 'us',
]);
// q=coffee, hl=en, gl=us
$results = $client->search(['q' => 'coffee']);
// Per-call parameters take precedence: q=coffee, hl=fr, gl=us
$results = $client->search(['q' => 'coffee', 'hl' => 'fr']);
// null drops a default for one call: q=coffee, hl=en
$results = $client->search(['q' => 'coffee', 'gl' => null]);
```
With positional arguments, pass default search parameters fourth: `new Client($apiKey, 'google', 30, ['hl' => 'en'])`.
### Persistent connections
The client keeps its connection to SerpApi open and reuses it, so only the first request pays for the DNS lookup and TLS handshake. The connection closes when the client is destroyed, or explicitly with `close()`:
```php
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'));
$client->search(['q' => 'coffee']);
$client->search(['q' => 'tea']); // reuses the connection
$client->close();
```
A closed client reconnects on its next request. To open a new connection for every request instead, pass `'persistent' => false` in the configuration array. [`demo/demo_persistent.php`](demo/demo_persistent.php) compares the two.
### Debugging
`inspect()`, `var_dump()`, and `print_r()` mask the API key:
```php
echo $client->inspect();
// #<SerpApi\Client @engine=google @timeout=120 @persistent=true @api_key=abcd****wxyz>
```
`var_export()` bypasses the mask and prints the key in clear text.
## Search API
### Search Google
<%= snippet('tests/ExampleSearchGoogleTest.php') %>
see: [https://serpapi.com/search-api](https://serpapi.com/search-api)
### Search Google Scholar
<%= snippet('tests/ExampleSearchGoogleScholarTest.php') %>
see: [https://serpapi.com/google-scholar-api](https://serpapi.com/google-scholar-api)
### Search Google Autocomplete
<%= snippet('tests/ExampleSearchGoogleAutocompleteTest.php') %>
see: [https://serpapi.com/google-autocomplete-api](https://serpapi.com/google-autocomplete-api)
### Search Google Shopping
<%= snippet('tests/ExampleSearchGoogleShoppingTest.php') %>
see: [https://serpapi.com/google-shopping-api](https://serpapi.com/google-shopping-api)
### Search Google Maps
<%= snippet('tests/ExampleSearchGoogleMapsTest.php') %>
see: [https://serpapi.com/google-maps-api](https://serpapi.com/google-maps-api)
### Search Google Jobs
<%= snippet('tests/ExampleSearchGoogleJobsTest.php') %>
see: [https://serpapi.com/google-jobs-api](https://serpapi.com/google-jobs-api)
### Search Google Events
<%= snippet('tests/ExampleSearchGoogleEventsTest.php') %>
see: [https://serpapi.com/google-events-api](https://serpapi.com/google-events-api)
### Search Google Lens
<%= snippet('tests/ExampleSearchGoogleLensTest.php') %>
see: [https://serpapi.com/google-lens-api](https://serpapi.com/google-lens-api)
To search with a local image instead of a URL, upload it with the [Image API](#image-api).
### Search Google Play
<%= snippet('tests/ExampleSearchGooglePlayTest.php') %>
see: [https://serpapi.com/google-play-api](https://serpapi.com/google-play-api)
### Search Google Local Services
<%= snippet('tests/ExampleSearchGoogleLocalServicesTest.php') %>
see: [https://serpapi.com/google-local-services-api](https://serpapi.com/google-local-services-api)
### Search Google Images
<%= snippet('tests/ExampleSearchGoogleImagesTest.php') %>
see: [https://serpapi.com/google-images-api](https://serpapi.com/google-images-api)
### Search Google Images Light
<%= snippet('tests/ExampleSearchGoogleImagesLightTest.php') %>
see: [https://serpapi.com/google-images-light-api](https://serpapi.com/google-images-light-api)
### Search Google News
<%= snippet('tests/ExampleSearchGoogleNewsTest.php') %>
see: [https://serpapi.com/google-news-api](https://serpapi.com/google-news-api)
### Search Google News Light
<%= snippet('tests/ExampleSearchGoogleNewsLightTest.php') %>
see: [https://serpapi.com/google-news-light-api](https://serpapi.com/google-news-light-api)
### Search Google Videos
<%= snippet('tests/ExampleSearchGoogleVideosTest.php') %>
see: [https://serpapi.com/google-videos-api](https://serpapi.com/google-videos-api)
### Search Google Light
<%= snippet('tests/ExampleSearchGoogleLightTest.php') %>
see: [https://serpapi.com/google-light-api](https://serpapi.com/google-light-api)
### Search Google AI Mode
<%= snippet('tests/ExampleSearchGoogleAiModeTest.php') %>
see: [https://serpapi.com/google-ai-mode-api](https://serpapi.com/google-ai-mode-api)
### Search Google AI Overview
The AI Overview API takes a `page_token` from a Google search. Google shows most AI Overviews inline, so the token is only present for some queries, and it expires a minute after the search:
```php
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'));
$search = $client->search(['q' => 'how does art work in android']);
if (isset($search->ai_overview->page_token)) {
$results = $client->search([
'engine' => 'google_ai_overview',
'page_token' => $search->ai_overview->page_token,
]);
print_r($results->ai_overview);
}
```
* source: [tests/ExampleSearchGoogleAiOverviewTest.php](https://github.com/serpapi/serpapi-php/blob/master/tests/ExampleSearchGoogleAiOverviewTest.php)
see: [https://serpapi.com/google-ai-overview-api](https://serpapi.com/google-ai-overview-api)
### Search Google Product
The Product API takes the `immersive_product_page_token` of a Google Shopping result, or a `product_id`:
```php
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'));
$shopping = $client->search(['engine' => 'google_shopping', 'q' => 'coffee maker']);
$results = $client->search([
'engine' => 'google_product',
'page_token' => $shopping->shopping_results[0]->immersive_product_page_token,
]);
print_r($results->product_results);
```
* source: [tests/ExampleSearchGoogleProductTest.php](https://github.com/serpapi/serpapi-php/blob/master/tests/ExampleSearchGoogleProductTest.php)
see: [https://serpapi.com/google-product-api](https://serpapi.com/google-product-api)
### Search Google Immersive Product
The Immersive Product API takes the `immersive_product_page_token` of a Google Shopping result:
```php
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'));
$shopping = $client->search(['engine' => 'google_shopping', 'q' => 'coffee maker']);
$results = $client->search([
'engine' => 'google_immersive_product',
'page_token' => $shopping->shopping_results[0]->immersive_product_page_token,
]);
print_r($results->product_results);
```
* source: [tests/ExampleSearchGoogleImmersiveProductTest.php](https://github.com/serpapi/serpapi-php/blob/master/tests/ExampleSearchGoogleImmersiveProductTest.php)
see: [https://serpapi.com/google-immersive-product-api](https://serpapi.com/google-immersive-product-api)
### Search Google Flights
<%= snippet('tests/ExampleSearchGoogleFlightsTest.php', 'best_flights') %>
see: [https://serpapi.com/google-flights-api](https://serpapi.com/google-flights-api)
### Search Google Hotels
<%= snippet('tests/ExampleSearchGoogleHotelsTest.php') %>
see: [https://serpapi.com/google-hotels-api](https://serpapi.com/google-hotels-api)
### Search Google Finance
<%= snippet('tests/ExampleSearchGoogleFinanceTest.php') %>
see: [https://serpapi.com/google-finance-api](https://serpapi.com/google-finance-api)
### Search Google Trends
<%= snippet('tests/ExampleSearchGoogleTrendsTest.php') %>
see: [https://serpapi.com/google-trends-api](https://serpapi.com/google-trends-api)
### Search Google Patents
<%= snippet('tests/ExampleSearchGooglePatentsTest.php') %>
see: [https://serpapi.com/google-patents-api](https://serpapi.com/google-patents-api)
### Search Google Reverse Image
<%= snippet('tests/ExampleSearchGoogleReverseImageTest.php') %>
see: [https://serpapi.com/google-reverse-image](https://serpapi.com/google-reverse-image)
### Search Bing
<%= snippet('tests/ExampleSearchBingTest.php') %>
see: [https://serpapi.com/bing-search-api](https://serpapi.com/bing-search-api)
### Search Baidu
<%= snippet('tests/ExampleSearchBaiduTest.php') %>
see: [https://serpapi.com/baidu-search-api](https://serpapi.com/baidu-search-api)
### Search Yahoo
<%= snippet('tests/ExampleSearchYahooTest.php') %>
see: [https://serpapi.com/yahoo-search-api](https://serpapi.com/yahoo-search-api)
### Search YouTube
<%= snippet('tests/ExampleSearchYoutubeTest.php') %>
see: [https://serpapi.com/youtube-search-api](https://serpapi.com/youtube-search-api)
### Search Walmart
<%= snippet('tests/ExampleSearchWalmartTest.php') %>
see: [https://serpapi.com/walmart-search-api](https://serpapi.com/walmart-search-api)
### Search eBay
<%= snippet('tests/ExampleSearchEbayTest.php') %>
see: [https://serpapi.com/ebay-search-api](https://serpapi.com/ebay-search-api)
### Search Naver
<%= snippet('tests/ExampleSearchNaverTest.php') %>
see: [https://serpapi.com/naver-search-api](https://serpapi.com/naver-search-api)
### Search Home Depot
<%= snippet('tests/ExampleSearchHomeDepotTest.php') %>
see: [https://serpapi.com/home-depot-search-api](https://serpapi.com/home-depot-search-api)
### Search Apple App Store
<%= snippet('tests/ExampleSearchAppleAppStoreTest.php') %>
see: [https://serpapi.com/apple-app-store](https://serpapi.com/apple-app-store)
### Search DuckDuckGo
<%= snippet('tests/ExampleSearchDuckduckgoTest.php') %>
see: [https://serpapi.com/duckduckgo-search-api](https://serpapi.com/duckduckgo-search-api)
### Search Amazon
<%= snippet('tests/ExampleSearchAmazonTest.php') %>
see: [https://serpapi.com/amazon-search-api](https://serpapi.com/amazon-search-api)
### Search Yandex
<%= snippet('tests/ExampleSearchYandexTest.php') %>
see: [https://serpapi.com/yandex-search-api](https://serpapi.com/yandex-search-api)
### Search Yelp
<%= snippet('tests/ExampleSearchYelpTest.php') %>
see: [https://serpapi.com/yelp-search-api](https://serpapi.com/yelp-search-api)
## APIs supported
### Location API
```php
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'));
$locations = $client->location(['q' => 'Austin', 'limit' => 3]);
echo "Number of locations: " . count($locations) . "\n";
print_r($locations);
```
NOTE: `api_key` is not required for this endpoint.
### Search Archive API
First, run a search and save the search ID:
```php
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'));
$results = $client->search([
'q' => 'Coffee',
'location' => 'Austin, Texas',
]);
$search_id = $results->search_metadata->id;
```
Now retrieve the previous search from the archive (free of charge):
```php
$archived = $client->searchArchive($search_id);
print_r($archived);
$markdown = $client->searchArchive($search_id, 'md');
echo $markdown;
```
### Account API
```php
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'));
$account = $client->account();
print_r($account);
```
### Image API
Upload a local image, then search with its `image_id` on engines that accept uploaded images, such as Google Lens:
```php
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'));
$upload = $client->uploadImage('path/to/image.jpg');
$results = $client->search([
'engine' => 'google_lens',
'image_id' => $upload->image_id,
]);
print_r($results->visual_matches);
```
`uploadImage` also accepts an open stream, such as `fopen('path/to/image.jpg', 'rb')`. Images must be JPG, PNG, or WebP files up to 500 KB, and an `image_id` expires after 10 minutes.
see: [https://serpapi.com/image-api](https://serpapi.com/image-api) and [https://serpapi.com/google-lens-upload-an-image](https://serpapi.com/google-lens-upload-an-image)
### HTML results
```php
use SerpApi\Client;
$client = new Client(getenv('SERPAPI_KEY'));
$html = $client->html(['q' => 'Coffee']);
echo strlen($html) . " bytes of HTML\n";
```
## Error handling
`SerpApiException` includes structured context for HTTP and API errors (status code, endpoint, search params, search id).
```php
use SerpApi\Client;
use SerpApi\SerpApiException;
try {
$client = new Client('invalid_key');
$client->search(['q' => 'test']);
} catch (SerpApiException $exception) {
echo $exception->getMessage() . "\n";
// HTTP request failed with status: 401 error: Invalid API key... from url: https://serpapi.com/search
echo $exception->getSerpApiError() . "\n";
echo $exception->getResponseStatus() . "\n";
echo $exception->getSearchId() . "\n";
print_r($exception->getSearchParams());
print_r($exception->toArray());
}
```
## Testing
We love "true open source", "continuous integration", and Test Driven Development (TDD).
We use PHPUnit to test our infrastructure around the clock using [GitHub Actions](https://github.com/serpapi/serpapi-php/actions/workflows/serpapi-php.yml) to achieve the best QoS (Quality of Service).
The `tests/` directory includes specifications that serve the dual purpose of examples and functional tests.
Set your secret API key in your shell before running tests:
```bash
export SERPAPI_KEY="your_secret_key"
```
Install dependencies and run the test suite:
```bash
make install
make test
```
Run the linter and static analysis:
```bash
make lint
make analyse
```
The `demo/` directory holds runnable scripts, including a batch of async searches and a persistent connection benchmark:
```bash
make demo
```
Contributions are welcome. Feel free to submit a pull request!
## Change log
* 1.0 - First stable version
## Conclusion
SerpApi supports all the major search engines. Google has more advanced support, with all the major services available: Images, News, Shopping, and more...
[The full documentation is available here.](https://serpapi.com/search-api)
Authors: Victor Benarbia victor@serpapi.com, Alaa Abdulridha alaa@serpapi.com
For more information: https://serpapi.com
## License
[MIT](MIT-LICENSE.txt)
You can’t perform that action at this time.
