By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,693 Members | 1,936 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,693 IT Pros & Developers. It's quick & easy.

using shell_exec question

P: n/a
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:application/zip");
header("Content-disposition: attachment; filename=" . $fn[$id] . ".zip");
header("Pragma: no-cache");
header("Expires: 0");
shell_exec($command);

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
May 22 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
On Mon, 22 May 2006 22:02:51 +0000, Paul F. Johnson wrote:
$command = "zip -9 " . $fn[$id] . ".zip " . $files;
header("content-type:application/zip");
header("Content-disposition: attachment; filename=" . $fn[$id] . ".zip");
header("Pragma: no-cache");
header("Expires: 0");
shell_exec($command);

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?


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

http://uk.php.net/shell_exec

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:application/zip");
header("Content-disposition: attachment; filename=$fn[$id].zip");
header("Pragma: no-cache");
header("Expires: 0");
shell_exec($command);
@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

May 23 '06 #2

P: n/a
On Tue, 2006-05-23 at 10:16 +0000, Andy Jeffries wrote:
What I would do is change your code to be as follows:

$command = "zip -9 $fn[$id].zip $files";
header("content-type:application/zip");
header("Content-disposition: attachment; filename=$fn[$id].zip");
header("Pragma: no-cache");
header("Expires: 0");
shell_exec($command);
@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.


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($command);
@readfile("$prog");
?>

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

May 23 '06 #3

P: n/a
On Tue, 23 May 2006 13:51:35 +0100, Paul wrote:
Okay, I've done that, but it's now giving an empty file of 0 bytes in
length.

The new code looks like this
<snipped>
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.
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.
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?


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

May 23 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.