Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

To capture a rendered web page in memory with PHP, control a real browser engine, navigate to the page, and retain the screenshot result instead of saving it to disk. The chrome-php/chrome library documents this workflow with headless Chrome or Chromium. PHP output buffering alone cannot render a website into pixels, and imagegrabscreen() captures a Windows desktop rather than a portable server-side web page.

What “in memory” means for a PHP screenshot

A website screenshot is an image of a browser-rendered page: the browser loads HTML and resources, applies CSS, runs JavaScript, and paints pixels. PHP can orchestrate that work, but it needs a browser engine such as Chrome or Chromium. With chrome-php/chrome, the documented flow is to create a browser and page, navigate, wait for navigation, and call $page->screenshot(). The screenshot result is held in memory; saving it to a file is an optional later step.

There is an important implementation detail: the project README excerpt establishes an in-memory screenshot result and the file-saving API, but does not specify the exact accessor or encoding method for extracting raw bytes from that result. Do not assume a method name from another library or an older release. Check the API for the exact version installed before passing the bytes to an image processor, object store, or HTTP response.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install Chrome control and capture a page

Prerequisites

Install the PHP package with Composer:

composer require chrome-php/chrome

The project README states requirements of PHP 7.4–8.5 and Chrome or Chromium 65 or newer, and says it is tested on Linux and compatible with macOS and Windows. Treat those as the README’s stated requirements, not a guarantee for every deployment: confirm the current package release, PHP runtime, and browser binary available in your environment.

Minimal browser lifecycle

This example follows the documented API shape. It captures the screenshot result and keeps that object in memory. The comment marks the version-specific point where your application must use the installed release’s documented binary accessor; it deliberately does not guess a method name.

<?php

require __DIR__ . '/vendor/autoload.php';

use HeadlessChromiumBrowserFactory;

$browser = (new BrowserFactory())->createBrowser();

try {
    $page = $browser->createPage();
    $page->navigate('https://example.com')->waitForNavigation();

    // The screenshot result is in memory; no file is required.
    $screenshot = $page->screenshot();

    // Use the binary accessor documented for the installed chrome-php/chrome
    // version to obtain bytes from $screenshot before storing or returning them.
} finally {
    $browser->close();
}

The browser is closed in a finally block so normal completion and exceptions both reach cleanup. In a web application, convert the screenshot result to bytes using the installed version’s documented API before sending it to the client or handing it to another service. If you also need an archival copy, the library’s documented saveToFile() step can write the screenshot to disk; that is separate from acquiring the screenshot result.

Return bytes from a web endpoint

A typical endpoint’s final steps are to obtain the binary bytes with the installed API, set the appropriate content type, and emit those bytes. The exact conversion expression depends on the installed library version and must be taken from that version’s API documentation rather than guessed. For a PNG response, the HTTP response needs Content-Type: image/png; for JPEG or WebP, use the matching media type. Avoid printing debugging output before the image bytes, because any extra response content can corrupt the image.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose what part of the page to capture

Pick the capture scope based on what the screenshot needs to prove. The chrome-php/chrome README documents viewport capture and a full-page clipping approach; the Playwright PHP screenshot guide separately discusses viewport, full-page, and element screenshots.

Scope Use it for Implementation consideration
Viewport The visible browser area at a particular moment, such as a page-state snapshot. Use the normal screenshot call when the visible viewport is the intended evidence.
Full page A long page whose content extends below the initial viewport. The chrome-php/chrome README shows captureBeyondViewport => true together with $page->getFullPageClip(). Confirm the option shape against the installed version.
Element A particular component, such as a chart or product card, without surrounding page noise. Use an element-capture API supported by the browser library in use. Playwright PHP describes element screenshots as a way to reduce surrounding noise.

A screenshot records appearance at a moment; it is not necessarily the strongest way to verify behavior. In automated tests, pair a visual artifact with a semantic assertion or locator check when the question is whether an element exists, contains expected text, or can be interacted with.

Wait for the right page state

waitForNavigation() is part of the documented basic flow, but a navigation event does not prove that every delayed image, client-side render, or asynchronous widget has finished. Decide what “ready” means for the target page: a navigation milestone may be enough for static content, while a dynamic page may require waiting for a specific visible element or other application-specific signal. The source material does not establish a universal wait strategy or timing that works for every site.

  • For content rendered after navigation, wait for the relevant page element or state rather than choosing an arbitrary delay by default.
  • For lazy-loaded content in a full-page capture, ensure the relevant content has loaded before taking the image; a screenshot cannot include pixels that the browser has not rendered.
  • For pages with consent dialogs, authentication, or bot checks, determine whether the browser session can reach the intended page state. A screenshot of an interstitial is still a screenshot, but may not be the one you intended.

Do not confuse browser screenshots with PHP output buffering

PHP output-control functions buffer output that PHP would otherwise send or display, including printed values and content written to php://output. Buffering can help collect or manage response bytes once they exist; it does not execute a browser layout engine, apply website CSS, or run page JavaScript. Likewise, imagegrabscreen() is documented as capturing the whole screen, is available only on Windows, and returns a GD image object on success. It is a desktop capture function, not a general server-side web page renderer.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Common problems and fixes

  • The package installs, but Chrome will not start: verify that a compatible Chrome or Chromium binary is installed and usable by the PHP process. Check the library release’s current requirements and the deployment environment rather than assuming a developer workstation and server are configured alike.
  • The capture is blank or incomplete: check that navigation completed and that the page’s client-side content had time to render. For dynamic pages, wait for a page-specific readiness condition before capture.
  • A full-page image stops at the viewport: confirm that the full-page clipping option is enabled using the shape supported by the installed version. The README example uses captureBeyondViewport => true with getFullPageClip().
  • You cannot find the screenshot bytes: inspect the screenshot result class/API for the version Composer installed. The documented flow confirms the result is in memory, but an accessor name should not be inferred from Puppeteer, Playwright, or a different chrome-php release.
  • The returned image is corrupted: ensure that only image bytes are emitted after the response headers. PHP warnings, notices, debug text, or whitespace before a binary response can make an otherwise valid screenshot unreadable.
  • The browser remains running after an error: keep browser shutdown in a finally block, as in the example, and check application error paths that might bypass ordinary cleanup.
  • imagegrabscreen() fails on a server: it is a Windows desktop-screen function, not a replacement for headless browser automation on a general server deployment.

Performance, reliability, and deployment choices

Running Chrome or Chromium means your PHP application must be able to start and manage a browser process. The practical deployment check is whether the target environment has the required browser binary and supports the library’s browser lifecycle—not simply whether the PHP package can be installed. Keep browser cleanup explicit, and tune readiness to the page rather than adding a long fixed delay to every request. The available project documentation cited here does not supply a controlled performance benchmark, success rate, or universal resource estimate, so those values should be measured in the environment and against the pages you intend to capture.

When selecting a browser-control approach, compare the PHP-facing API for bytes, supported PHP and browser versions, viewport/full-page/element options, navigation and cleanup handling, and whether the deployment can run its browser. The available sources describe examples for chrome-php/chrome and Playwright PHP, but do not establish a controlled benchmark or complete version-by-version comparison.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If you would rather make a request than install and operate Chrome from PHP, ScreenshotNeo is a screenshot API and MCP server. One GET request returns a screenshot or PDF; see the API documentation for request options and response handling.

<?php

$url = 'https://stripe.com';
$apiKey = 'YOUR_API_KEY';

$ch = curl_init('https://api.screenshotneo.com/v1/shot?' . http_build_query([
    'access_key' => $apiKey,
    'url' => $url,
]));

curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 90,
]);

$image = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$error = curl_error($ch);
curl_close($ch);

if ($image === false || $status < 200 || $status >= 300) {
    throw new RuntimeException('Screenshot request failed: ' . ($error ?: 'HTTP ' . $status));
}

// $image contains the response body in memory; inspect response headers
// for the page verdict and billing status before treating it as an image.
  • Cookie/consent banners are accepted like a visitor, and 60+ known consent platforms, newsletter popups, and chat widgets are removed before capture; each step can be turned off.
  • Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing. Responses include X-Page-Verdict and X-Billed headers so you can distinguish outcomes.
  • An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
  • The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Every feature is on every plan.

Sign up free for 1,000 screenshots a month with no card.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Does a PHP output buffer capture a web page as an image?

No. It buffers PHP output; it does not render HTML in a browser engine.

Do I have to save the screenshot to a file first?

No. The chrome-php/chrome flow produces an in-memory screenshot result; saving is optional.

Can I use imagegrabscreen() on a Linux server to capture a website?

No. The PHP manual describes it as a whole-screen capture function available only on Windows.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.