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 errorsSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
To run wkhtmltopdf from PHP, install the wkhtmltopdf executable on the server, then start it as a separate process. PHP does not provide wkhtmltopdf as a built-in function or extension. Your PHP worker or job runner must be able to execute a compatible binary under its own operating-system account, with the libraries, fonts, permissions, and environment that binary needs.
For new integrations, PHP 7.4 or newer lets you pass proc_open() an argument array, avoiding shell parsing. The example below uses that approach, captures diagnostics, checks the exit code, and verifies the PDF before returning it. First make the command work from the same deployment environment; then connect it to PHP.
Install and verify the executable first
Choose a wkhtmltopdf package that matches the server’s operating system and architecture. The project publishes distribution-specific packages because Linux library, OpenSSL, libc, and font/runtime differences matter. There is no universal generic Linux build, and a package described as static does not necessarily include every dependency.
The project’s downloads page lists 0.12.6 as its stable series and gives June 11, 2020 as its release date. That is an old release, so assess whether its rendering behavior and security properties suit your application before adopting it. The exact installation command depends on your OS, distribution, architecture, and hosting setup; use the project’s current instructions for the target rather than copying a command meant for another system.
#1 Best Overall
Check the command outside PHP
Once installed, run the simplest useful conversion in a shell available in the deployment environment:
wkhtmltopdf input.html output.pdf
The CLI synopsis is wkhtmltopdf [GLOBAL OPTION]... [OBJECT]... <output file>. The page object can be an input URL or file; global and per-page options affect the output. The installed command’s -H help is the reliable place to check which switches that build supports. Options can depend on how it was built, including whether it uses patched Qt.
Try the command as the same operating-system user and in the same container, VM, or job environment that will run PHP. A successful conversion in an administrator’s interactive shell does not prove that a restricted web worker can find or launch the same executable.
Run wkhtmltopdf with PHP proc_open()
proc_open() starts a process and lets PHP manage its standard input, standard output, and standard error. Its descriptor 0 is stdin, 1 is stdout, and 2 is stderr. On PHP 7.4 or newer, pass the command as an array: PHP starts the program directly rather than asking a shell to parse a command string.
This example assumes that you have already created a trusted HTML file and an output directory writable by the PHP worker. Set $binary to the absolute path to the executable on your server. It uses local, server-generated file paths rather than request-provided command fragments.
Rank #2
<?php
$binary = '/usr/local/bin/wkhtmltopdf'; // Replace with the installed absolute path.
$input = '/srv/myapp/tmp/report.html'; // Trusted, server-generated input.
$output = '/srv/myapp/tmp/report.pdf'; // Server-generated destination.
if (!is_file($input) || !is_readable($input)) {
throw new RuntimeException('The HTML input file is missing or unreadable.');
}
$command = [$binary, $input, $output];
$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 wkhtmltopdf.');
}
// This example provides no stdin input and does not consume PDF bytes from stdout.
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) {
throw new RuntimeException(
'wkhtmltopdf failed with exit code ' . $exitCode . ': ' . trim($stderr)
);
}
if (!is_file($output) || filesize($output) === 0) {
throw new RuntimeException('wkhtmltopdf did not create a nonempty PDF.');
}
// The file is ready for the application to serve or move into durable storage.
The example reads stdout and stderr after the process finishes, which is suitable for ordinary conversions that write the PDF to a file. If a process can produce enough output to fill a pipe, reading one pipe to completion while leaving another unread can block the child process. For workloads that may generate substantial output, drain the pipes concurrently or redirect unused output to a file or an appropriate sink, then still collect the exit status and validate the output.
Control the input and output paths
Do not let a request supply an executable path, arbitrary command-line flags, or an unrestricted output path. Validate any user-selectable options against an allowlist, and generate filenames and directories on the server. This both reduces command-injection risk and makes it easier to control where a process can read and write.
When the input is a URL, the renderer will fetch it from the server environment. Treat URL selection as a security-sensitive feature: validate allowed schemes and hosts, and account for access to internal network resources. Shell-safe argument passing prevents shell interpretation; it does not by itself make arbitrary remote content safe to fetch or render.
Choose the invocation style deliberately
Argument array with proc_open()
For PHP 7.4+, the array form is the clearest general-purpose choice when you need separate stderr, an exit code, or process control. Keep the executable and each option or value in its own array element. Do not build one command string and pass it as an array element.
String-based shell APIs
If you use a shell-string API such as exec(), escape each dynamic argument separately with escapeshellarg(); it is not a function for safely escaping an entire command. PHP documents platform-specific escaping behavior on Windows, including loss of some characters, and warns that argument escaping alone does not prevent every command-injection pattern. Validate values with allowlists, keep paths server-generated, and never accept arbitrary flags or executable paths from a request.
Escaping only addresses how the command is parsed. It does not sanitize HTML or JavaScript for the renderer, constrain a URL’s network access, or protect files the process can access.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Optional PHP wrapper
A Composer wrapper such as mikehaertl/phpwkhtmltopdf can provide a convenience API, error retrieval, and explicit binary-path configuration. It remains a layer over the same external executable: installing the PHP package does not install wkhtmltopdf itself. Check the wrapper’s compatibility against the wkhtmltopdf package and your PHP/runtime version. Its documentation also discusses Windows concerns and headless-server considerations for some dynamically linked builds, including Xvfb workarounds; verify those against the package you selected rather than applying older platform examples blindly.
Set PDF options supported by your build
Options can control paper size, orientation, margins, headers and footers, JavaScript settings, and page-rendering behavior. The precise switches and semantics depend on the installed build. Check wkhtmltopdf -H there, and test the output using representative documents before relying on a setting in production.
Keep option names and values separate in the command array. For example, where the installed build documents a paper-size switch, add its switch and value as separate elements rather than concatenating request data into a command string. A flag accepted by one package may not be available in another, so an “unknown option” should be diagnosed against that binary’s help output.
Why it works in a terminal but not in PHP
A web server or queue worker commonly runs with a different user, PATH, working directory, environment, and restrictions from an interactive login shell. Compare the process context rather than assuming both invocations are equivalent.
Recommended Free Tools
Rank #4
- Executable not found: configure the absolute binary path. Check that it exists inside the actual runtime environment.
- Permission denied: verify execute permission on the binary and traverse/read/write permissions on the relevant directories for the PHP worker account.
- Missing library or loader error: install a package built for the deployment OS and architecture, and satisfy its runtime dependencies. A binary copied from a different distribution may not be compatible.
- Generic PDF failure: capture stderr and the exit code. Check for inaccessible input, an invalid option, missing fonts, or an output path the worker cannot write.
- Different appearance from local output: compare package build, fonts, environment, network access, and supported options. Do not assume an old QtWebKit-era renderer behaves like a current browser.
- PHP cannot launch processes: inspect the hosting environment’s PHP restrictions and process policy. A wrapper cannot overcome a runtime that is not permitted to execute the binary.
These are troubleshooting checks, not a diagnosis of any particular deployment. Record the selected binary path, package/build, process exit status, and stderr in operational logs; avoid logging secrets embedded in URLs or headers.
Package for containers, servers, and Lambda
Install or bundle the executable for the same OS and architecture used at runtime. In a container, make the binary and required libraries part of the image and verify them in the final image, not only in a build stage. For a managed host, confirm that the web worker can access the install location and that the host permits child processes.
The wkhtmltopdf project documents an Amazon Linux 2 archive and an example of bundling it into a Lambda function or layer; its example sets FONTCONFIG_PATH=/opt/fonts. Treat that as guidance for the documented Amazon Linux 2 target, not a universal recipe for every Lambda runtime generation. Confirm that the package, runtime libraries, fonts, and environment variables match the runtime you actually deploy.
Security and maintenance limits
The wkhtmltopdf project explicitly warns: “Do not use wkhtmltopdf with any untrusted HTML – be sure to sanitize any user-supplied HTML/JS, otherwise it can lead to complete takeover of the server it is running on!” This is a serious project warning. Sanitizing is not a substitute for isolating a renderer that processes attacker-controlled content. If the application must render such content, reconsider the renderer and use strong isolation, with network and filesystem access restricted to what the job needs.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →That warning is separate from shell injection: an argument array can keep a hostile string from being interpreted by a shell, but it does not neutralize hostile HTML or JavaScript once the renderer processes it. Likewise, restricting the renderer does not remove the need to validate command arguments.
The project’s status history says QtWebKit was deprecated in 2015 and removed from Qt in 2016. The listed stable wkhtmltopdf series, 0.12.6, dates to June 11, 2020. These project-published facts are not an independent security audit, but they are reasons not to assume current CSS and JavaScript compatibility or ongoing maintenance. Test the documents your application actually needs, review the project’s status information, and compare alternatives if modern browser rendering or a different security posture is required.
Or skip the browser setup
If your requirement is to capture a live website as an image or PDF rather than convert application-generated HTML with a locally managed renderer, ScreenshotNeo offers a screenshot API and MCP server. A single GET request can return a PNG, JPEG, WebP, or PDF. For example, from a shell:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for API parameters. Cookie banners, popups, and chat widgets are removed before capture; bot checks, blank pages, and failed loads are not billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. This is an alternative for website capture, not a drop-in replacement for rendering arbitrary local HTML through wkhtmltopdf.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Sign up free for 1,000 screenshots a month, with no card required.
Frequently Asked Questions
Does installing a PHP wrapper install wkhtmltopdf?
No. A wrapper still requires the external wkhtmltopdf executable and its runtime dependencies to be installed and accessible.
Can wkhtmltopdf convert a PHP template directly?
Render the template to HTML first, then give wkhtmltopdf an accessible HTML file or URL. PHP itself is not an input format understood by the command.
Quick 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.

