Running venv Python script from PHP - php

I am running many python scripts from PHP. My php script template as below:
<?php
setlocale(LC_ALL, "en_US.utf8");
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
$command = escapeshellcmd("/usr/bin/python2.7 /path/to/script");
$args = escapeshellarg($_GET["title"]). " " .
escapeshellarg($_GET["user"]);
$output = shell_exec($command . " " . $args);
echo $output;
But now I need to run some python scripts which are in virtual environment.
I tried to replace /usr/bin/python2.7 with ./www/python/venv/bin/python3, but it does not work.
So how to run it in PHP?

To really run venv you would need to do three steps in the shell:
Change into project root.
source venv/bin/activate
run python path/to/script
Prerequisite you already have prepared a virtual env for the project.
You could combine this three steps into a bash script and call this script from PHP.

Ideally You should use APIs, that is the best practice. But if you don't have API available you can use pipe. That can be used like this function: exec_command($command) where, $command = $command . " " . $args Below is the code:
<?php
setlocale(LC_ALL, "en_US.utf8");
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
$command = escapeshellcmd("/usr/bin/python2.7 /path/to/script");
$args = escapeshellarg($_GET["title"]). " " .
escapeshellarg($_GET["user"]);
$command = $command . " " . $args;
$output = "";
$hd = popen($command, "r");
while(!feof($hd))
{
$output .= fread($hd, 4096);
}
pclose($hd);
echo $output;
?>

Related

7zip command executes from command line but not within php script

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?

Working Python script throw out error when PHP calls it with exec

I have a simple php code:
<?php echo exec('/opt/anaconda2/bin/python test2.py 2>&1'); ?><br>
And test2.py simply import a library called theano
import theano
It works under ssh but throw out:
KeyError: 'PATH'
when looking at the php in browser.
What's happeneing here? Is there any way that I can see full trace of error msg?
You can try this for the PHP side of things, but I think KeyError is a Python thing:
<?php
$output = array();
exec('/opt/anaconda2/bin/python test2.py 2>&1', $output, $returnCode);
echo 'Output is: ' . PHP_EOL;
var_dump($output);
echo 'Return code is: ' . PHP_EOL;
var_dump($returnCode);
?>

PHP passing parameters to a background script

I've been looking for quite a while on internet, but I cannot find a solution to my problem. I am pretty new to PHP, and I am having issues to run a php script in background.
Basically, I am getting POST data from JQuery ajax, I put it in a long string using escapeshellarg() on each variable and separated by spaces, and I call the script I want to process in background with exec() or shell_exec() functions (I tried both without any success...).
$arg_list = escapeshellarg($str_solution)." ";
$arg_list .= escapeshellarg($str_rubriques)." ";
$arg_list .= escapeshellarg($intervalle)." ";
$arg_list .= escapeshellarg($date_start)." ";
$arg_list .= escapeshellarg($date_end)." ";
$arg_list .= escapeshellarg($_SESSION['user_id'])." ";
$arg_list .= escapeshellarg($_SESSION['user_name']);
//BACKGROUND EXECUTION
$output = shell_exec("/opt/plesk/php/5.6/bin/php-cgi -q script_rapports_intervalle.php ".$arg_list." &");
print_r($output);
On the script_rapports_intervalle.php file, I just do :
print_r($argv);
print_r("here i am");
die;
//HERE GOES THE SCRIPT
//....
I do got a response from this script, as it displays only the "here i am" string. When I use a var_dump() on $argv, it says it is NULL. I have also tried to pass simple arguments like "foo" and "bar", but it seems that $argv is always equal to NULL.
Moreover, I saw many usages for processing a background script: putting "&" at the end of the command, or putting "| at now" instead. Which one should I use?
I guess I am surely doing things the wrong way, but I still cannot see where to fix the issues.
For me this simple code works
$params = array("function_name" => 'image_detect',"image_guid" => $image_guid);
$query_string = http_build_query($params, "", " ");
if (PHP_OS === "WINNT") {
pclose(popen("start /B php " . $script_location . " " . $query_string, "r"));
} else {
exec("/opt/plesk/php/5.6/bin/php " . $script_location . " " . $query_string . " &> /dev/null &");
}
So in your case you can check by replacing /opt/plesk/php/5.6/bin/php-cgi with /opt/plesk/php/5.6/bin/php

Execute find command through ssh2_exec in php & get results

I am using php to execute a find command in linux for search a file in a directory and copy it into a other directory.
My php code is :-
<?php
include 'config.php';
$mxf = $_POST['year'];
$year = substr($mxf, 0, 4);
$ndrive = $_POST['ndrive'];
$command = 'find /var/www/html/collections/'.$year.'/ -name ' . $mxf . ' -exec cp {} ' . $ndrive . ' \;';
$stream = ssh2_exec($con, $command);
stream_set_blocking($stream, true);
$stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
echo stream_get_contents($stream_out);
ssh2_exec($con, 'logout');
?>
Now i want that script return false if requested file is not found in directory or file not available on server. So how can i handle this type of error with ssh2_exec command.

Make PHP wait for Matlab script to finish executing [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
php exec command (or similar) to not wait for result
exec() waiting for a response in PHP
I have a php script that calls and runs a Matlab script. The result of the Matlab script is a .png image, which I would then like to load in php and send to a webpage. The php code I have is:
$matlabExe = '"C:\\Program Files\\MATLAB\\R2012a\\bin\\matlab.exe"';
$mFile = "'C:\\processSatData.m'";
$combine = '"run(' . $mFile . ');"';
$command = $matlabExe . ' -nodisplay -nosplash -nodesktop -r ' . $combine;
passthru($command);
$im = file_get_contents('C:\\habitat.png');
header('Content-type:image/png');
echo $im;
However, it appears that after sending the 'passthru' command, php does not wait for the Matlab script to finish running. Thus, if the image file does not exist before running the php code, then I get an error message.
Is there a way to make it so that the php code waits for the Matlab script to finish running before it attempts to load the image file?
passthru is not the main issue here .. but i guess as soon you have a response from your command the image is not written instantly but by a 3rd process
file_get_contents might also fail in this instance because .. The image might not be written once or in the process of writing which can result to file lock .. in any case you need to be sure you have a valid image before output is sent;
set_time_limit(0);
$timeout = 30; // sec
$output = 'C:\\habitat.png';
$matlabExe = '"C:\\Program Files\\MATLAB\\R2012a\\bin\\matlab.exe"';
$mFile = "'C:\\processSatData.m'";
$combine = '"run(' . $mFile . ');"';
$command = $matlabExe . ' -nodisplay -nosplash -nodesktop -r ' . $combine;
try {
if (! #unlink($output) && is_file($output))
throw new Exception("Unable to remove old file");
passthru($command);
$start = time();
while ( true ) {
// Check if file is readable
if (is_file($output) && is_readable($output)) {
$img = #imagecreatefrompng($output);
// Check if Math Lab is has finished writing to image
if ($img !== false) {
header('Content-type:image/png');
imagepng($img);
break;
}
}
// Check Timeout
if ((time() - $start) > $timeout) {
throw new Exception("Timeout Reached");
break;
}
}
} catch ( Exception $e ) {
echo $e->getMessage();
}
I believe if you change passthru to exec it will work as intended. You can also try this:
$matlabExe = '"C:\\Program Files\\MATLAB\\R2012a\\bin\\matlab.exe"';
$mFile = "'C:\\processSatData.m'";
$combine = '"run(' . $mFile . ');"';
$command = $matlabExe . ' -nodisplay -nosplash -nodesktop -r ' . $combine;
passthru($command);
// once a second, check for the file, up to 10 seconds
for ($i = 0; $i < 10; $i++) {
sleep(1);
if (false !== ($im = #file_get_contents('C:\\habitat.png'))) {
header('Content-type:image/png');
echo $im;
break;
}
}

Categories