Search code examples
phppdfghostscriptshell-exec

Using ghostscript in a php script


Using Laravel for a web app where I am using https://github.com/clegginabox/pdf-merger to merge pdf files and ran into the following error when trying to merge two pdfs together where one was over version 1.4:

Exception in pdf_parser.php line 133:

This document (C:\path-to-doc\file.pdf) probably uses a compression technique 
which is not supported by the free parser shipped with FPDI. 
(See https://www.setasign.com/fpdi-pdf-parser for more details)

in pdf_parser.php line 133

I followed the suggestion in the following answer to use ghostscript to convert any pdf over 1.4 to 1.4 so the merge will work.

FPDF error: This document (testcopy.pdf) probably uses a compression technique which is not supported by the free parser shipped with FPDI

I've installed ghostscript successfully and added it to my path. For testing I have a sample pdf file which is version 1.5 called test.pdf and I run the following command from the windows terminal:

gswin64 -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dQUIET -dBATCH -sOutputFile=new-file.pdf test-file.pdf

and I get my new-file.pdf just fine as version 1.4.

Now I have the following php script which when ran from the web browser just loads continuously. If I let it run a bit sometimes a new file has been created but it's like 3kb in size and blank and also the original pdf file comes blank sometimes?!

<?php

shell_exec( "gswin64 -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dQUIET -dBATCH -sOutputFile=new-file.pdf test-file.pdf");

echo 'done';

Any ideas what I'm doing wrong?


Solution

  • Was just about to post this question and figured it out, so went ahead and answered for the benefit of others.

    I read this answer on super user https://superuser.com/questions/200188/reading-a-pdf-file-for-testing-in-ghostscript#answer-200784

    This part being the light bulb

    If you use Ghostscript on Windows, you'll have two executables:

    1. gswin32c.exe
    2. gswin32.exe

    The first one is to be run from inside a 'DOS box' (i.e. cmd.exe window) -- either interactively or not. It prints all stderr/stdout messages into the cmd.exe window and also expects any input commands to be typed in there.

    The second one opens a separate Window for "interactivity': prints stderr/stdout to separate window, and expects commands there.

    So I changed my php script to use gswin64c and to output the text from the command's response:

    $output = shell_exec( "gswin64c -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dQUIET -dBATCH -sOutputFile=new-file.pdf test.pdf");
    
    echo "<pre>$output</pre>";
    

    This showed that I was referencing the wrong file name i.e. test-file.pdf instead of test.pdf.

    Error: /undefinedfilename in (test-file.pdf)
    Operand stack:
    
    Execution stack:
       %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   --nostringval--   false   1   %stopped_push
    Dictionary stack:
       --dict:1192/1684(ro)(G)--   --dict:0/20(G)--   --dict:78/200(L)--
    Current allocation mode is local
    Last OS error: No such file or directory
    

    After updating the file name it all worked just fine!

    Update

    In response to Marsha's comment in the question...

    What do you mean by "added it to my path"? Thanks in advance.

    When you add an executable or the location to a group of executables to your PATH environment variable it allows executable(s) to be invoked from the command line from any location. For example you could invoke ghostscript from C:\youruser\Desktop after adding it to your path, instead of being in the folder where your ghostscript files reside C:\gs\bin or whatever it is.

    Sometimes the software you're installing will do this for you automatically and sometimes you need to do it manually yourself (as is the case with ghostscript).

    How to add an executable to the PATH environment variable:

    1. My Computer
    2. Properties
    3. Advanced system settings
    4. Environment variables
    5. Then append the executable to the end of the existing value in either user variables/PATH or system variables/Path - if you use user variables it will only apply to your user if you use system variables it will apply to all users

    Tips:

    • You can skip to step 3 if you press windows key + pause
    • You must separate new entries in the path variable with a semi-colon ;

    If you google something like "add exe to my path windows" I'm sure you'll find plenty of info on this. Hope this helped!