using shell_exec question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Paul F. Johnson

    using shell_exec question

    Hi,

    I'm trying to create a zip file from some pdfs and have code similar to this

    $id=$_GET['id'];
    $fn = array("a", "b", "c", "d");
    chdir('../downloads'); // the php file is in /php
    $files = $fn[$id]."1.pdf ".$fn[$id]."2.pdf 7-17.pdf";
    $command = "zip -9 " . $fn[$id] . ".zip " . $files;
    header("content-type:applicatio n/zip");
    header("Content-disposition: attachment; filename=" . $fn[$id] . ".zip");
    header("Pragma: no-cache");
    header("Expires : 0");
    shell_exec($com mand);

    The files do exist and a save as window appears, but the file generated is 0
    bytes long. I have tried changing the command to "/usr/bin/zip"
    and "//usr//bin//zip" and putting the shell_exec before the header lines as
    well changing shell_exec to exec and even just system. All the same result.

    Is there something I'm missing here?

    TTFN

    Paul
  • Andy Jeffries

    #2
    Re: using shell_exec question

    On Mon, 22 May 2006 22:02:51 +0000, Paul F. Johnson wrote:[color=blue]
    > $command = "zip -9 " . $fn[$id] . ".zip " . $files;
    > header("content-type:applicatio n/zip");
    > header("Content-disposition: attachment; filename=" . $fn[$id] . ".zip");
    > header("Pragma: no-cache");
    > header("Expires : 0");
    > shell_exec($com mand);
    >
    > The files do exist and a save as window appears, but the file generated
    > is 0 bytes long. I have tried changing the command to "/usr/bin/zip" and
    > "//usr//bin//zip" and putting the shell_exec before the header lines as
    > well changing shell_exec to exec and even just system. All the same
    > result.
    >
    > Is there something I'm missing here?[/color]

    Yes, re-read the help page for shell_exec, you're missing something there:

    Execute command via shell and return the complete output as a string


    Basically, shell_exec executes the command and returns the output as a
    string. So what you are doing is running (for example):

    zip -9 a.zip 1.pdf 2.pdf 3.pdf

    When you run this command manually on the server, what output does it
    produce? The answer is nothing (assuming the command succeeds as good
    Linux utilities should). So, that's part one of the problem, there's no
    output to actually send to the browser.

    Part two of the problem is that even if you could get zip to write it's
    output to "stdout" so you could then get the returned zip data from
    shell_exec, you aren't actually sending it to the browser (i.e. you run
    shell_exec without capturing the result or printing it).

    What I would do is change your code to be as follows:

    $command = "zip -9 $fn[$id].zip $files";
    header("content-type:applicatio n/zip");
    header("Content-disposition: attachment; filename=$fn[$id].zip");
    header("Pragma: no-cache");
    header("Expires : 0");
    shell_exec($com mand);
    @readfile("$fn[$id].zip");

    In this, all I've done is change a few bits to make use of variable
    substitution within a string (concatenation is faster but looks a lot less
    readable) and then added a call to readfile at the end, which reads a file
    from disk and prints the contents to the browser.

    Cheers,


    Andy


    --
    Andy Jeffries MBCS CITP ZCE | gPHPEdit Lead Developer
    http://www.gphpedit.org | PHP editor for Gnome 2
    http://www.andyjeffries.co.uk | Personal site and photos

    Comment

    • Paul

      #3
      Re: using shell_exec question

      On Tue, 2006-05-23 at 10:16 +0000, Andy Jeffries wrote:
      [color=blue]
      > What I would do is change your code to be as follows:
      >
      > $command = "zip -9 $fn[$id].zip $files";
      > header("content-type:applicatio n/zip");
      > header("Content-disposition: attachment; filename=$fn[$id].zip");
      > header("Pragma: no-cache");
      > header("Expires : 0");
      > shell_exec($com mand);
      > @readfile("$fn[$id].zip");
      >
      > In this, all I've done is change a few bits to make use of variable
      > substitution within a string (concatenation is faster but looks a lot less
      > readable) and then added a call to readfile at the end, which reads a file
      > from disk and prints the contents to the browser.[/color]

      Okay, I've done that, but it's now giving an empty file of 0 bytes in
      length.

      The new code looks like this

      <?php
      chdir ('../downloads');
      $pid = $_GET['id'];
      $pid--;
      $courses=array( "hndmp", "batar", "bamlb", "bscmt", "bajor");
      $counter = count($courses) ;
      if ($pid > $counter)
      exit;
      $prog = $courses[$id];
      $filenames = array($prog."fc .pdf", $prog."1-3.pdf", $prog."5-6.pdf");
      $prog .= ".zip";
      $command = "";
      for ($i = 0; $i < $counter; ++$i)
      $command .= "zip -9 $prog $filenames[$i];";
      header("content-type: application/zip");
      header("content-disposition: attachment; filename=$prog" );
      header("pragma: no-cache");
      header("expires : 0");
      shell_exec($com mand);
      @readfile("$pro g");
      ?>

      As a test, I added an echo line after the for loop and the output was
      expected (the created zip file was actually a text file with the echo
      output inside of it). Changing @readfile to readfile showed that the
      file hadn't actually been created.

      Now, if I change where $prog is to be /tmp/$prog, I hit an interesting
      problem, the file is created, but the permissions are for apache:apache
      rather than myself and obviously, chown won't work (unless I sudo it).
      Have I hit more a permissions problem than a php one?

      TTFN

      Paul
      --
      "Logic, my dear Zoe, is merely the ability to be wrong with authority" -
      Dr Who

      Comment

      • Andy Jeffries

        #4
        Re: using shell_exec question

        On Tue, 23 May 2006 13:51:35 +0100, Paul wrote:[color=blue]
        > Okay, I've done that, but it's now giving an empty file of 0 bytes in
        > length.
        >
        > The new code looks like this[/color]

        <snipped>
        [color=blue]
        > As a test, I added an echo line after the for loop and the output was
        > expected (the created zip file was actually a text file with the echo
        > output inside of it). Changing @readfile to readfile showed that the file
        > hadn't actually been created.[/color]

        How can it be if you manually looked at the zip file and saw it was a text
        file with the echo output inside of it? My point is, if the file doesn't
        exist afterwards it's a problem in the creation (maybe the zip command
        isn't putting it in the right place). If the file exists but it's not
        going to the browser then it's either a permissions problem or it's
        looking in the wrong place.

        That should give you a nudge to do some echos (remove the header lines so
        you can just see the output of the echos) to debug which it is.
        [color=blue]
        > Now, if I change where $prog is to be /tmp/$prog, I hit an interesting
        > problem, the file is created, but the permissions are for apache:apache
        > rather than myself and obviously, chown won't work (unless I sudo it).
        > Have I hit more a permissions problem than a php one?[/color]

        Why would you care if the permissions are for apache:apache? That's who
        created the file and who is reading the file (to pass it down to the
        browser)?

        Cheers,


        Andy

        --
        Andy Jeffries MBCS CITP ZCE | gPHPEdit Lead Developer
        http://www.gphpedit.org | PHP editor for Gnome 2
        http://www.andyjeffries.co.uk | Personal site and photos

        Comment

        Working...