Forum How do I...?

calling prince with php not working

aimfeld
Hi there,

We are considering buying a prince server licence, however, basic local testing has failed so far. I've installed prince on Windows Vista and tried creating a very simple pdf using lots of variations of the following php code:

$prince = new Prince('C:\\Program Files\\Prince\\Engine\\bin\\prince.exe');
$msgs = array();
$result = $prince->convert_string_to_file('<h1>Test</h1>', 'C:\\Users\\aimfeld\\Temp\\test.pdf', $msgs);

Using a debugger, I've found $result to turn out false and $msgs to remain empty. When I call prince from the command line and pass a html file with the content "<h1>Test</h1>", a pdf file is generated just fine.

Any ideas what could be wrong here?

I appreciate any help.
Cheers, Adrian
mikeday
It could be that the PHP code does not have permissions to execute Prince, or that Prince is running but does not have permissions to write to the specified output file. Often PHP code will be hosted by a web server running as a separate user, eg. "Network Services", which may not have access to some paths unless explicitly granted.

Can you try calling $prince->setLog('c:\\temp\\prince.log') before the conversion and specify a path that is guaranteed to be writable from your PHP code? If the output log file doesn't appear, there is probably a permissions problem.

Another thing you can try is converting an input file instead of an input string.
aimfeld
I tried setting full permission for all existing users both to the whole prince install folder and to the folder for the pdf and log file, but still no luck. specified a log file to be created as follows:

$prince->setLog('C:\\xampp\\htdocs\\wematch\\prince\\log.txt');

but no log file is created.

My current code looks like this:

$prince = new Prince('C:\\Program Files\\Prince\\Engine\\bin\\prince.exe');
$prince->setLog('C:\\xampp\\htdocs\\wematch\\prince\\log.txt');
$msgs = array();
$result = $prince->convert_string_to_file('<h1>Test</h1>', 'C:\\xampp\\htdocs\\wematch\\prince\\test.pdf', $msgs);

I have no idea what's wrong here, I'm not even sure if prince is actually executed or not.
mikeday
How about calling convert_string_to_passthru() instead of convert_string_to_file() and omit the call to setLog(), then Prince will not need to create any files and we can see if it is actually running at all. If you still get no output doing this, then perhaps PHP does not have permissions to execute Prince. Which web server are you running PHP with?
aimfeld
Hi mikeday, thanks for your patience. I tried the following:

$prince = new Prince('C:\\Program Files\\Prince\\Engine\\bin\\prince.exe');
$result = $prince->convert_string_to_passthru('<h1>Test</h1>');

which gives me $result == false and no output, so it seems that prince is actually not running at all. I'm testing locally on Xampp 1.7.1, Apache 2.2, PHP 5.2.9, installed on Windows Vista, and my website code is based on Zend Framework. I'm new to web programming and I might be missing something basic. Or maybe I should just blame Vista :wink: .
mikeday
Try this, change line 359 of prince.php from this:
$process = proc_open(escapeshellcmd($pathAndArgs), $descriptorspec, $pipes);

to this:
$process = proc_open(escapeshellcmd($pathAndArgs), $descriptorspec, $pipes, NULL, NULL,
    array('bypass_shell' => TRUE));

This should in theory make PHP call Prince directly, instead of going through cmd.exe, which is often blocked to the "Network Service" user for security reasons. It does require PHP 5.2.1 though.
hamishwillee
Hi Mike

I have the same problem on vista using XAmpp. I tried the above change and it made no effect. I then turned of User Account Control altogether, again with no effect. As UAC is off, I *think* the problem can't be network access.

Have you any other thoughts on possible solutions?

Regards
Hamish
mikeday
You also need to disable PHP safe_mode, as it can block access to proc_open if it is enabled.
hamishwillee
mikeday wrote:
You also need to disable PHP safe_mode, as it can block access to proc_open if it is enabled.


safemode is set off by default in the xampp php.ini. I also added a .htaccess with
php_flag safe_mode off
for good measure.

I don't think this is the problem.
mikeday
Prince works fine from the command-line, you are specifying the correct path to the Prince executable (usually c:\Program Files\Prince\Engine\bin\prince.exe), have tried calling $prince->setLog(...) specifying a writable temporary directory for the log file, and tried calling Prince with passthru and without a log file, and none of these work?
hamishwillee
mikeday wrote:
Prince works fine from the command-line, you are specifying the correct path to the Prince executable (usually c:\Program Files\Prince\Engine\bin\prince.exe), have tried calling $prince->setLog(...) specifying a writable temporary directory for the log file, and tried calling Prince with passthru and without a log file, and none of these work?


1. Prince works fine from the command-line
YES
2. , you are specifying the correct path to the Prince executable (usually c:\Program Files\Prince\Engine\bin\prince.exe),
YES
Code I'm using for testing is:
$prince = new Prince("C:\Program Files\Prince\Engine\bin\Prince.exe");
$result = $prince->convert_string_to_passthru('<h1>Test</h1>'); 
if ($result==true) {
wfDebugLog('myextension', 'True: ' . print_r($result, true) );
}
else
{
wfDebugLog('myextension', 'false: ' . print_r($result, true) );
}

The false is what gets returned, indicating prince is not being launched.
Note I've tried other variants
$prince = new Prince('C:\Program Files\Prince\Engine\bin\Prince.exe');
$prince = new Prince('C:\Program Files\Prince\Engine\bin\prince.exe');
$prince = new Prince('C:\\Program Files\\Prince\\Engine\\bin\\prince.exe');

3. Doesn't seem much point in doing:
have tried calling $prince->setLog(...) specifying a writable temporary directory for the log file,
But yes, and no file has yet been created. Currently testing without logging.

4. and tried calling Prince with passthru and without a log file, and none of these work?
Correct.
mikeday
Are any errors or warnings occurring in the Apache or PHP log files?
hamishwillee
mikeday wrote:
Are any errors or warnings occurring in the Apache or PHP log files?

Nothing in the Apache logs.
I don't know where the PHP logs go to - can you point me?
mikeday
It should either go to the Apache error log or to the Windows event log, depending upon php.ini.
hamishwillee
mikeday wrote:
It should either go to the Apache error log or to the Windows event log, depending upon php.ini.

The php.ini has: display_errors = On
So would have expected them to display on-screen. No errors reported

Changed setting to log to apache.
; Log errors to specified file.
error_log = "D:\xampp\apache\logs\phperror.log"

I don't get any errors, though I do get an access log when I try to print.
127.0.0.1 - - [17/Nov/2009:15:17:27 +1100] "GET /mediawiki/index.php?title=Special:Pdfprint&page=Using_Qt_and_Symbian_C%2B%2B_Together HTTP/1.1" 200 44338
mikeday
Okay, can you look inside prince.php, go to line 363, and see what is going on? :)

For example, how about printing the $result value, to see what is being returned from Prince?
hamishwillee
mikeday wrote:
Okay, can you look inside prince.php, go to line 363, and see what is going on? :)

For example, how about printing the $result value, to see what is being returned from Prince?


Hi Mike
I AM printing the $result value. In the code fragment above you see I print on true or false. I get log:
2009-11-17 03:31:09 admin: false:

So all I'm getting back from PHP is that the file isn't being started. I can't see any other logs back explaining what/why it isn't started. Sorry if I'm being dim.
Is there another way to launch a process in the background?

Regards
H
hamishwillee
Sorry, just re-read that.
In answer, not really. I don't have the ability in the given timeframe to debug prince.php.
hamishwillee
If you guys are in Carlton perhaps I should wander down with my laptop :)
mikeday
The problem turned out to be with escapeshellcmd() on Windows, which appears to be breaking the path name by removing all the slashes. We will investigate this issue and see what is the most reliable way of handling this.
hamishwillee
mikeday wrote:
The problem turned out to be with escapeshellcmd() on Windows, which appears to be breaking the path name by removing all the slashes. We will investigate this issue and see what is the most reliable way of handling this.

Thanks Mike, your help much appreciated! When you have an "approved" version that is ready to test I am happy to act in that capacity
mikeday
We've updated the PHP wrapper to remove all the calls to escapeshellcmd(), which was replacing slashes and quotes with spaces on Windows, causing many problems. Hopefully this should fix most issues. There may still be problems in some circumstances if the Prince executable path contains spaces, which the bypass_shell workaround would hopefully fix.
aimfeld
With the updated wrapper, it now works for me, too :). However, I had to reinstall prince under c:\prince instead of c:\program files\prince. The blank in the path seems to screw things up.

Thanks for all the help!
Cheers, Adrian
jim_albright
Use quotes around the whole path to solve space problem.

Jim Albright
Wycliffe Bible Translators