exec() and passthru() php executing - php

I try to execute a python script with PHP But I got no results:I tried
$tmp = passthru("C:\\Python27\\python.exe C:\\Python27\\script.py C:\\Python27\\file.pdf",$output);
print($output)
The results :"1"
While
$tmp = exec("C:\\Python27\\python.exe C:\\Python27\\script.py C:\\Python27\\file.pdf",$output);
returns Array ( )
I'm excepted to return a string,any suggestions?
I verified in my php.ini file
safe_mode = Off
Thanks!!

The documentation of exec() says that the $output parameter is an array that will be filled in with each line. If you want to turn this into a single string, use:
$output_string = implode("\n", $output);

This should work for you:
ob_start();
passthru("C:\\Python27\\python.exe C:\\Python27\\script.py C:\\Python27\\file.pdf");
$filedata = ob_get_clean();
echo $filedata;

python buffers output by default. Set environment variable PYTHONUNBUFFERED to a nonempty string, or run python with -u.

Related

dynamically get results from exec

I have a php script that calls a go script. It gets results every 1-2 seconds, and print's them. Using php's exec and output, I only get the results when the program finishes. Is there a way I can check the output to see when it changes and output that while it's still running?
Something like this, but pausing the execution?:
$return_status = 0;
$output = [];
$old_output = ["SOMETHING ELSE"];
while ($return_status == 0) {
exec($my_program,$output,$return_status); #somehow pause this?
if $output != $old_output {
echo($output);
$old_output = $output;
}
}
Yes. Use the popen() function to get a file handle for the command's output, then read from it a line at a time.

var_dump has unreadable output

I have a method to dump a var_dump output to a file, as such:
function dumpToFile($object) {
$file = "c:/tmp/php.log";
ob_start();
var_dump($object);
$output = ob_get_clean();
$fh = fopen($file, "a+");
fwrite($fh, $output."\r\n");
}
Out of nowhere, the output of this is always starting with a tag like this and has some characters that are HTML encoded, like &quot
<pre class='xdebug-var-dump'> dump content... </pre>
I don't remember changing the PHP.ini file, any ideas ? I'm using php-cgi.exe under Windows.
var_dump itself outputs the garbled data, so it's not my method as far as I can see.
Seems like your xdebug has been enabled. See below post on how to disable:
https://stackoverflow.com/a/8754934

How to write the exec command(in PHP) output to a file?

I will provide a example
i want the directory list to be written to a file
so i did this
<?php
$command="dir";
exec($command,$output);
//i want the directory list to be written to a file
// so i did this
$fp=fopen("file.txt","w");
fwrite($fp, $output);
//its actually writing the 0(return value for exec is int) to the file
// but i want the list of directories to be written to file
?>
its actually writing the 0(return value for exec is int) to the file
but i want the list of directories to be written to file
Please tell me a way to do that
You can simply use shell_exec:
<?php
$output = shell_exec('dir');
$fp=fopen("file.txt","w");
fwrite($fp, $output);
?>
i think that for your needle you should use the command "passthru".
Here an example:
<?php
$command = exec('dir', $outpout);
$data = "";
foreach($output AS $key=>$val){
$data .= $val . "\n";
}
$fp = fopen('file.txt', 'w') or die("i cant write...permission ?");
fwrite($fp, $data);
fclose($fp);
?>
Let me know if it works
Have a nice day
Antonio
P.S. Thanks Kevin
You can do it directly in the exec call (it's shorter) :
exec("dir > file.txt")
Anyway, your code is wrong because $output is an array.
Fixed code :
$command="dir";
exec($command,$output);
$fp=fopen("file.txt","w");
fwrite($fp, join("\n",$output))
And a shorter code :
exec("dir",$output);
file_get_contents("file.txt",join("\n",$output));

Execute User Input at breaks from PHP to Shell

I have a php script that is called and it executes a shell command through shell_exec(). This shell command requires multiple user inputs at different stages. I am stuck with getting the interactivity piece working at each input stage.
This is just an example of how I imagine it working...
<?php
$return = shell_exec('runcmd');
//Let runcmd run until first break
echo $return;
$userinput1 = 'foo';
//Let runcmd run until next break
echo $return;
$userinput2 = 'bar';
//Let runcmd run until nth break
echo $return;
$userinputNth = 'nth';
To feed input to a shell command, use popen.
$handle = popen('runcmd', 'w');
fputs($handle, 'foo
bar
nth
');
pclose($handle);
Since output is not captured, we needn't echo it.

Running a script from another script with session data

I am trying to have a script start another script and put its data into a session variable for the other script to use. The problem is that when the second script, data.php, runs it doesn't seem to be able to access the session variables. They are blank and nothing gets written to data.txt. If I run data.php by itself it writes the last value that $_SESSION["data"] was set to properly, but not when it's run with exec. I am not sure what the problem is. Any ideas?
input.php:
session_start();
$_SESSION["data"] = "Data!";
exec("/usr/bin/php /path/to/data.php > /dev/null 2>&1 &");
data.php:
session_start();
$fp = fopen('data.txt', 'w');
fwrite($fp, $_SESSION["data"]);
fclose($fp);
Edit: I am trying to start data.php from inside input.php and have the variables from input.php accessible in data.php.
You can pass data to PHP scripts running with the CLI as command line arguments. This data will be available to the child script in the $argv array.
input.php:
$arg = "Data!";
exec("/usr/bin/php /path/to/data.php ".escapeshellarg($arg)." > /dev/null 2>&1 &");
data.php
$fp = fopen('data.txt', 'w');
fwrite($fp, $argv[1]);
fclose($fp);
A couple of notes:
It is important to pass each argument through escapeshellarg() to ensure that users are not able inject commands into your shell. This will also stop special shell characters in arguments from breaking your scripts.
$argv is a global variable, not a superglobal like $_GET and $_POST. It is only available in the global scope. If you need to access it in a function scope, you can use $GLOBALS['argv']. This is about the only situation in which I consider the use of $GLOBALS acceptable, although it is still better to handle the arguments in the global scope on startup, and pass them through the scopes as arguments.
$argv is a 0-indexed array, but the first "argument" is in $argv[1]. $argv[0] always contains the path to the currently executing script, because $argv actually represents the arguments passed to the PHP binary, of which the path to your script is the first.
Values from command line arguments always have a string type. PHP is very promiscuous with its typing so with scalar values this doesn't matter, but you (fairly obviously) can't pass vector types (objects, arrays, resources) through the command line. It is possible to pass objects and arrays by encoding them with e.g. serialize() or json_encode(). There is no way to pass resources through the command line.
EDIT When passing vector types I prefer to use serialize() because it carries with it information about the classes that objects belong to.
Here is an example:
input.php:
$arg = array(
'I\'m',
'a',
'vector',
'type'
);
exec("/usr/bin/php /path/to/data.php ".escapeshellarg(serialize($arg))." > /dev/null 2>&1 &");
data.php
$arg = unserialize($argv[1]);
$fp = fopen('data.txt', 'w');
foreach ($arg as $val) {
fwrite($fp, "$val\n");
}
fclose($fp);
Here is a couple of functions from my clip collection I use to simplify this process:
// In the parent script call this to start the child
// This function returns the PID of the forked process as an integer
function exec_php_async ($scriptPath, $args = array()) {
$cmd = "php ".escapeshellarg($scriptPath);
foreach ($args as $arg) {
$cmd .= ' '.escapeshellarg(serialize($arg));
}
$cmd .= ' > /dev/null 2>&1 & echo $$';
return (int) trim(exec($cmd));
}
// At the top of the child script call this function to parse the arguments
// Returns an array of parsed arguments converted to their correct types
function parse_serialized_argv ($argv) {
$temp = array($argv[0]);
for ($i = 1; isset($argv[$i]); $i++) {
$temp[$i] = unserialize($argv[$i]);
}
return $temp;
}
If you need to pass a large amount of data (larger than the output of getconf ARG_MAX bytes) you should dump the serialized data to a file and pass the path to the file as a command line argument.
You could try to urlencode the $_SESSION ["data"] and pass it as an argument to the CLI script:
Script 1
$URLENCODED = urlencode($_SESSION["data"]);
exec("/usr/bin/php /path/to/data.php " . $URLENCODED . " > /dev/null 2>&1 &")
Script 2
$args = urldecode($argv[1]); // thanks for the reminder daverandom ..forgot to do this :)
fwrite($fp, $args);

Categories