After many trials and many days of search I am asking this question. I have tried many online solutions but doesn't seem to work for me. I have a python file Server.py that starts the flask server for me.
I want to start this file from a php file and display output. Right now I am trying with exec() function but the webpage keeps running and I could not figure if the server has started or not.
I have tried following ways with exec() and making a batch file
exec('C:/foldername/py/apps/webapp/s.bat &');
or
exec('C:/foldername/py/apps/webapp/s.bat > /dev/null');
or
$command = "python C:/folder/server.py";
$pid = popen( $command,"r");
Please help
I was able to achieve what I want in the end. I created a task schedule to open the batch file that can start my server. Then I set trigger on windows event. After that I created a batch file which creates an event in windows event logger and a php script to run that batch file. So, finally I was able to start python server file by php script with the help of task scheduler.
Related
I have 2 websites, hosted on 2 different servers. They are kind of interlinked. Sometimes I just do stuff on Website-1 and run a script on Website-2. Like I edited something on Website-1 and now I want to run a script on Website-2 to update accordingly on it's server.
Till now I am using following code on website 1.
$file = file_get_contents('Website-2/update.php');
But the problem with this is that my Website-1 server script stops running and wait for the file to return some data. And I don't wanna do anything with that data. I just wanted to run the script.
Is there a way where I can do this in a better way or tell PHP to move to next line of code.
If you want to call the second site without making your user wait for a response,
I would recommend using a message queue.
Site 1 request would put a message to the queue.
Cron job to check queue and run update on site 2 when message exists.
Common queues apps to look at:
[https://aws.amazon.com/sqs/?nc2=h_m1][1]
[https://beanstalkd.github.io/][2]
[https://www.iron.io/mq][3]
[1]: https://aws.amazon.com/sqs/?nc2=h_m1
[2]: https://beanstalkd.github.io/
[3]: https://www.iron.io/mq
What you're trying to achieve is called a web hook and should be implemented with proper authentication, so that not anybody can execute your scripts at any time and overload your server.
On server 2 you need to execute your script asynchronously via workers, threads, message queues or similar.
You can also run the asynchronous command on your server 1. There are many ways to achieve this. Here are some links with more on this.
(Async curl request in PHP)
(https://segment.com/blog/how-to-make-async-requests-in-php/)
Call your remote server as normal. But, In the PHP script you normally call, Take all the functionality and put it in a third script. Then from the old script call the new one with (on Linux)
exec('php -f "{path to new script}.php" $args > /dev/null &');
The & at the end makes this a background or non-blocking call. Because you call it from the remote sever you don't have to change anything on the calling server. The php -f runs a php file. The > /dev/null sends the output from that file to the garbage.
On windows you can use COM and WScript.Shell to do the same thing
$WshShell = new \COM('WScript.Shell');
$oExec = $WshShell->Run('cmd /C php {path to new script}.php', 0, false);
You may want to use escapeshellarg on the filename and any arguments supplied.
So it will look like this
Server1 calls Server2
Script that was called (on Server2) runs exec and kicks off a background job (Server2) then exits
Server1 continues as normal
Server2 continues the background process
So using your example instead of calling:
file_get_contents('Website-2/update.php');
You will call
file_get_contents('Website-2/update_kickstart.php');
In update_kickstart.php put this code
<?php
exec('php -f "{path}update.php" > /dev/null &');
Which will run update.php as a separate background (non-blocking) call. Because it's non-blocking update_kickstart.php will finish and return to searver1 which can go about it's business and update.php will run on server2 independantly
Simple...
The last note is that file_get_contents is a poor choice. I would use SSH and probably PHPSecLib2.0 to connect to server2 and run the exec command directly with a user that has access only to that file(Chroot it or something similar). As it is anyone can call that file and run it. With it behind a SSH login it's protected, with it Chrooted that "special" user can only run that one file.
I am trying to build a small custom task scheduler. Basically the idea is I have cron run my process script, which looks in the database and finds any scheduled tasks that are ready to run, and runs them. So I think the best way to do this would be to try to launch the tasks "in the background" by way of shell_exec and using > /dev/null, which I understand makes it so the initial script (the process script) doesn't wait for the task scripts to complete.
So first, if there is a better way to achieve this, I'm open to suggestions. Though note I am on php 5.3 so there may be some options in 5.4 and up that I don't have access to :(
However here's the question at hand:
I am testing on WAMP on my windows machine and I am trying to make a call that looks like this:
shell_exec("php $path$base_url$querystring > output_test.txt 2>&1 &");
$path is the full windows path to the script
$base_url is the base url of the script I am calling
$querystring is of course the query string being passed to the task script
I am also outputting to output_test.txt which creates such file in same directory, where I get the following error:
Could not open input file:
C:\xampp\htdocs\email\batch_email_send_u2u.php?dealer=7
Yes I realize the path references an xampp installation, but that is not the issue - all the wamp files are executing from there and everything else has worked like this for years - it was just set up this way to support a legacy setup.
It seems to me shell_exec is locating and running php, it's just that it can't open the referenced script. Can't figure out why.
Also I need to eventually get this working on a real linux server so any advice on how to make that happen would be greatly appreciated!
Found a solution! Special thanks to dan08 for getting me set on the right path.
Ultimately I found the answer in this thread: Pass variable to php script running from command line
I ended up using the argv[] array as described in that post and with a little tweak to the script I'm calling it works like a champ now.
have a php page called cronEmail in the web folder. It incudes the code to end an email to specific users on the website. I want it to open the page once a day and send the email. The page has only php and MySql code to read the recipients of the email.
I am trying to use Task scheduler in the control panel to run the page. I create a user defined script and in schedule I set the time to a certain time and to only run daily once a day.
In the rum command i have tried numerous ways to run it on the time but every time it just passes and does nothing. an example of what I put in for the script is
/web/cronEmail.php OR
chmod 755 /volume1/web/cronEmail.php
There are only two of a many can anyone point me in the right direction
Thanks a million
Seems like you want a cronjob, in the terminal open cron with:
crontab -e
then at the bottom of the file place this
0 4 * * * php /url/to/folder/cronEmail.php
Not sure if you found another solution, but this is what worked for me. If you put the following in the "Run Command" section, it should work:
php /volume1/web/cronEmail.php
You can also create an error log by doing the following:
php /volume1/web/cronEmail.php>> /volume1/web/errors.log 2>&1
If you don't use the php at the beginning, and open up the error.log file that is created, what you'll see is that the Task Scheduler doesn't seem to know that it's looking for PHP, and doesn't recognize the script.
I have a php scrip, in which i have written the following code
$client = new \Predis\Client();
$client->select(4);
$client->lpush('emailid',$x['to']);
$command = "/usr/bin/php5 -f /var/www/Symfony/src/Ens/NewBundle/Controller/cron.php";
exec( "$command > /dev/null &", $arrOutput );
return $this->render('EnsNewBundle:Email:header.html.twig');
in this I have written an another php script named as cron.php. I want to run that script in background. and I want to check that is this running in background or not. how can i check that
Maybe you could have a look to the Symfony2 Process component.
It's quite useful for running command from PHP.
You can take the output of cron in a file by > filename and check if it really runs.
Or check in process list if there is a new php process stating when you run this one.
You should also look at Codememe bundle here
Do check open source queuing systems too, they are helpful many times.
Like Beanstalkd or RabbitMQ
You can push data to these queues, they can be say "filenames" and other worker takes data from the "tubes" of queues and apply say "php filename" and then picks up next data from queue.
I have a PHP website and I would like to execute a very long Python script in background (300 MB memory and 100 seconds). The process communication is done via database: when the Python script finishes its job, it updates a field in database and then the website renders some graphics, based on the results of the Python script.
I can execute "manually" the Python script from bash (any current directory) and it works. I would like to integrate it in PHP and I tried the function shell_exec:
shell_exec("python /full/path/to/my/script") but it's not working (I don't see any output)
Do you have any ideas or suggestions? It worths to mention that the python script is a wrapper over other polyglot tools (Java mixed with C++).
Thanks!
shell_exec returns a string, if you run it alone it won't produce any output, so you can write:
$output = shell_exec(...);
print $output;
First off set_time_limit(0); will make your script run for ever so timeout shouldn't be an issue. Second any *exec call in PHP does NOT use the PATH by default (might depend on configuration), so your script will exit without giving any info on the problem, and it quite often ends up being that it can't find the program, in this case python. So change it to:
shell_exec("/full/path/to/python /full/path/to/my/script");
If your python script is running on it's own without problems, then it's very likely this is the problem. As for the memory, I'm pretty sure PHP won't use the same memory python is using. So if it's using 300MB PHP should stay at default (say 1MB) and just wait for the end of shell_exec.
A proplem could be that your script takes longer than the server waiting time definied for a request (can be set in the php.ini or httpd.conf).
Another issue could be that the servers account does not have the right to execute or access code or files needed for your script to run.
Found this before and helped me solve my background execution problem:
function background_exec($command)
{
if(substr(php_uname(), 0, 7) == 'Windows')
{
pclose(popen('start "background_exec" ' . $command, 'r'));
}
else
{
exec($command . ' > /dev/null &');
}
}
Source:
http://www.warpturn.com/execute-a-background-process-on-windows-and-linux-with-php/
Thanks for your answers, but none of them worked :(. I decided to implement in a dirty way, using busy waiting, instead of triggering an event when a record is inserted.
I wrote a backup process that runs forever and at each iteration checks if there is something new in database. When it finds a record, it executes the script and everything is fine. The idea is that I launch the backup process from the shell.
I found that the issue when I tried this was the simple fact that I did not compile the source on the server I was running it on. By compiling on your local machine and then uploading to your server, it will be corrupted in some way. shell_exec() should work by compiling the source you are trying to run on the same server your are running the script.