gen_Eric
gen_Eric

Reputation: 227310

proc_open gives different output in Apache2 vs CLI

I am using wkhtmltopdf to convert HTML documents to PDF files on our website. I am using the following code in my PHP class:

<?php

$pdfConv = proc_open('wkhtmltopdf -q -s letter --no-background --print-media-type --title Test - -', [
    0 => array('pipe', 'r'),
    1 => array('pipe', 'w'),
    2 => array('pipe', 'w')
], $pipes, '/tmp', NULL, [
    'bypass_shell' => true
]);

if(is_resource($pdfConv)){
    // Send STDIN
    fwrite($pipes[0], $htmlData);
    fclose($pipes[0]);

    // Receive STDOUT
    $pdfFile = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    // Set headers and send file to browser to be downloaded

    // Close process
    proc_close($pdfConv);
}

NOTE: For testing purposes I did $htmlData = file_get_contents('http://google.com');.

When I browsed to the page in my web browser and clicked "download PDF", I got the following output:

Messed up PDF File

(Download original PDF file)

Trying to figure what was wrong, I took to the command-line and ran:

wkhtmltopdf -q -s letter --no-background --print-media-type --title Test http://google.com /tmp/google.pdf

This worked perfectly, so I wondered if something was wrong with PHP. I typed php -a and pasted the above code into the command-line and ran it, and it worked perfectly.

Here is what the PDF should look like:

Good PDF File

(Download original PDF file)

Why would running the same code from Apache (via my web browser) give a different PDF than running on the command line directly? Where did these weird characters come from? How can I even debug this?

Upvotes: 4

Views: 261

Answers (1)

gen_Eric
gen_Eric

Reputation: 227310

Thanks to @Havenard, I figured out the problem. I ran export from my command line and via proc_open in PHP and compared the output.

On my command line, I saw LANG=en_US.UTF8 but from PHP it said LANG="C".

The solution was to set the LANG value in the environment in proc_open

$pdfConv = proc_open('wkhtmltopdf -q -s letter --no-background --print-media-type --title Test - -', [
    0 => array('pipe', 'r'),
    1 => array('pipe', 'w'),
    2 => array('pipe', 'w')
], $pipes, '/tmp', [
    'LANG' => 'en_US.UTF8'
], [
    'bypass_shell' => true
]);

Upvotes: 1

Related Questions