Why doesn't PHP exec() work on the first page load?
I'm executing a python script via PHP using the following line:
exec("python suggester.py " . $query_plus . " " . $location, $output);
Most of the time this works fine, but on the initial load of my page (suggester.promediacorp.com) the POST request sits in waiting/pending for almost a minute until it finally returns a response. If the page is refreshed, or another query runs after, it works perfectly.
I'm almost 100% sure the issue is related to exec(), because when I remove that code I get my response immediately. Additionally, the issue persists even if the python file has no contents.
You do not have arguments escaped propperly. See http://php.net/manual/en/function.escapeshellarg.php
I figured it out. It was an issue with php's error logging that was echoed before my script finished running.
Related
So I am making a simple website for personal use, it sends an Post request via Ajax, PHP code is something like that:
$cmd = "some command";
$r = shell_exec($cmd);
echo $r;
Now, the first time I send the request it works, but if I send more requests without refreshing whole page it returns nothing. PHP script does execute, just shell_exec returns nothing. I have no idea what is causing this.
(Debian, Apache2, PHP7.0)
ajax code:
$.post("exec.php", {command: val}).done(function(data){
self.outp.append(data);
});
And I confirmed that val is correct, if in PHP i add something to $r (example: $r .= "test") it does return that.
#Edit I've found out using GET insted of POST makes the problem disappear, it does not really resolve the problem, but it's something.
ok, I know I'm doing something weird here but I gotta do it.
So my elixir program needs to run one PHP script and take the information from that script, but it never comes in. I can manually run the php script and it works fine. At the bottom of the script it says:
echo $avar->getPUId();
So it's printing it out to echo I guess. I get the data I need when I run it from a command line:
C:\PHP>php.exe "-f" "C:\pap.php" "613b8859"
37a69912
But when I run it from iex I get nothing:
iex(1)> System.cmd("C:\\PHP\\php.exe", ["-f", "C:\\pap.php", "613b8859"])
Terminate batch job (Y/N)? y
Now, if I mess up on the filename or something php will give me an error in response saying like:
iex(1)> System.cmd("C:\\PHP\\php.exe", ["-f", "C:\\pap321.php", "613b8859"])
{"Could not open input file: c:/pap123.php\n", 1}
...
so I know I can talk to PHP, and it can talk back to me with errors, but echo isn't caught by my elixir application that calls it apparently. Is there any other way I can grab the data as it comes out of the PHP script?
I used
https://github.com/alco/porcelain
result = Porcelain.shell("C:\\PHP\\php.exe -f C:\\pap.php 613b8859")
IO.inspect result.out
it worked great.
So I'm working with PHP to attempt to execute a script I have in the same directory. The script runs fine locally and the permissions for the http-data user are set to be able to execute the script referenced in this block of PHP
$cmd = system('th neural_style.lua -style_image'.' ~/'.$style.'.jpg '.'-content_image '.$content_image.' -gpu 0 -backend cudnn -save_iter 1 -cudnn_autotune -output_image /var/www/html/processed/'.$email.'/out.png 2>&1', $retval);
echo '
</pre>
<hr />Recent output: ' . $last_line . '
<hr />Return value: ' . $retval;
The script should execute fine using the system method from what I understand, I know the variables look messy though this is the error I get from PHP:
sh: th: command not found
I set my default interpreter to bash instead of dash thinking that might be an issue, no dice. Torch is in the same directory, and like I said runs fine as my login.
I know what I'm trying to do in a way is like sacrilege, if there is a better way to run a script that takes 8 minutes roughly to complete using some user input from the web, I want to know. This is just what came natural to me. I'm looking to notify the user when the process is complete with an email anyways so any way of executing it is just dandy.
Edit: any mention of "http-data" was supposed to say "www-data".
Change the default shell for your http-data user to bash or dash. It is currently using sh.
Check what your $PATH variable is inside the PHP environment.
Here I am writing about my flow in detail.
I am doing an Ajax request on same host.
AJAX call to saveUser.php
in saveUser.php, I have included Common.php.
Common.php have createFile1() and createFile2() function.
createFile1() function just creating a sample1.php for another purpose.
in createFile2(), I am creating a file sample2.php and executing a exec('php /home/public/sample2.php > /dev/null &'); command to execute that file.
I am calling this createFile1() and createFile2() function respectively from saveUser.php which is being called by an AJAX request.
As I have set the exec command to run in background by '&' at end of command, it is returning without waiting for the response and all goes smoothly in front.
But when I am checking on my server, these files sample1.php and sample2.php are getting created again and again. It seems all this saveUser.php action are getting executed again and again until I stops the sample2.php process from SSH.
I checked the processes list, each time 'php /home/public/sample2.php' is having new process_id, so it confirms that it is getting executed again and again. If I remove the exec() code and execute this sample2.php from SSH, it works as expected, there is not such problem.
Please suggest me whats going on wrong? Is there any problem with server configuration, I am using hostgator shared account.
Also I am including same Common.php file in sample2.php also, informing in case it can help it.
Thanks for your help in advance.
saveUser.php code
include_once dirname(__FILE__).'/Common.php';
createFile1();
createFile2();
echo 'saved successfully!';
Common.php code
function createFile1()
{
$template = file_get_contents('sendDmTemplate.php');
$serviceFp = fopen('sendDmFiles/sample1.php',"w");
fwrite($serviceFp , $fileContent);
fclose($serviceFp);
}
function createFile2()
{
$fileContent = file_get_contents(dirname(__FILE__).'/sampleFileTemplate.php');
$serviceFp = fopen('sample2.php',"w");
fwrite($serviceFp , $fileContent);
fclose($serviceFp);
exec('php '.dirname(__FILE__).'/sample2.php > /dev/null &');
}
sample2.php code
include_once dirname(__FILE__).'/Common.php';
echo 'hi';
This exact same thing happened to me. I was trying to have one php script call exec() on another php script but for some strange reason it would just exec() itself again creating an infinite loop. The currently accepted answer didn't get me anywhere, but I was able to get it to work by specifying an absolute path to php.
So, instead of
exec('php /home/public/sample2.php > /dev/null &');
it would be
exec('/usr/local/bin/php /home/public/sample2.php > /dev/null &');
Check the following:
1) Are you sure you are NOT calling your script saveUser.php multiple times? Mayby a codingerror somewhere in the javascript XHR? Check this by looking in the (apache?) log.
2) Are you sure your php executes alright without the -q? I use php -q pathtoscript.php
3) If not 1 or 2: Post the code in here (or somewhere) of saveUser.php
EDIT: I see your problem. The file you create includes common.php again, and executes that again. Etc. <-- wrong Oops. I wrote that too early. Looking into it again now.
4) Is it possible you use some errorhandling that redirects to your saveUser.php?
Edit:
5) There might arise a problem from the fact that you are including the file that is executing the command itself in combination with include_once, but I am not sure. You could simply test this by changing your content of sample2.php content by adjusting sampleFileTemplate.php. Create a common2.php (with identical content as common.php), and use that one. COuld you testdrive that setup and report back?
I have a PHP script which calls exec(). I've been having trouble all day with some code calling the same script working and some not (exec() returns a 127 error code).
I have finally worked out that the code that is not working is the code that is being called from jQuery on my web page:
$('#next_button').click(function(event) {
$.get('download_forms.php', function(data) {
alert(data);
});
});
However, if I type the url for download_forms.php into the address bar of my browser, then exec() will execute properly. I have tries to run other scripts that call exec() from jQuery to test and they all fail, but work if typed into the address bar.
I don't see why this would be an issue. Whether I type the url into Firefox's address bar, or whether pressing the button on my webpage, an HTTP request will be made.
Does anybody know what the difference could possibly be?
Note: I have tried different commands in exec() and they are all failing from my jQuery (note all the rest of the PHP code runs fine) but work when the script address is typed directly into the address bar.
Many thanks
Update
This is my download_forms.php code. The initial exec() was just to see if exec() worked at all. As above, it only executes properly if typed directly into the address bar.
include ('inc/session.inc.php');
require_once('Downloader.php');
exec('id', $output, $r);
echo var_dump($output);
echo($r);
try {
$downloader = new Downloader();
$saveMessages = $downloader->saveToDatabase();
// exec() in the combineAndDownloadForms() method
$downloadMessages = $downloader->combineAndDownloadForms();
} catch(Exception $e) {
echo $e->getMessage();
}
Further Update
I made a hyperlink through from my webpage to the download_forms.php page (ie a <a>), but exec() still doesn't execute. At least I know it's nothing to do with ajax.
For what it's worth, I fixed this issue and all of the above was a red herring.
I hadn't noticed that the page I was on was using the secure https protocol, so when the download_forms.php script was being used, it was also accessed using https and it seems that the exec() and passthru() functions won't execute commands on the server in these circumstances, which makes sense.
I changed the script so that it changed the protocol of the download_forms.php url to ordinary http and it's now functioning fine.
HTH