Run PHP script in background on Apache start/restart(Windows Server) - php

I've installed Apache 2.4 with PHP 5.4 on Windows Server 2008 following instructions from this manual:
Apache installing manual.
Apache runs as a service now.
My application requires a php websocket script to run in the background. I'm running it manually with:
php myscript.php
The question is: Is there a way to start a background script automatically on system(apache) restart?
I found the following topic, but I didn't know where I could find an apache startup script for Windows.
Any help will be much appriciated.

I come up with a solution :)
Create an environment variable pointing to your Apache directory
APACHE_HOME = C:/PATH/TO_APACHE
Rename %APACHE_HOME%\bin\httpd.exe to %APACHE_HOME%\bin\httpdVendor.exe
Create a batch file and put the following code :
php myscript.php
%APACHE_HOME%\bin\httpdVendor.exe -k runservice
exit 0
Download/Install the free software BatToExeConverter (next, next, ...)
Open the installed converter and open your freshly created batch file
Click on the button Build EXE (let the default configuration)
Save the file : %APACHE_HOME%\bin\httpd.exe
Start your Apache Server
Tested on : Windows 7, Apache 2.4, Advanced Bat to Exe Converter 2.92

Use built in Windows Task Scheduler which triggers .bat script, which calls curl with defined url.
Download curl from http://curl.haxx.se/download.html and extract curl.exe on any directory, but we will use c:\backgroundtasks
Adjust script below to your needs:
cd c:\
cd c:\backgroundtasks
curl http://localhost/path/to/script.php
exit
Configure Task Scheduler to run as basic task:
General tab - as system account (to run when you are not logged in server)
Triggers tab - adjust frequency
Settings tab - at bottom set If the task is already running... to Stop the existing instance

The best method here would be to use Windows services dependencies.
Make a php-websocket-server.cmd file with any necessary environment settings (e.g. changing to a directory, setting PATH, etc...) with the last line:
php myscript.php
Install the Windows Server Resource Kit Tools, to get srvany and instsrv to create a user defined service. Note the install path as you'll need it in the next step.
Open a cmd shell and run:
<path_to_resource_kit>\instsrv PHPWebSocketServer <path_to_resource_kit>\srvany.exe
Next, create a file php-websocket-server.reg containing the following (update for your environment):
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PHPWebSocketServer\Parameters]
"Application"="c:\\path\\to\\php-websocket-server.cmd"
Import it by double-clicking or regedit /s php-websocket-server.reg
Back in your cmd shell:
sc config Apache2.4 depend= PHPWebSocketServer
to make the Apache2.4* service depend on your php service. Now, when Apache is started, the php service will be brought up first. And likewise, if you stop the php service Apache will stop along with it.
*the howto indicates that the service is named "Apache2.4" but you may want to verify in your installation.

When running as service, you won't have the startup script.
Execute some service implementation that allows running other programs as services, and then make the new service (which is running your script) a dependency of the Apache service. However, this will not restart the script when apache restarts.
One possible solution using SrvStart, and another using ServiceEx.
Perhaps don't install Apache as a service, and then edit the startup/restart script, and use the above method to run Apache as service (instead of using Apache's own installer).

Create bat file,e eg 'myphp.bat' containing path/php myscript.php. Include the correct path to php if it's not path'd.
create a bat file, eg runmyphp.bat containing
AT 00:00 /every:M,T,W,Th,F "cmd /c /path/myphp.bat", again including the correct path.
Then use explorer to drag runmyphp into the startup folder, so it will always run on system startup.
Google 'windows at command' or 'windows cron' to get all the correct syntax for the 'at' command, but you can currently find a detailed explanation here.

I found another answer C:\wamp\scripts\wampserver.lib.php this file is run every time when your wamp starts
include your file path include_once("file_path"); to this file and its done . this is perfect solution which you want
Enjoy!!!!!!!!!

Although the solution of Halayem Anis is very creative, I think its important to note that you can never be sure that a PHP script keeps running in the background. So if you choose to start your script on "Apache start", then you probably end op resetting Apache quite often, simple to reboot your script.
I assume that's even how you came to this question, as on a normal server you never have to touch the Apache reset button. It starts on system start and then it just runs. If that was the case, you could simple run your php myscript.php command on start up.
Considering there is no way to make sure the script keeps running, I would use a different approach, where I check if it is running and if not, restart it.
So the first step is to make it possible to track if the script is running. I would go for the simple approach where your myscript.php writes a single byte to a file every 5seconds or so. This way I can use the last modified time on the file to see if it is still running, because last modified time + 5 seconds < now == not running.
You could also store the last access time in a database every 5 seconds or so. Might be slightly faster then accessing files if you have a lot of traffic.
The second part is to have each request check if the script is running. For this two work I would use the PHP.ini to prepend a php script on every request. You can do it with the auto_append_file option.
This prepend script would work like this:
<?php
$filename = 'checkonline.txt';
$cmd = "php myscript.php";
if (filemtime($filename)+5<time()) {
//run in background without freezing php
//based on code posted on PHP exec manual, linked below
if (substr(php_uname(), 0, 7) == "Windows"){
pclose(popen("start /B ". $cmd, "r"));
}
else {
exec($cmd . " > /dev/null &");
}
}
?>
Make sure to check how filemtime and exec work and what you need to keep in mind. They work slightly different on Windows/*nix.

Wrap-up all your required processes in a batch file and use RunAsService
With some tweaking, you can ensure that your service starts before Apache.

Related

PHP on Windows - check if working in background

I have Windows 10 with xampp installed.
Let's assume I have a PHP script, containing
set_time_limit(0);
ignore_user_abort(true);
$counter = 0;
while($counter < 60){
file_put_contents('runtime_log.txt', $counter." \r\n", FILE_APPEND);
$counter++;
sleep(1);
}
I can close the browser window and the script will be still writing output to runtime_log.txt
If I wanted to check if it's running in the background on Linux, I would use
ps aux | grep php
How to do the same thing on Windows?
EDIT: I have simplified my question, because I can see that it's been misunderstood.
You can't get that information directly from the process list in Windows, because by default Apache is configured to load PHP as a module (a .DLL) so it will not be listed as a different process when it's running (unless PHP is configured to run as CGI, but nowadays that option is not used anymore).
I think that you can search for that using Process explorer, open it and then search (with the binoculars icon) for opened handles for runtime_log.txt, if the file is opened by PHP an open handle should appear for the httpd (Apache) process (this is method I use for finding the program that prevents me from deleting a file).
Note that you probably need to run Process Explorer elevated (as an administrator) since Apache is running as system service.
Don't put too much effort, just use the constant PHP_OS as also described here: How to get the OS on which PHP is running?

Set up Eclipse PDT with PHP's built-in server

I'm yet a newbie to PHP development, so far I used NetBeans for the job. Unfortunately NetBeans is not the best IDE, and it is unreasonably slow on my Mac.
I'd like to use Eclipse PDT for PHP, as I know and like Eclipse a lot better (I'm coming from Java).
But I cannot set up a server in Eclipse... All docs and topics just showed ppl saving files in the htdocs folder of an external server (such as MAMP or XAMPP). As I don't need a database, I just want to use PHP's built-in server instead of installing and running a heawyweight app in vain.
I'd like to reproduce the only really good thing in NetBeans: I just click on the Run button, and I see the result in the Browser immediately.
How do you set that up?
Even if I am a bit late to help you, I want to write down my solution, cause I've faced the same problem today.
I think the only chance is to start the php built-in webserver manually. Open a terminal in the desired root directory and start the webserver with
php -S localhost:8000
Then you can add a new server with Base URL: http://localhost:8000 and the choosen document root and you'll have the same functionality like in Netbeans.
Put together this hackety-hack-hack to make this work (even works with xdebug remote debugging if you set it up!!!).
UPDATE: one caveat with this solution is when you terminate the running CLI in Eclipse, it's terminating the wrapper script, not the php server directly. I've added some trapping and forawding of signals to child (php server) process. Works in OSX.
Overview:
I'm running Eclipse Neon
Need a router file in document root you wish to serve from (see this: http://php.net/manual/en/features.commandline.webserver.php)
Create a wrapper bash script to call PHP in server mode and pass in details
Set script to have executable permissions
Add this bash script as a PHP executable
For the project, create a run configuration as PHP CLI, using this new executable, passing the router file in.
Here's the bash script php5.6-server:
#!/bin/bash
_sigterm() {
echo "Caught SIGTERM signal!"
kill -2 "$child"
}
_sigint() {
echo "Caught SIGINT signal!"
kill -14 "$child"
}
if [ $1 = "-v" ]; then
#This is needed for when eclipse trys to detect php version
/path/to/php -v
else
trap _sigterm SIGTERM
trap _sigint SIGINT
# This is why your router file needs to be in the doc root
ROUTER=${#: -1}
DIR=$(dirname $ROUTER)
/path/to/php -S localhost:8000 -t $DIR $ROUTER
child=$!
wait "$child"
fi
Here's a simple router.php just to get it working:
<?php
// router.php
if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) {
return false; // serve the requested resource as-is.
} else {
echo "<p>Welcome to PHP</p>";
}
Now in Eclipse go to Eclipse->Preferences->PHP->PHP Executables and add a new server:
And that should be it. Now create a PHP CLI Run configurations using the wrapper executable as 'Alternate PHP' and for the php file specify the route file:
Then Run as CLI!!! A PHP server should now be listening on port 8000 on your localhost. I suspect this method may also work for HHVM's Proxygen server.

PHP - Can't open .exe files with exec command

I work with PHP 5.4, IIS 7.5.
If execute a simple command, it works:
<?php
exec("dir", $r);
print_r($r);
?>
But if open .exe file, it doesn't work, the page is loading until the php timeout and doesn't open the notepad:
<?php
exec("notepad.exe", $r);
print_r($r);
?>
And if execute the notepad's php in command line, it works:
php -f <file>
I think that the problem is with IIS, but I don't know what. Thanks!
UPDATE
I did another test case and doesn't work, the page finishes loading but doesn't delete the task:
<?php
$r = exec("SCHTASKS.exe /Delete /TN TaskTest /F");
print_r($r);
?>
The IIS_IUSRS have permission for execute the schtasks.
SOLUTION
Notepad doesn't open because is a interactive program.
For Tasks scheduler, gives read and write permissions to the task folder (C:\Windows\System32\Tasks) to IUSR.
What makes you think it isn't working?
Be aware that windows services cannot normally interact with the desktop, so it may be the case that notepad is starting, just not anywhere you can see it - and as PHP will wait for it to terminate, and nobody can see it to terminate it, it'll timeout, as you're seeing.
It may also be the case that the user that the web server is running as does not have execute permissions on the folder that notepad is in (assuming it had the relevant path).
The problem is that you are instructing exec to gather and return the output of the spawned process and the process must terminate for this to happen. Since Notepad does not terminate immediately PHP is stuck waiting forever (you can test this by running any non-interactive process instead, for example net.exe).
Takeaway: exec and friends are not meant to launch interactive processes.
In any case, exec will spawn a command interpreter which in turn will spawn Notepad. However, due to security features introduced in recent Windows versions, and depending on the user that IIS is running as, these processes will not create visible windows on your current desktop so there will be nothing for you to see. You will be able to verify that they were spawned using Task Manager or another equivalent program.

How can I launch a local Application on OSX from php running MAMP?

I'm running a bunch of local Kiosks on mac mini's and have been using dropbox to keep all the files in sync. However - the dropbox updates have been sketchy as of late because of the firewall settings where these things are. A workaround I have found is by having dropbox quit and restart periodically to force it to update.
My question is - since all of these are running php applications on MAMP - is there a way to launch a local app from php? I'm able to kill dropbox by doing something like this:
$killit = killall -KILL Dropbox;
But it doesn't work the same to restart it. I've tried doing this:
$start_dbox = open /Applications/Dropbox.app;
To no avail. Is there a better way to automate this process of shutting down and reopening a local application?
I've had similar problems trying to control software remotely. The 'open' command must be executed either as the currently logged in console user, or from a terminal owned by the console (e.g. Terminal.app).
If you change your PHP to redirect STDERR, you should see the error that 'open' is returning:
$start_dbox = "open /Applications/Dropbox.app 2>&1";
The following text should then be returned from the system call:
LSOpenURLsWithRole() failed with error -10810 for the file /Applications/Dropbox.app.
One workaround I've used in the past is to create a lock file somewhere in the filesystem, which your PHP script can write to and your console user can read. Then, you can create a cron that runs as the console user and periodically checks the lock file to see if it needs to restart Dropbox.
I was actually able to solve this by creating a shell script with the following:
#!/bin/sh
export DYLD_LIBRARY_PATH=""
osascript -e 'tell application "Dropbox" to activate'
Saved it as start_db.sh and dropped it in my root apache directory (so there was no permissions problem for that user).
Then in my php file I was able to do:
$start_dbox = exec('/full/path/to/start_db.sh');
Worked like a charm. Dropbox now quits and restarts with no issues.

PHP from commandline starts gui programs but apache doesn't

First, I read some threads by people with similar problems but all answers didn't go beyond export DISPLAY=:0.0 and xauth cookies. So here is my problem and thanks in advance for your time!
I have developed a little library which renders shelves using OpenGL and GLSL.
Last few days I wrapped it in a php extension and surprisingly easy it works now.
But the problem is it works only when I execute the php script using the extension from commandline
$php r100.php(i successfuly run this from the http user). The script is in the webroot of apache and if I request it from the browser I get ** CRITICAL **: Unable to open display in apache's error_log.
So, to make things easier to test and to be sure that the problem is not in the library/extension, at the moment I just want to start xmms with following php script.
<?php
echo shell_exec("xmms");
?>
It works only from the shell too.
I've played with apache configuration so much now that I really dont know what to try.
I tried $xhost + && export DISPLAY=:0.0
In the http.conf I have these
SetEnv DISPLAY :0.0 SetEnv XAUTHORITY /home/OpenGL/.Xauthority
So my problem seems to be this:
How can I make apache execute php script with all privileges that the http user has, including the environment?
Additional information:
HTTP is in video and users groups and has a login shell(bash).
I can login as http and execute scripts with no problem and can run GUI programs which show up on display 0.
It seems that apache does not provide the appropriate environment for the script.
I read about some difference between CLI/CGI but cant run xmms with php-cgi too...
Any ideas for additional configuration?
Regards
Sounds bit hazard, but basically you can add even export DISPLAY=:0.0 to apache start-up script (like in Linux /etc/init.d/httpd or apache depending distro).
And "xhost +" need to be run on account which is connected to local X server as user, though I'm only wondering how it will work as php script should only live while apache http request is on-going.
Edit:
Is this is kind of application launcher?, you can spawn this with exec("nohub /usr/bin/php script.php &"); .. now apache should be released and php should continue working in background.
In your console, allow everyone to use the X server:
xhost +
In your PHP script, set the DISPLAY variable while executing the commands:
DISPLAY=:0 glxgears 2>&1

Categories