Run PHP Script as Daemon Process

Run php script as daemon process

You could start your php script from the command line (i.e. bash) by using

nohup php myscript.php &

the & puts your process in the background.

Edit:

Yes, there are some drawbacks, but not possible to control? That's just wrong.

A simple kill processid will stop it. And it's still the best and simplest solution.

What's the best way to keep a PHP script running as a daemon?

If you can't use the (proper) init structure to do this (you're on shared hosting, etc.), use cron to run a script (it can be written in whatever language you like) every few minutes that checks to see if they're running, and restarts them if necessary.

Running a PHP Script as a Daemon in Debian

The issue was in the redirection of the output. I also modified the php file with a header for bash so it does not show as multiple php processes in top, but shows the file name instead:

Revised Service Script:

#! /bin/sh

### BEGIN INIT INFO
# Provides: congen-insert
# Required-Start: $local_fs $network
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: congen-insert
# Description: ConGen DB Insert Daemon
### END INIT INFO

NAME="congen-insert"
DESC="DB Insert Process for ConGen"
PIDFILE="/var/run/${NAME}.pid"
LOGFILE="/var/log/${NAME}.log"

DAEMON="/var/congen/php/controllers/congen-insert"
DAEMON_OPTS="> /dev/null 2>&1"

START_OPTS="--start --background --make-pidfile --pidfile ${PIDFILE} --exec ${DAEMON} ${DAEMON_OPTS}"
STOP_OPTS="--stop --pidfile ${PIDFILE}"

test -x $DAEMON || exit 0

set -e

case "$1" in
start)
echo -n "Starting ${DESC}: "
start-stop-daemon $START_OPTS >> $LOGFILE
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon $STOP_OPTS
echo "$NAME."
rm -f $PIDFILE
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon $STOP_OPTS
sleep 1
start-stop-daemon $START_OPTS >> $LOGFILE
echo "$NAME."
;;
status)
echo -n "Sorry, this isn't implemented yet"
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac

exit 0

Revised PHP Script to run:

#!/php52/php-5.6.6/bin/php
<?php
const LoaderPath = __DIR__ . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . "includes.php";

require_once LoaderPath;

use PhpAmqpLib\Channel\AMQPChannel;
use PhpAmqpLib\Message\AMQPMessage;
use requests\InsertRequest;

$connection = GetRabbitConnection();

$channel = $connection->channel();

$RedisClient = GetRedisClient();

DeclareQueues($connection, $RedisClient);

$InsertExchange = $RedisClient->get(Insert.":".Exchange);
$InsertQueue = $RedisClient->get(Insert.":".Queue);
$Prefetch = $RedisClient->get(Insert.":".Prefetch);

$RedisClient->disconnect();
$RedisClient = null;

$mysql= ConnectionBuilder::GetMySQLi();

$channel->basic_qos(0,$Prefetch,false);

$channel->basic_consume($InsertQueue, $InsertExchange, false, false, false, false, "callback");


echo "Consuming on Exchange $InsertExchange with Queue $InsertQueue\n";

while(true) {
$channel->wait();
}

$channel->close();

function callback(AMQPMessage $message){
global $mysql;
echo "Message received", "\n";
$InsertRequest = new InsertRequest($message->body);

echo "Running Insert Statement\n";
if (!$mysql->query($InsertRequest->SQL)){
echo "Error: ".$mysql->error;
}

/** @type AMQPChannel $channel */
$channel = $message->delivery_info['channel'];
$channel->basic_ack($message->delivery_info['delivery_tag']);
echo "Insert Complete\n";

}

After adding the file to /etc/init.d/ and making both the php script and service script executable, I can start the service using service congen-insert start and use the rest of the commands just like any other init.d service.

It should be noted that I am redirecting the console to /dev/null, but you could also redirect to a file by replacing the /dev/null with a writable path.

An explanation of the 2>&1 quoted from another SO post "2 is the stream number for stderr (error messages), 1 is represents [sic] the stdout stream (the standard non-error output stream)." as such I am essentially redirecting stdout to /dev/null and redirecting stderr to stdout

running a php script as a daemon

Use this:

ignore_user_abort(true);

So if the user closes the window, PHP script continues to run until it finishes.

More information Here

Starting a daemon from PHP

Try appending > /dev/null 2>&1 & to the command.

So this:

exec("sudo /etc/init.d/daemonToStart > /dev/null 2>&1 &");

Just in case you want to know what it does/why:

  • > /dev/null - redirect STDOUT to /dev/null (blackhole it, in other words)
  • 2>&1 - redirect STDERR to STDOUT (blackhole it as well)
  • & detach process and run in the background

How do I start a php server in the background as a daemon in a docker container

Docker is neither an init system nor does it run traditional init systems without some hacks. The first process you run in the Docker container will be PID 1. This could be a supervisor (like supervisord, s6, dumb-init).

However, more generally, you can just run the process you want and handle running in the foreground or background with options to the docker run command. In this example your Docker command (or CMD in the Dockerfile) can just be php -f /var/www/callcenter/livesite/bin/startwebsocketserver.php. Then, run your container with the -d option and it will run in the background. You can attach to it with docker attach or just watch the output with docker logs.

If you actually need to use some sort of process supervisor (such as, when you need to have multiple processes running in the container), then I'd start looking to Docker init options out there. I mentioned a couple and there are more. Upstart won't work inside a container.

Start a PHP daemon from a web interface

It's very unlikely they could do it successfully because you'd probably need admin permission to start a daemon on Linux.

You'd have to use exec() or shell_exec() to try and run the command from PHP. I don't have a lot of experience of that but I think php exec command (or similar) to not wait for result will help you because clearly you'll want to fire and forget.

Your main problem will be though that you won't be able to detect if the program fails, or if it needs restarting for any reason. (And that's assuming the host even lets you execute it to begin with).

The bottom line is, really, if you want to run your own processes, don't use cheap shared hosting, use a proper environment.



Related Topics



Leave a reply



Submit