I have a PHP script I am hoping to run as a daemon. I can easily do this from linux CLI. Is there any way I could get my daemon running using a browser though? Like some way to 'fork it off' ?

    It had occurred to me to try and use those, but I was concerned that the browser connection would time out waiting for system/exec/passthru to return. Since I'm running a daemon, I expect it to run for a pretty long time (i.e., hours).

      Well all you'd have to do is start the demon, right? That shouldn't take more than a few seconds, tops.

      Something like system("/etc/init.d/service start"); ought to work functionally. Unless it's something you need to get output from... can you give me any more information on the demon you're starting, or what it needs to do?

        I have written a socket server in PHP which I hope to use as a multiplayer game hub. I'm trying really hard to make it easy to set up and am expecting that a lot of potential users won't have CLI access to their host machine.

        So basically, I have a PHP script that doesn't halt until you send it a socket command which instructs it to halt or you forcibly halt it with CTRL-C from CLI.

        I've been thinking about this a bit and am thinking that simply visiting the script in a browser won't work. Or would it? I could set [man]ignore_user_abort[/man] and visit the script and maybe echo some sort of meta redirect or something?

        That sounds really sloppy though you know? I was hoping for a more 'official' kind of thing.

        the /etc/init.d/service start sounds promising but I don't expect I'll always have access to those kind of priveleges on every machine.

        I appreciate your input, btw!

          Perhaps you could do something of this nature?

          startserver.php

          <?PHP
          // put in same directory as shell script to start your flash-php socket server
          system("./flashserver-start");
          // possible check here for return value from shell script after checking process list
          // something like:
          
          if (system("./flashserver-start") == 'success') {
             echo 'Forked flash-php daemon successfully, process started at '.date("H:i:s");
          }
          else {
             echo 'There was an error starting flash-php daemon';
          }
          
          ?>
          

          flashserver-start

          #whatever CLI command you run here to start your process normally:
          #
          # you could also have it check the status of the server using ps
          # and return a value here, that gets passed to PHP start script for error-checking
          if ps -C server-process-command-name 
             echo 'success';
          else 
             echo 'fail';
          fi
          # warning: i've never done if/else structures in shell scripts before,
          # so that's probably not functional.
          

          endserver.php

          system("killall [name of your daemon process here]");
          

          I don't know what CLI command you run to start your server, but put that in the flashserver-start file (I'm guessing it's something like php flashserver.php) but whatever command you run from CLI, just put it in the shell script, chmod +x it, and I think that should work fairly well.

          No hangup cause all your script does is call the shell script that starts the daemon, then another script kills it.

          Edit: I think this would be best - it also solves the problem of the server closing all connections if the initial page that opened it closes, solves timeout/hangup issues, and allows you to still send either the kill command by socket or to forcibly interrupt it from externally. You could put links in a control file:

          <a href="startserver.php">PHP Page that system calls the shell script to start your flash/php socket server</a>.<br />
          <a href="force-kill.php">PHP Page that system calls a killall in the event of system hangup.</a>.
          

          Edit: I cleaned up the code a bit and added the ps/error-checking stuff... you could clean it up a bit more with some research into ps/shell-scripting, I just don't know enough shell scripts to do it efficiently. You could do a command line php script that would do it similarly, though. Either way, PHP or shell scripting, you could have a script check if the daemon is running, if not, start it. if it starts, return success, else fail and report message. then the kill script can check if it's running, if yes, kill, if not, report message.

          Hope that helped. 😃

            Starting / stopping a daemon should be possible, provided your web application is running as the same user as you intend to run the daemon.

            Personally, I'd go for a conventional daemon started from the command line (or by the system at boot time). It just sounds more sound.

            If you do fork off a process from PHP, make doubly sure that you don't end up with more than one instance of this daemon running at once (Hint: Using file locking to ensure this is pretty good).

            Mark

              He would do a conventional daemon start but as he said, it's an app he's trying to distribute and a lot of his target users aren't going to have access to ssh/configuration access of that level. It's a php script that opens sockets, targetted for games/chats, mainly. I think the way I've got set up at the moment will be best, once we clean it up a bit and tie it into a shell script a bit better. It'll provide a rudimentary administration page, too.

                MarkR: I don't really have the slightest clue about how to fork off a process. My intuition tells me that this socket server would perform much better if it were multithreaded, but the ol' intuition is kind of a backseat driver--it doesn't know how to do that.

                Horizon...I'm working on your recommendations now. THX!

                  Awesome. Let me know how it goes. Particularly if you try out the error-checking and such with ps, I think that's a good idea.

                    Hmm....this isn't working. It's doing exactly the same thing as if I were to try and call system/exec/passthru directly on my_server.php directly.

                    This script for instance, never echoes success or failure because my script (being a daemon and therefore looping infinitely or sleeping) NEVER RETURNS. It launches the server just fine but because the server doesn't 'finish' neither does this script.

                    #attempt to start the flashmog_server
                    ./flashmog_server.php
                    
                    # you could also have it check the status of the server using ps
                    # and return a value here, that gets passed to PHP start script for error-checking
                    if ps -C 'flashmog_server'
                       echo 'success';
                    else
                       echo 'fail';
                    fi
                    

                    On the other hand, I can close all my browser windows and the server is still running 😕

                    I'm not sure how I feel about this...the call to launch the server 'blocks' until the server is 'finished'. What do I do with that? Should the server-launching script output some kind of meta tag that moves to a different file? Perhaps this other file could try and connect via socket to the server just to check and see if it's running? Something feels vaguely kludgey about all this.

                    Thoughts?

                    UPDATE: After closing all my browser windows, the socket server responded for a few seconds closed shortly after, abandoning whatever clients were connected. That won't work!

                      EDIT: Better solution.

                      When you run the command to start the server, use

                      ./server.php &
                      

                      The ampersand will tell it to kick it to the background, but it still runs and everything. Then it can still be checked on with ps -C and sent a kill sig based on the PID or the process name in the event of a failure. That should work, I'm testing it out now with a server that just sleep(100000);'s 😃

                        New post cause I think I solved it!!

                        I found some info on if/else structures, as well as checking if a service is running, here:
                        http://www.anyexample.com/linux_bsd/bash/check_if_program_is_running_with_bash_shell_script.xml

                        I've got a test server set up. Check this out.

                        Files: server_start.sh and server.php

                        server.php

                        <?PHP
                        sleep(10000);
                        ?>
                        

                        server_start.sh

                        ## attempt to start the server
                        SERVICE='server.php'
                        ./server.php & > /dev/null
                        
                        ## check if it is running
                        if ps ax | grep -v grep | grep $SERVICE > /dev/null
                        then
                           echo "$SERVICE daemon has been started successfully."
                        else
                           echo "$SERVICE daemon failed to start."
                        fi
                        

                        Here's a screen of me running it:

                        🆒

                          Ok so I adapted your scripting technique to start the daemon:

                          ## attempts to start the server
                          SERVICE_PROCESS='flashmog_server'
                          
                          
                          ## check if it is running
                          if ps ax | grep -v grep | grep $SERVICE_PROCESS > /dev/null
                          then
                            echo "$SERVICE_PROCESS daemon is already running."
                          else
                          
                            ## launch the server
                            ../flashmog_server.php & > /dev/null
                          
                            ## check if it running now
                            if ps ax | grep -v grep | grep $SERVICE_PROCESS > /dev/null
                            then
                              echo "$SERVICE_PROCESS daemon launched successfully."
                             else
                              echo "$SERVICE_PROCESS daemon failed to start."
                            fi
                          fi
                          

                          It does launch the server successfully but all output from the server is still routed to stdout. If I run the script from the command line, output from the server script appears in my terminal window despite the '> /dev/null' part. I'm guessing that's supposed to route output to 'null' - meaning throw it away.

                          I thought this was still workable because the success/failure messages do appear immediately rather then when the daemon finishes (which is never) so I created a php file to call start_server.sh like so:

                          <?php
                          // put in same directory as shell script to start your flash-php socket server
                          system("./start_server.sh");
                          echo 'shell script complete';
                          ?>
                          

                          When I access this file in a browser, the server starts, i see the 'success' message in the browser - but i also get all the output from the server itself. More importantly, the browser has the hourglass icon on my mouse - meaning that php script is still running and there's still an output stream connection between my browser and apache. Most importantly of all, if I close all my browser windows the server will halt shortly after.

                          We're close, but not finished 🙁

                          I hope to get my server source up this weekend...it'll be GPL...site in progress here:
                          http://jaith.net/flashmog

                            Yeah, I'm playing with it right now too on my test machine. I know what you mean about it hanging in the browser, but for some reason when you run the exact command from bash it doesn't hang, but in PHP system() or exec() it does hang it for some reason. I don't get it. Playing with it now though.

                              gah.

                              This is so weird - no matter which system call i use from php, even if I throw in the & to kick the process to the background, PHP still hangs on it waiting for output, whether I call the scripts directly or not. I don't get it. :/ Working on it, will update with progress. :\

                                EDIT: I got it!

                                <?PHP
                                $serviceName = 'flashmog_server.php';
                                
                                // check if the server is running
                                $check = "ps ax | grep -v grep | grep $serviceName";
                                $runCheck = system($check);
                                
                                if (!empty($runCheck)) {
                                   // server is running
                                   echo $serviceName.' is already running.';
                                }
                                else {
                                   // server not running, start
                                   $start = "(php ".$serviceName." &) > /dev/null";
                                   system($start);
                                
                                   // check that it started
                                   $startCheck = system($check);
                                   if (!empty($startCheck)) {
                                      echo $serviceName.' was started successfully.';
                                   }
                                   else {
                                      echo $serviceName.' did not start.';
                                   }
                                }
                                ?>
                                

                                The only problem I can find with it right now is that if you call it without killing the server first if it's already running, it outputs this:
                                25434 ? S 0:00 php flashmog_server.php flashmog_server.php is already running.

                                I'm guessing that's because I don't set a retval in system on the first check, but I dunno. But this code works to start the server, and to check if the server is already running. 😃

                                Edit: I set return values on all my system calls and it still outputs the results of that first grep check for some reason, no idea why. :\

                                  ok i been tinkering with this a bit. you obviously found the 'Can't use function return value in write context' error when trying to run system in an if clause.

                                  btw, system() echoes all the results regardless of whether you set a return value or whatever. try [man]shell_exec/man instead.

                                  I am able to launch the process and it seems to survive closing all the browser windows. I'm using this script:

                                  <?php
                                  error_reporting(E_ALL);
                                  $service_name = 'flashmog_server.php';
                                  $server_path = '/www/html/flashmog/' . $service_name;
                                  
                                  // check if the server is running
                                  $check = 'ps ax | grep -v grep | grep ' . $service_name;
                                  $check_result = shell_exec($check);
                                  echo 'initial check result:' . $check_result . '<br>';
                                  
                                  if (!empty($check_result)) {
                                    // server is running
                                    echo $service_name . ' is already running.';
                                  } else {
                                    // server not running, start
                                    $start = "(php " . $server_path . " &) > /dev/null";
                                    system($start);
                                    // check that it started
                                    $check_result = shell_exec($check);
                                    echo 'post-launch check result:' . $check_result . '<br>';
                                    if (!empty($check_result)) {
                                      echo $service_name . ' was started successfully.';
                                    }
                                    else {
                                      echo $service_name . ' did not start.';
                                    }
                                  }
                                  ?>
                                  

                                  I wrote a little script to check if it's running (and hopefully report more than one instance?):

                                  <?
                                  $service_name = 'flashmog_server.php';
                                  $check = 'ps ax | grep -v grep | grep ' . $service_name;
                                  passthru($check);
                                  ?>
                                  

                                  It returns this:

                                  13092 ? S 0:00 php /www/html/flashmog/flashmog_server.php
                                  

                                  I also wrote a script to do a ps:

                                  <?
                                  $result = shell_exec('ps');
                                  echo nl2br($result);
                                  ?>
                                  

                                  Interestingly, the ps lists flashmog_server as 'php' rather than 'flashmog_server':

                                  PID TTY TIME CMD
                                  19728 ? 00:00:07 apache2
                                  19729 ? 00:00:13 apache2
                                  19730 ? 00:00:11 apache2
                                  19731 ? 00:00:06 apache2
                                  19732 ? 00:00:10 apache2
                                  20497 ? 00:00:02 apache2
                                  21390 ? 00:00:13 apache2
                                  8930 ? 00:00:00 apache2
                                  8931 ? 00:00:00 apache2
                                  8932 ? 00:00:00 apache2
                                  13092 ? 00:00:00 php
                                  13174 ? 00:00:00 ps
                                  

                                  There are two problems I'm having really. The first is with the launcher script checking for the daemon so quickly. If for some reason I specify the wrong script path or there is a syntax error in the server, the check will still return true because PHP is running at the time of the check however the server will end as soon as php figures out the fatal error. I considered sleeping between the launch and the check but it seems more exact to get a success/failure result from the attempt at executing the file.

                                  The second problem I'm having is terminating the process. As I pointed out with my ps.php script, the process executing is listed as php rather than flashmog_server so end_server.php doesn't seem to work:

                                  <?
                                  error_reporting(E_ALL);
                                  $service_name = 'flashmog_server.php';
                                  
                                  system('killall ' . $service_name);
                                  
                                  // check if the server is running
                                  $check = 'ps ax | grep -v grep | grep ' . $service_name;
                                  $check_result = shell_exec($check);
                                  echo 'check result:' . $check_result . '<br>';
                                  if (!empty($check_result)) {
                                    // server is running
                                    echo 'Server end failed. ' . $service_name.' is still running.';
                                  } else {
                                    echo 'Success.  No instances of ' . $service_name . ' are running.';
                                  }
                                  ?>
                                  

                                  the result:

                                  check result:13092 ? S 0:00 php /www/html/flashmog/flashmog_server.php
                                  Server end failed. flashmog_server.php is still running.

                                  Yet another consideration seems to be the possibility of running more than one instance of this daemon on a given server. I suspect that each user running the process will not have visibility to any other user's instance, but if a single user wanted to run more than one game, we would need to be able to start/kill each one independently and would somehow need to track them separately in order to start/end.

                                  my check.php script appears to return the process id of whatever instances it finds running, so i think we might be able to kill the process using 'kill -9 13092' or something. It would be nice if a given project could track the PID of the server from the time it launches and when end_server needs to be called, it would somehow know where to look for the pid.

                                  Thoughts?

                                    my check.php script appears to return the process id of whatever instances it finds running, so i think we might be able to kill the process using 'kill -9 13092' or something. It would be nice if a given project could track the PID of the server from the time it launches and when end_server needs to be called, it would somehow know where to look for the pid.

                                    I thought about this earlier, but didn't get to coding it. My roommate made me watch Resident Evil Apocalypse with her. :/

                                    Anyways, the way you can do this is system() the grep command to see which one is running and grab the PID from the output of that. The PID is the first number that gets returned, but I can't say for sure if it will always be a 5-digit number, so what you'd want to do is use explode() by the space character, and the first bit returned would be the PID. You could use that immediately after starting the server, set it in a session, and use that session info to force kill it later, and also to keep track of multiple instances.

                                    That oughta work.