To automate a browser with PHP, install the community php-webdriver/webdriver client, install Chrome or Chromium, start a compatible ChromeDriver endpoint, then connect to it with RemoteWebDriver. Your PHP code sends WebDriver commands through the driver to the browser. This guide walks through a small local test, explains selectors and waits, and shows when to move from a local driver to Selenium Server or Grid.
How Selenium, PHP and the browser fit together
Selenium WebDriver is an API and protocol for controlling a browser. In this setup, PHP is the client language, php-webdriver/webdriver is its community client library, ChromeDriver is the browser-specific driver, and Chrome or Chromium is the browser doing the actual work. The client sends WebDriver commands to the driver, which controls the browser. Selenium’s setup guidance describes the essentials as a language binding, a browser, and the browser’s driver: Selenium WebDriver: Getting Started and WebDriver documentation.
The PHP library is not an official Selenium language binding; it is a community-maintained PHP client. For a beginner’s local run, you do not need Selenium Server or Grid.
Install the PHP WebDriver client
Install Composer if it is not already available, then run this from your project directory:
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
composer require php-webdriver/webdriver
The package is php-webdriver/webdriver. Older examples may use the former name facebook/webdriver; use the current package name. Composer generates vendor/autoload.php, which your PHP script will load. The project README documents installation and usage: php-webdriver project README.
A Packagist snapshot dated December 28, 2025 lists version 1.16.0, PHP ^7.3 || ^8.0, and the PHP extensions curl, json, and zip as requirements. Package metadata can change, so check the current record when setting up a new project: Packagist package record.
Install and start ChromeDriver
The Composer package does not install Chrome, Chromium, or ChromeDriver. Install Chrome or Chromium and a ChromeDriver version compatible with that browser. ChromeDriver is a separate executable; use the current browser-vendor instructions rather than an old copied binary version: ChromeDriver: Get started.
Rank #2
For a simple local setup, start ChromeDriver on port 4444. The PHP client can then connect to http://localhost:4444. The exact command and installation method depend on your operating system and how you installed ChromeDriver; follow its current setup instructions. Keep the process running while your PHP script runs.
Run your first PHP browser automation
Save this as first-test.php in the Composer project directory. It opens Example Domain, checks that the page title matches the expected value, and closes the browser session even if an error occurs.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use FacebookWebDriverRemoteDesiredCapabilities;
use FacebookWebDriverRemoteRemoteWebDriver;
$driver = RemoteWebDriver::create(
'http://localhost:4444',
DesiredCapabilities::chrome()
);
try {
$driver->get('https://example.com');
$expectedTitle = 'Example Domain';
$actualTitle = $driver->getTitle();
if ($actualTitle !== $expectedTitle) {
throw new RuntimeException(
"Expected title '{$expectedTitle}', got '{$actualTitle}'"
);
}
echo "Page title verified: {$actualTitle}n";
} finally {
$driver->quit();
}
- Start ChromeDriver and leave it running at the local endpoint.
- In another terminal, run
php first-test.phpfrom the project directory. - If the session starts and the page loads, the script prints
Page title verified: Example Domain. If the title differs or another exception occurs,finallystill attempts to close the session.
The client’s documented pattern is to create a remote WebDriver session with a server URL and browser capabilities, navigate with get(), interact with page elements, and call quit() when finished. See the project README and examples for the library’s API details.
Find elements, interact and verify outcomes
Locators tell WebDriver which DOM element to work with. Prefer a stable element ID when the page provides one; CSS selectors are another practical choice. For example, once a page with a known search field is open, you can locate it with WebDriverBy::id('search') or WebDriverBy::cssSelector('input[name="q"]'), then call methods such as sendKeys() or click(). Those locator values are examples only: use selectors that actually match the page under test.
For an interaction test, make the expected result explicit. For example, after clicking a submit button, check for a confirmation element or expected URL rather than assuming that a click succeeded. If you use PHPUnit or another test runner, put the assertion in that runner; the browser client itself is not a test framework.
Free tools Windows power users keep installed
One-click scans. No signup required.
Wait for dynamic pages instead of guessing
Modern pages may render content after the initial navigation completes. A fixed sleep can be too short on a slow run and waste time on a fast one. Use a condition-based wait for the element or state your test needs before interacting or asserting. Selenium treats waiting strategies as a core WebDriver concept; consult its WebDriver documentation and the PHP client documentation for the API supported by your installed version.
Rank #4
Local driver or Selenium Server/Grid?
A direct browser-driver connection is the simplest route for learning and local development. Selenium Server and Grid introduce remote execution and coordination when you need to run tests across browsers or machines. The php-webdriver README discusses both direct drivers and server-based setups: php-webdriver setup documentation.
| Approach | Where the browser runs | Good fit | Setup trade-off |
|---|---|---|---|
| Direct local ChromeDriver | On the development machine | Learning, a small local script, or debugging one browser | Requires a local browser and compatible driver; least moving parts |
| Selenium Server or Grid | On a server or Grid node, locally or remotely | Multiple browser types, CI orchestration, remote browsers, or distributed runs | Requires server/Grid configuration in addition to the PHP client and browser setup |
Common setup failures and fixes
- Connection refused at
localhost:4444: ChromeDriver is not running at that address or port. Start it, check its listening port, and make the URL passed toRemoteWebDriver::create()match. - Session creation fails: Check that Chrome or Chromium is installed, ChromeDriver is executable, and the driver supports the installed browser version. Consult the current ChromeDriver setup guidance rather than pinning an outdated driver from an old tutorial.
- Composer cannot install the package: Confirm Composer is available, the package name is
php-webdriver/webdriver, and your PHP version and required extensions meet the current package requirements. - Class not found: Make sure Composer ran successfully in this project and the script includes the correct
vendor/autoload.phppath. - Element not found: The locator may not match the page, or the element may not have rendered yet. Inspect the actual page and use a condition-based wait for dynamic content.
- Browser remains open after a failure: Put test work inside a
tryblock and callquit()infinally, as in the example. - Confusing ChromeDriver with Selenium Server: For a local beginner example, the PHP client can talk directly to the browser driver. Server/Grid is a separate route for remote, multi-browser, CI, or distributed execution.
Or skip the browser setup
If your goal is to capture a page rather than automate browser interactions, ScreenshotNeo provides a screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF; its options include full-page capture, element capture by CSS selector, custom waits, and other browser settings. See the API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.
Frequently Asked Questions
Is php-webdriver/webdriver an official Selenium project binding?
No. It is a community-maintained PHP client for WebDriver.
Can I use Firefox instead of Chrome?
Yes, but you need Firefox and its compatible browser driver, plus capabilities and setup appropriate to that browser.
Does this example test a site without a browser installed?
No. It controls an actual browser, locally or through a remote WebDriver endpoint.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsQuick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




