mintopia / flights
Library for searching Google Flights
Installs: 4
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/mintopia/flights
Requires
- php: ^8.4|^8.5
- psr/http-client: ^1.0
- psr/http-message: ^2.0
- psr/log: ^3.0
- psr/simple-cache: ^3.0
Requires (Dev)
- google/protobuf: ^4.33
- guzzlehttp/guzzle: ^7.10
- phpstan/phpstan: ^2.1
- squizlabs/php_codesniffer: ^4.0
- symfony/console: ^8.0
Suggests
- ext-protobuf: Protobuf implementation in C as a PHP extension
- google/protobuf: Protobuf implementation in PHP
- guzzlehttp/guzzle: Guzzle HTTP Client
This package is auto-updated.
Last update: 2025-12-12 07:14:34 UTC
README
Introduction
This is a PHP library for looking up flight information with Google Flights. There isn't an official free API so instead this uses the same endpoints that the Google Flights website does.
The Google Flights endpoint is a mix of protobuf and nested JSON arrays. This library will encode and decode the requests and extract the JSON from the HTML pages.
Requirements
- PHP 8.4
- Either
ext-protobufor thegoogle/protobufpackage.
Terminology
There's some terminology used in the library that is helpful to understand.
Flight- An individual flight, with a flight number, a departure and arrival time.Journey- 1 or more flights that make up a particular segment of trip, eg. Outbound or Return. It can contain multiple flights if there are connections. Each journey does have a price. You can add these using theaddSegmentmethod on the Search class.Itinerary- A collection of journeys that make up a single ticketed and priced trip. This would include both the and return flights.
Airports are represented by their 3-digit IATA codes, eg. LHR for London Heathrow or LON for all airports in
the London area.
Airlines are represented by their 2-digit IATA codes, eg. BA for British Airways or VS for Virgin Atlantic.
Usage
The main entrypoint is the \Mintopia\Flights\FlightService class. From here you can configure your search parameters
and then fetch all trips that meet those parameters.
Instantiating the Library
The library requires a PSR 18 compatible HTTP client and a Request Factory. A library like Guzzle is able to provide this. It can be passed in to the constructor or a service container can provide these.
$client = new GuzzleHttp\Client(); $requestFactory = new GuzzleHttp\Psr7\HttpFactory(); $search = new Mintopia\Flights\FlightService(requestFactory: $requestFactory, httpClient: $client);
You can also specify a PSR-3 compatible logging interface to either the constructor or via the setLogger method. If
one is isn't supplied then a null logger is used instead. An example using Monolog is:
// Our HTTP client and request factory from Guzzle use GuzzleHttp\Client; use GuzzleHttp\Psr7\HttpFactory; $client = new Client(); $requestFactory = new Psr7\HttpFactory(); // Create a logger using Monolog use Monolog\Level; use Monolog\Logger; use Monolog\Handler\StreamHandler; // Create a log channel to write to flights.log $log = new Logger('flights'); $log->pushHandler(new StreamHandler('flights.log', Level::Debug)); // Now create the flight search use Mintopia\Flights\FlightService; $search = new QueryBuilder(requestFactory: $requestFactory, httpClient: $client, logger: $log);
Searching for flights
Once you have a client, you can start a query and add segments to it, then when done call getItineraries(). The
library will then use Google Flights to fetch possible itineraries.
The query builder is immutable, so it will return new instance of itself on every mutable method call.
use GuzzleHttp\Client; use GuzzleHttp\Psr7\HttpFactory; use Mintopia\Flights\FlightService; // Our dependencies $client = new Client(); $requestFactory = new Psr7\HttpFactory(); // Create our search client $flightService = new FlightService($requestFactory, $client); $itineraries = $flightService->query()->addSegment( from: ['LHR', 'LGW'], to: 'JFK', date: '2025-12-10', maxStops: 0, airlines: ['BA', 'VS'] )->get();
This would perform a search for all flights on 10th December 2025 from London Heathrow and London Gatwick, to New York's JFK with no stops and limited to Virgin Atlantic.
$flightService = new FlightService($requestFactory, $client); $flightService->query()->addSegment('LHR', 'FAO')->get();
You can leave out most of the options, it'll default to tomorrow for the date with 0 stops and any airline. Airports can be specified either as an array for multiple or the single airport code.
To search for a return flight, add another segment:
$flightService = new FlightService($requestFactory, $client) $itineraries = $flightService ->query() ->addSegment('LGW', 'FAO', '+1 day') ->addSegment('FAO', 'LGW', '+3 days') ->get();
By default it searches for flights for one passenger, but you can add more:
use Mintopia\Flights\Enums\PassengerType; $flightService = new FlightService($requestFactory, $client) $itineraries = $flightService ->query() ->addSegment('LGW', 'FAO') ->addPassenger(PassengerType::Adult) ->get();
You can also set passengers in a single call:
$flightService = new FlightService($requestFactory, $client) $itineraries = $flightService ->query() ->addSegment('LGW', 'FAO') ->setPassengers([ PassengerType::Adult, PassengerType::Adult, PassengderType::Child, ]) ->get();
If you want to search for a different class, eg. Business or Premium Economy, you can also specify it:
use Mintopia\Flights\Enums\BookingClass; $flightService = new FlightService($requestFactory, $client) $itineraries = $flightService ->query() ->addSegment('LGW', 'FAO') ->setBookingClass(BookingClass::Business) ->get();
Finally you can sort the results by adding the sortOrder() call to the search.
use Mintopia\Flights\Enums\SortOrder; $flightService = new FlightService($requestFactory, $client) $itineraries = $flightService ->query() ->addSegment('LGW', 'FAO') ->sortOrder(SortOrder::Price) ->get();
Caching
The library supports a PSR16 compatible cache. To use it, either pass it in as a constructor argument or into the
setCache method. All HTTP requests that result in a 200 OK response will be cached for the TTL. You can set the TTL
with the setCacheTTL method which can take either a DateInterval object, a date interval string or a number of
seconds. The default is 1 hour.
There are two PSR16 cache interfaces included with the library, mostly for testing, and they aren't enabled by default. You can instantiate them and pass them in if you want them, but you probably have better ones available to you.
use Mintopia\Flights\FlightService; use Mintopia\Flights\Cache\MemoryCache; use Mintopia\Flights\Cache\FileCache; // The cache also supports a PSR-3 logger $log = new Logger('flights'); $log->pushHandler(new StreamHandler('flights.log', Level::Debug)); // Use the MemoryCache. This uses a PHP array in-memory and does not persist the cache. $memoryCache = new MemoryCache(log: $log); $flightService = new FlightService(cache: $memoryCache); // Use the FileCache instead. This will save the cache to a file in the temp directory by default, but you can override // if you want. $fileCache = new FileCache(cacheFilename: __DIR__ . '/cache'); $fileCache->setLogger($log); $flightService->setCache($fileCache);
The FileCache will automatically save the cache when the cache is deconstructed, but you can force it to be saved by
calling the flush() method on it. You can also pass in the argument autoFlush set to true in the constructor to
flush it automatically everytime the cache is modified.
Putting it all together
So let's see a full implementation of the library:
<?php // Include the composer autoload include __DIR__ . '/vendor/autoload.php'; // Third-party libraries use GuzzleHttp\Client; use GuzzleHttp\Psr7\HttpFactory; use Monolog\Level; use Monolog\Logger; use Monolog\Handler\StreamHandler; // Our library classes use Mintopia\Flights\FlightService; use Mintopia\Flights\Cache\FileCache; // Create a logger for flights.log $log = new Logger('flights'); $log->pushHandler(new StreamHandler('flights.log', Level::Debug)); // Make our HTTP dependencies $client = new Client(); $httpFactory = new HttpFactory(); // Now make our cache $cache = new FileCache($log, autoFlush: true); // Create our flight service and use it! $flightService = new FlightService($httpFactory, $client, $log, $cache); $itineraries = $flightService->query()->addSegment('LON', 'FAO')->get(); // Now iterate and do what you want with $itineraries
Contributing
Please fork and raise pull requests! If you encounter any issues, please raise it and I'll investigate and hopefully fix it.
The project is targeting PHP 8.4 onwards, any breaking changes for a version of PHP that is supported will result in a new major version.
PHPStan is used at level 8 for static analysis, PHP Code Sniffer is setup for PSR12 compliance. Testing is not written yet but the aim is to use PHPUnit, 100% coverage and mutation testing using Infection.
Finally - if you're using this in something cool - let me know! I love seeing things being used. If you're using it in something making you money - a coffee would be appreciated!
Development
There are some development libraries included for code quality, as well as Symfony Console to provide some CLI tooling to perform basic searches and to compile the protobuf files.
CLI One-Way Flight Search
This is mostly used for testing. Just specify the to/from airports. It'll do a search for 1 adult for the following day and 0 max stops.
flights search LGW FAO
For full help, use flights search --help
Compiling Protobuf Definitions
The flights.proto file contains the protobuf definitions that have been reverse engineered from Google Flights. This
was originally from the hexus07/google-flight-scraper Python
project.
If you have protoc installed, you can compile the protobuf files by using flights compile. They'll be built and
copied to the correct location.
Todo
- Support for multi city searches
- More features, plane type, WiFi, seat pitch, etc.
- Unit tests, coverage and mutation testing
- Full documentation
- Possibly an adapter to make it nice to use in Laravel with a Service Provider, Carbon for dates and Collections (this is done, I just need to publish it)
Thanks
- Zoƫ O'Connell for inspiring me with her find-flights project.
Licensing
Protobuf Definitions
The flights.proto file is based on hexus07/google_flight_scraper/ which is used under the MIT
license and has been modified further. The flights.proto file contains the copyright and license .
Flights Library
MIT License
Copyright (c) 2025 Jessica Smith
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.