Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
C

chrome

> 编程语言
Open source

Instrument headless chrome/chromium instances from PHP

2.7K stars0 likes2 views
WebsiteGitHub

About

Instrument headless chrome/chromium instances from PHP

Chrome PHP

This library lets you start playing with chrome/chromium in headless mode from PHP.

Can be used synchronously and asynchronously!

Features

  • Open Chrome or Chromium browser from php
  • Create pages and navigate to pages
  • Take screenshots
  • Evaluate javascript on the page
  • Make PDF
  • Emulate mouse
  • Emulate keyboard
  • Always IDE friendly

Happy browsing!

Requirements

Requires PHP 7.4-8.5 and a Chrome/Chromium 65+ executable.

Note that the library is only tested on Linux but is compatible with macOS and Windows.

Installation

The library can be installed with Composer and is available on packagist under chrome-php/chrome:

bash
$ composer require chrome-php/chrome

Usage

It uses a simple and understandable API to start Chrome, to open pages, take screenshots, crawl websites... and almost everything that you can do with Chrome as a human.

…

Using different Chrome executable

When starting, the factory will look for the environment variable "CHROME_PATH" to use as the Chrome executable. If the variable is not found, it will try to guess the correct executable path according to your OS or use "chrome" as the default.

You are also able to explicitly set up any executable of your choice when creating a new object. For instance "chromium-browser":

php
use HeadlessChromium\BrowserFactory;

// replace default 'chrome' with 'chromium-browser'
$browserFactory = new BrowserFactory('chromium-browser');

Debugging

The following example disables headless mode to ease debugging

php
use HeadlessChromium\BrowserFactory;

$browserFactory = new BrowserFactory();

$browser = $browserFactory->createBrowser([
    'headless' => false, // disable headless mode
]);

Other debug options:

php
[
    'connectionDelay' => 0.8,            // add 0.8 second of delay between each instruction sent to Chrome,
    'debugLogger'     => 'php://stdout', // will enable verbose mode
]

About debugLogger: this can be any of a resource string, a resource, or an object implementing LoggerInterface from Psr\Log (such as monolog or apix/log).

API

Browser Factory

Options set directly in the createBrowser method will be used only for a single browser creation. The default options will be ignored.

php
use HeadlessChromium\BrowserFactory;

$browserFactory = new BrowserFactory();
$browser = $browserFactory->createBrowser([
    'windowSize'   => [1920, 1000],
    'enableImages' => false,
]);

// this browser will be created without any options
$browser2 = $browserFactory->createBrowser();

Options set using the setOptions and addOptions methods will persist.

php
$browserFactory->setOptions([
    'windowSize' => [1920, 1000],
]);

// both browser will have the same 'windowSize' option
$browser1 = $browserFactory->createBrowser();
$browser2 = $browserFactory->createBrowser();

$browserFactory->addOptions(['enableImages' => false]);

// this browser will have both the 'windowSize' and 'enableImages' options
$browser3 = $browserFactory->createBrowser();

$browserFactory->addOptions(['enableImages' => true]);

// this browser will have the previous 'windowSize', but 'enableImages' will be true
$browser4 = $browserFactory->createBrowser();

Available options

Here are the options available for the browser factory:

Option name Default Description
connectionDelay 0 Delay to apply between each operation for debugging purposes
customFlags none An array of flags to pass to the command line. Eg: ['--option1', '--option2=someValue']
debugLogger null A string (e.g "php://stdout"), or resource, or PSR-3 logger instance to print debug messages
disableJavascript false Disable JavaScript execution on every page created via createPage()
disableNotifications false Disable browser notifications
enableImages true Toggles loading of images
envVariables none An array of environment variables to pass to the process (example DISPLAY variable)
headers none An array of custom HTTP headers
headless true Enable or disable headless mode
ignoreCertificateErrors false Set Chrome to ignore SSL errors
keepAlive false Set to true to keep alive the Chrome instance when the script terminates
noSandbox false Enable no sandbox mode, useful to run in a docker container
noProxyServer false Don't use a proxy server, always make direct connections. Overrides other proxy settings.
proxyBypassList none Specifies a list of hosts for whom we bypass proxy settings and use direct connections
proxyServer none Proxy server to use. usage: 127.0.0.1:8080 (authorisation with credentials does not work)
sendSyncDefaultTimeout 5000 Default timeout (ms) for sending sync messages
startupTimeout 30 Maximum time in seconds to wait for Chrome to start
userAgent none User agent to use for the whole browser (see page API for alternative)
userDataDir none Chrome user data dir (default: a new empty dir is generated temporarily)
userCrashDumpsDir none The directory crashpad should store dumps in (crash reporter will be enabled automatically)
windowSize none Size of the window. usage: $width, $height - see also Page::setViewport
excludedSwitches none An array of Chrome flags that should be removed from the default set (example --enable-automation)

Persistent Browser

This example shows how to share a single instance of Chrome for multiple scripts.

The first time the script is started we use the browser factory in order to start Chrome, afterwards we save the uri to connect to this browser in the file system.

The next calls to the script will read the uri from that file in order to connect to the Chrome instance instead of creating a new one. If Chrome was closed or crashed, a new instance is started again.

…

Browser API

Create a new page (tab)

php
$page = $browser->createPage();

Get opened pages (tabs)

php
$pages = $browser->getPages();

Close the browser

php
$browser->close();

Set a script to evaluate before every page created by this browser will navigate

php
$browser->setPagePreScript('// Simulate navigator permissions;
const originalQuery = window.navigator.permissions.query;
window.navigator.permissions.query = (parameters) => (
    parameters.name === 'notifications' ?
        Promise.resolve({ state: Notification.permission }) :
        originalQuery(parameters)
);');

Page API

Navigate to an URL

php
// navigate
$navigation = $page->navigate('http://example.com');

// wait for the page to be loaded
$navigation->waitForNavigation();

When using $navigation->waitForNavigation() you will wait for 30sec until the page event "loaded" is triggered. You can change the timeout or the event to listen for:

php
use HeadlessChromium\Page;

// wait 10secs for the event "DOMContentLoaded" to be triggered
$navigation->waitForNavigation(Page::DOM_CONTENT_LOADED, 10000);

Available events (in the order they trigger):

  • Page::DOM_CONTENT_LOADED: dom has completely loaded
  • Page::FIRST_CONTENTFUL_PAINT: triggered when the first non-white content element is painted on the screen
  • Page::FIRST_IMAGE_PAINT: triggered when the first image is painted on the screen
  • Page::FIRST_MEANINGFUL_PAINT: triggered when the primary content of a page is visible to the user
  • Page::FIRST_PAINT: triggered when any pixel on the screen is painted, including the browser's default background color
  • Page::INIT: connection to DevTools protocol is initialized
  • Page::INTERACTIVE_TIME: scripts have finished loading and the main thread is no longer blocked by rendering or other tasks
  • Page::LOAD: (default) page and all resources are loaded
  • Page::NETWORK_IDLE: page has loaded, and no network activity has occurred for at least 500ms

When you want to wait for the page to navigate 2 main issues may occur. First, the page is too long to load and second, the page you were waiting to be loaded has been replaced. The good news is that you can handle those issues using a good old try-catch:

php
use HeadlessChromium\Exception\OperationTimedOut;
use HeadlessChromium\Exception\NavigationExpired;

try {
    $navigation->waitForNavigation()
} catch (OperationTimedOut $e) {
    // too long to load
} catch (NavigationExpired $e) {
    // An other page was loaded
}

The navigation accepts the options strict, referrer, referrerPolicy and transitionType:

php
// navigate with a custom referrer
$navigation = $page->navigate('http://example.com', ['referrer' => 'https://google.com/']);

Evaluate script on the page

Once the page has completed the navigation you can evaluate arbitrary script on this page:

php
// navigate
$navigation = $page->navigate('http://example.com');

// wait for the page to be loaded
$navigation->waitForNavigation();

// evaluate script in the browser
$evaluation = $page->evaluate('document.documentElement.innerHTML');

// wait for the value to return and get it
$value = $evaluation->getReturnValue();

Sometimes the script you evaluate will click a link or submit a form, in this case, the page will reload and you will want to wait for the new page to reload.

You can achieve this by using $page->evaluate('some js that will reload the page')->waitForPageReload().

Call a function

This is an alternative to evaluate that allows calling a given function with the given arguments in the page context:

php
$evaluation = $page->callFunction(
    "function(a, b) {\n    window.foo = a + b;\n}",
    [1, 2]
);

$value = $evaluation->getReturnValue();

Add a script tag

That's useful if you want to add jQuery (or anything else) to the page:

php
$page->addScriptTag([
    'content' => file_get_contents('path/to/jquery.js')
])->waitForResponse();

$page->evaluate('$(".my.element").html()');

You can also use an URL to feed the src attribute:

php
$page->addScriptTag([
    'url' => 'https://code.jquery.com/jquery-3.3.1.min.js'
])->waitForResponse();

$page->evaluate('$(".my.element").html()');

Set the page HTML

You can manually inject html to a page using the setHtml method.

php
// Basic
$page->setHtml('<p>text</p>');

// Specific timeout & event
$page->setHtml('<p>text</p>', 10000, Page::NETWORK_IDLE);

When a page's HTML is updated, we'll wait for the page to unload. You can specify how l

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

PHPhacktoberfest

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言