The PHP exec command is not executing the same as the shell's interaction.
cd /var/www/myfolder
zip -r /var/www/myfolder/temp/newfile.zip ./*
generates just a zip of files in the temp directory. However (simplified version):
$zip_dir = '/var/www/myfolder';
$temp_dir = $zip_dir . '/temp/';
chdir($zip_dir);
exec('zip -r ' . $temp_dir . 'newfile.zip ./*', $return);
generates the same zip but with the full path's of var and www (which results in two copies of myfolder so my file is twice as large as needed). The $return however has the same output as the command line execution. Both state only 15 files directories/folders were zipped. There is no mention of var or www in the PHP output.
I believe the chdir() command will not have any bearing on how the commands in exec() are run. So this might fix it:
$zip_dir = '/var/www/myfolder';
$temp_dir = $zip_dir . '/temp/';
$cmd = 'cd ' . escapeshellarg($zip_dir) . ' && zip -r ' . escapeshellarg($temp_dir . 'newfile.zip') . ' ./*';
exec($cmd, $return);
Note we always escape variables being passed to the command line.
But why not just zip within PHP?
<?php
$zip_target = "/var/www/myfolder";
$zip_file = "/var/www/myfolder/temp/newfile.zip";
$zip_temp = tempnam(sys_get_temp_dir(), 'a458');
$zip_obj = new \ZipArchive();
if ($zip_obj->open($zip_temp, ZIPARCHIVE::OVERWRITE)) {
$zip_obj->addGlob("$zip_target/**/*.*");
}
$zip_obj->close();
rename($zip_temp, $zip_file);
Related
I am trying to convert videos into MP4 using FFMPEG. I have it set up this way:
.
.
private $ffmpegPath;
public function __construct($con) {
$this->con = $con;
$this->ffmpegPath = realpath("ffmpeg/bin/ffmpeg.exe");
}
.
.
public function convertVideoToMp4($tempFilePath, $finalFilePath){
$cmd = "$this->ffmpegPath -i $tempFilePath $finalFilePath 2>&1";
$outputLog = array();
exec($cmd, $outputLog, $returnCode);
if($returnCode != 0){
foreach ($outputLog as $line){
echo $line."<br>";
return false;
}
}
return true;
}
And in the browser i get the following error:
'C:\xampp\htdocs\Thinksmart First Sprint' is not recognized as an internal or external command".
In my constructor i have it set up to give me the realpath and i suspect that this is what it does in the command line:
C:/xampp/htdocs/Thinksmart FIrst Sprint/ffmpeg/bin/ffmpeg.exe -i (file temp name) (file name i want)
And this should work, but i dont know why it wont. Any ideas? Its my first time working with video conversions.
As you can see, spaces in your command are used to separate arguments. So if there are spaces in a path you need to quote the entire path with quotes so that the shell/processor knows they aren't separators but are one argument:
$cmd = $cmd = '"' . $this->ffmpegPath . '" -i $tempFilePath $finalFilePath 2>&1';
Which will result in a command something like this:
"C:/xampp/htdocs/Thinksmart First Sprint/ffmpeg/bin/ffmpeg.exe" -i C:/path/to/file1 C:/path/to/file2 2>&1
I think only double-quotes work on Windows. You need to quote $tempFilePath and $finalFilePath if they might have spaces in them as well.
I am attempting to write a script which automatically unzips 7zip archives. I'm able to get the command to run from the command prompt, but it doesn't work when running from within the php script.
Here's what I have in terms of code:
$filefolder = "F:/dev/";
$filename = "archive.7z";
$filepath = $filefolder . $filename;
$unzip = "cmd /c 7z x " . $filePath . " -o" . $fileFolder . " -spf";
print_r($unzip . "<br>"); //checking to make sure the command is formed correctly
exec($unzip, $outcome, $rtnStatus);
print_r($outcome);
print_r($rtnStatus);
The following is returned for $outcome and $rtnStatus:
Array ( )
1
What am I missing here?
Following Command search a file in a directory and zip it,it works well
$command = "cd {$root}/files && mkdir -p {$identifier} && zip -jFS -0 {$root}{$zipname} 2491/'test&.txt'";
exec($command);
But changing files as variable is not allowing shell to execute,the below code does not work
$container_name = "2491";
$files = Array ( '0' => 'test&.txt' ,'1' => 'test5.txt','2' => 'test6.txt');
$files = " " . $container_name . "/'" . implode("' " . $container_name . "/'", $files) . "'";
$files = str_replace('$', '\$', $files);
$command = "cd {$root}/files && mkdir -p {$identifier} && zip -jFS -0 {$root}{$zipname} {$files}";
exec($command);
$root,$identifier,$zipname not causing the problem,its $files What can be the issue?
Update
var_dump for $command before execution:
string(128) "cd /var/www/files && mkdir -p zip--1 && zip -jFS -0 /var/www/files/zip--1/1002_22-06022-06022-_content.zip 2491/'test&.txt'"
which if I execute as
exec("cd /var/www/files && mkdir -p zip--1 && zip -jFS -0 /var/www/files/zip--1/1002_22-06022-06022-_content.zip 2491/'test&.txt'");
runs perfectly
Error Reponse:
zip error: Nothing to do! (/var/www/files/zip--1/1002_22-06022-06022-_content.zip)
I got it fix, issue was with file name having '&' which was chanding to '&', thus breaking the command. To get it I passed through the file name with [htmlspecialchars_decode].1
I want to execute shell command from PHP, running under apache. I make script, that shows all info about enviroment.
PHP Script:
<?php
$root = dirname(__FILE__);
$coffeeFile = $root . DIRECTORY_SEPARATOR . 'Script.coffee';
$jsFile = $root . DIRECTORY_SEPARATOR . 'Script.js';
echo "User: " . exec('whoami') . "\n";
echo "Which: " . exec('which coffee') . "\n";
echo "Coffee file perms: " . substr(sprintf('%o', fileperms($coffeeFile)), -4) . "\n";
echo "Js file perms: " . substr(sprintf('%o', fileperms($jsFile)), -4) . "\n";
echo "Dir perms: " . substr(sprintf('%o', fileperms($root)), -4) . "\n";
$command = "coffee -bo $root -c $coffeeFile";
exec($command, $output);
if (filemtime($coffeeFile) > filemtime($jsFile)) {
echo 'compile failed. command: ' . $command . PHP_EOL;
echo "Output: " . implode("\n", $output) . PHP_EOL;
} else {
echo 'compile success. command: ' . $command . PHP_EOL;
}
It I'll execute it from command line from _www user, it will work:
Command:
sudo -u _www php index.php
Output from CLI:
User: _www
Which: /usr/bin/coffee
Coffee file perms: 0777
Js file perms: 0777
Dir perms: 0777
compile success command: coffee -bo /Users/username/htdocs/testcase -c /Users/username/htdocs/testcase/Script.coffee
But if run it from browser, compile fails, but not errors or output is there.
Output in browser:
User: _www
Which: /usr/bin/coffee
Coffee file perms: 0777
Js file perms: 0777
Dir perms: 0777
compile failed. command: coffee -bo /Users/username/htdocs/testcase -c /Users/username/htdocs/testcase/Script.coffee
Output: /* empty array in output */
How it can be? I change my file before every execution, it need to be compiled every time. Users are the same, "which" command works, dir and files have permissions, coffee file is valid. Maybe there are some apache or php.ini settings, that locks execution of some shell commands?
Kindly check does PHP have shell_exec access given or not. Default setting shell_exec is blocked and you have edit php.ini to unblock it and restart service and do things.
Note: Providing shell access can be dangerous as it is the open invitation to the hackers to hack your machine.
I just setup wkhtmltopdf to take html docs and turn them into pdfs but now I need a way to combine the multiple pdfs.
Any suggestions?
We do have pdflib license if there is something it can do but seems its mainly an api for custom building pdfs.
If you got wkhtmltopdf I suppose you're using Linux and you got a root shell access.
You could use Pdftk Toolkit via system() or exec().
First install it. It's a package in Debian/Ubuntu, for example:
sudo apt-get install pdftk
Then make sure that's visible in your bin search PATH.
And a simple PHP snippet:
// In / Out filenames
$input_files = array( 'file_one.pdf', 'file_two.pdf' );
$file_out = 'merged.pdf';
// Escape names and create argument
$line_parts = '';
foreach( $input_files as $file ) {
$line_parts .= escapeshellarg( $file ) . ' ';
}
// Run pdftk
$cmd = 'pdftk ' . $line_parts . ' cat output ' . escapeshellarg( $file_out );
system( $cmd, $retval );
if( $retval ) { print 'There was an error!'; }