October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk8 min

How to Use wkhtmltoimage in PHP to Screenshot a Web Page

A practical PHP workflow for invoking wkhtmltoimage safely, handling process results, and checking legacy renderer behavior against your installed version.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

PHP can capture a web page with wkhtmltoimage by starting the executable as a child process, passing it an input URL or HTML file and an output image path, then checking the exit status and resulting file. Use a fixed executable path, keep dynamic values out of options, and escape each dynamic shell argument—or use array-form proc_open() on PHP 7.4 or later. Because the upstream project is archived and the renderer uses Qt WebKit, check the behavior of the exact binary you deploy rather than assuming modern browser support.

What the PHP-to-screenshot workflow does

wkhtmltoimage is a command-line renderer in the wkhtmltopdf project. It renders HTML to an image using Qt WebKit, and the project describes it as headless, meaning it does not require a display service. PHP does not render the page itself in this setup: it starts the external program, waits for it to finish, and handles its output. The project overview describes the tools and their headless operation.

As an Amazon Associate I earn from qualifying purchases.

The basic command shape is:

wkhtmltoimage [options] INPUT OUTPUT

The input can be a page URL or a local HTML file; the output is a path where the image should be written. Exact options and behavior depend on the installed build. The project’s upstream GitHub repository is archived and read-only, so treat this as legacy software and verify its capabilities in your environment. The repository includes the archive notice and project documentation.

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

Install and verify the executable first

Install a build appropriate for the target operating system, then record the executable path and confirm it runs under the same account and environment as PHP. The example below uses /usr/local/bin/wkhtmltoimage as a fixed path; replace it with the actual path on your server. Do not rely on a developer workstation’s PATH or assume a binary available interactively will also be available to a web-server process.

  1. Check the installed program’s help output and version-specific documentation for accepted syntax and options.

  2. Run a simple conversion as the operating-system user that will run PHP.

  3. Confirm that the process can reach the intended URL or read the local file and write to the chosen output directory.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  4. Test representative pages in the deployment environment, including pages with the scripts and styles your application depends on.

The project documents its command-line role and image conversion API, but the available documentation here does not establish a universal, exhaustive list of current CLI flags. In particular, do not assume viewport, full-page height, JavaScript timing, load handling, or JPEG-quality switches without checking the deployed binary. Check the project repository and documentation against the version you have installed.

Run it safely from PHP

PHP 7.4 and later: array-form proc_open()

Array-form commands for proc_open() are available from PHP 7.4.0. PHP documents that this form launches the process directly and handles argument escaping. This example passes a URL as one argument, captures standard output and error, checks the exit code, and requires a non-empty output file before reporting success.

<?php
$executable = '/usr/local/bin/wkhtmltoimage'; // Set to a trusted, fixed path.
$url = 'https://example.com';                 // Validate if this comes from a user.
$outputFile = '/var/tmp/page-shot.jpg';       // Use a controlled writable directory.

$command = [$executable, $url, $outputFile];
$descriptors = [
    0 => ['pipe', 'r'],
    1 => ['pipe', 'w'],
    2 => ['pipe', 'w'],
];

$process = proc_open($command, $descriptors, $pipes);
if (!is_resource($process)) {
    throw new RuntimeException('Could not start wkhtmltoimage');
}

fclose($pipes[0]);
$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
$exitCode = proc_close($process);

if ($exitCode !== 0 || !is_file($outputFile) || filesize($outputFile) === 0) {
    throw new RuntimeException(
        "Screenshot failed (exit code {$exitCode}). stderr: {$stderr}; stdout: {$stdout}"
    );
}

// The image is available at $outputFile.
?>

This is a process-launch pattern, not a guarantee that every installed build accepts every input or produces a particular image size. Adjust the output extension and any options only after checking the binary’s help and matching-version documentation. PHP’s proc_open() documentation describes array-form commands and process pipes.

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

Shell-based fallback

If you use a shell-based execution function instead, escape each dynamic argument individually with escapeshellarg(); do not escape an entire command string as one argument. Keep the executable and option names fixed by the application. A basic command construction looks like this:

<?php
$executable = '/usr/local/bin/wkhtmltoimage';
$url = 'https://example.com';
$outputFile = '/var/tmp/page-shot.jpg';

$command = escapeshellarg($executable)
    . ' ' . escapeshellarg($url)
    . ' ' . escapeshellarg($outputFile)
    . ' 2>&1';

$output = [];
$exitCode = 0;
exec($command, $output, $exitCode);

if ($exitCode !== 0 || !is_file($outputFile) || filesize($outputFile) === 0) {
    throw new RuntimeException(
        'Screenshot failed: ' . implode("n", $output)
    );
}
?>

PHP documents both shell execution and escapeshellarg(); review the platform-specific behavior for your deployment. PHP: escapeshellarg() explains argument escaping, and PHP: exec() documents command execution. Escaping prevents shell metacharacters in a value from being interpreted as shell syntax, but it does not decide whether a URL, output path, or executable is appropriate to use.

Validate inputs and contain the subprocess

Shell escaping alone does not make arbitrary input safe. Keep the executable path trusted, avoid letting request data supply command-line switches, and constrain the output location. If URLs come from users, validate allowed schemes and destinations according to the application’s requirements; a renderer that fetches remote pages can otherwise be asked to access locations your application did not intend. The exact URL-fetching behavior depends on the program and its build.

PHP’s documentation warns about passing user-controlled values to command execution functions. PHP’s security documentation provides broader guidance; apply it alongside the relevant function documentation for your PHP version and operating system.

Choose output and rendering settings by checking your build

The project’s image API documentation shows image conversion and format selection, including an example configured for JPEG. It also describes raster image or SVG output through that API. Those API details should not be treated as proof that a similarly named or configured CLI option exists in every binary. Use the documentation matching the installed project version and confirm the command-line syntax with the executable itself.

Before relying on an output format or page-layout setting in production, check:

The upstream repository’s archived status establishes that it is read-only; it does not, by itself, establish a specific security vulnerability or prove that a particular deployment is incompatible. Evaluate the actual binary, operating system, PHP runtime, and pages you need to capture rather than assuming recent browser-engine behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot failed or unexpected captures

The process cannot start

Check that the configured executable path exists, is executable by the PHP process user, and matches the server’s operating system and architecture. Verify that PHP’s process-execution functions are available in the deployed configuration and inspect the process-launch error and server logs.

The process exits with an error or creates no image

Record the exit code and stderr, then run the same fixed input and output command from the same account in a controlled environment. Confirm that the input is reachable or readable and that the output directory is writable. Re-check the syntax against the installed binary’s help rather than copying an option from another release.

The image exists but the page looks wrong

Confirm that the page is compatible with the deployed Qt WebKit renderer and that any necessary content is available to it. Compare a simple static page with the problematic page to narrow the cause. Do not assume that a modern JavaScript feature, layout behavior, or timing option is supported; the project is archived and exact behavior is version-dependent.

A URL or path breaks the command

For shell commands, escape each dynamic argument separately. With PHP 7.4 or later, consider array-form proc_open() to avoid shell parsing for process arguments. Also validate the value’s meaning: escaping does not block unwanted URL destinations, arbitrary executable choices, or misuse of permitted options.

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

Performance, reliability, and cost considerations

Each PHP capture starts an external process, so factor process startup and page rendering into the request’s latency and resource budget. A slow or unreachable page can occupy a PHP worker; set operational limits appropriate to your host and application, and avoid allowing a user to trigger unlimited concurrent captures. The precise timeout, memory use, and throughput depend on the page, binary, and server, so measure them in the target environment rather than relying on a general figure.

Because the upstream repository is archived, include the binary and its runtime dependencies in your maintenance decisions: document the version deployed, test upgrades or operating-system changes, and have a fallback if the renderer no longer suits a required page. This status is a lifecycle consideration, not evidence of a particular defect.

Or skip the browser setup

If you need an API rather than managing a local renderer, ScreenshotNeo returns a screenshot or PDF from one GET request. Cookie and consent banners are accepted before capture, and more than 60 known consent platforms, newsletter popups, and chat widgets can be removed; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, with response headers identifying the page verdict and billing status. Its MCP server provides screenshot tools for AI agents, and the free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

See the ScreenshotNeo API documentation for the request details. Sign up for 1,000 free 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 wkhtmltoimage require a display server?

The project describes wkhtmltoimage as headless, so it does not require a display service.

Which PHP versions support array-form proc_open commands?

PHP documents array-form commands for proc_open() from PHP 7.4.0.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.