Run PHP script in background on Apache start/restart(Windows Server)
Asked Answered
C

8

7

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.

Cinque answered 5/2, 2013 at 23:24 Comment(5)
what do you mean by running in the background? A cron? Auto prepended?Einhorn
Well the script ment to run 24/7 and should be listening incoming requests. So at system reset it should auto start just like I would type in 'php myscript.php' in the console and leave the console open.Cinque
There is no reliable way to keep a php script running 24/7. How are the incoming request generated? What do they do?Einhorn
The script is websocket server like this one: github.com/GulDmitry/php-websocket-server.Cinque
Just needed a way to refresh some browsers in case some event occurs on another. App is working localy on a few machines only and this is the solution I came up with. Might not be the best practice :P What would you suggest then?Cinque
M
13

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

    Maddox answered 21/1, 2015 at 22:24 Comment(2)
    A very creating solution :)Testimonial
    It's clever, but also a hack that has to be reimplemented any time the Apache binary is updated.Knap
    A
    2

    Use built in Windows Task Scheduler which triggers .bat script, which calls curl with defined url.

    1. Download curl from http://curl.haxx.se/download.html and extract curl.exe on any directory, but we will use c:\backgroundtasks
    2. Adjust script below to your needs:

      cd c:\

      cd c:\backgroundtasks

      curl http://localhost/path/to/script.php

      exit

    3. 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
    Accursed answered 22/1, 2015 at 17:38 Comment(0)
    K
    2

    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.

    Knap answered 27/1, 2015 at 18:19 Comment(0)
    B
    1

    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).

    Bronson answered 6/2, 2013 at 8:7 Comment(0)
    P
    1

    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.

    Pleiad answered 23/1, 2015 at 6:44 Comment(0)
    S
    1

    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!!!!!!!!!

    Selfannihilation answered 23/1, 2015 at 13:46 Comment(2)
    That only works because wamp uses it's own manager: wampmanager.tpl. If you use WAMP, you could just as well alter the wampmanager.ini and alter the [StartupAction] section.Lemnos
    @HugoDelsing yes sir First I thought to use cron job but it is not perfect solution , I found this way and I don't think any other way is more easier then thisSelfannihilation
    L
    1

    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.

    Lemnos answered 27/1, 2015 at 9:6 Comment(0)
    E
    0

    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.

    Eyepiece answered 26/1, 2015 at 3:44 Comment(0)

    © 2022 - 2024 — McMap. All rights reserved.