2

I want to run following code in Background at certain occurrence:

File A :

// ------------------- Some Code Before Following -----------------------

// send notification to given device token
$notification = new Notification();                    
$notification->sendNotification($token,$count);

// ------------------- Some Code After Above ------------------------

This will called following class :

// Here I am sending notification to given device token (APNS Push Notification) 
<?php

class Notification
{
    public function sendNotification($token,$count)
    {
        if(strlen($token)%16 == 0)
        {
            // set Device token
            $deviceToken = $token;
            $passphrase = 'xxxxx';
            $badge = $count;

            // Displays alert message here:
            $message = 'Hello! There.';

            $ctx = stream_context_create();
            stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
            stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

            // Open a connection to the APNS server
            $fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err,$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
            if (!$fp)
                exit("Failed to connect: $err $errstr" . PHP_EOL);

            echo("Connected to APNS.");

            // Create the payload body
            $body['aps'] = array(
                                 'alert' => $message,
                                 'badge' => $badge,
                                 'sound' => 'default'
                                 );

            // Encode the payload as JSON
            $payload = json_encode($body);

            // Build the binary notification
            $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

            // Send it to the server
            $result = fwrite($fp, $msg, strlen($msg));

            if (!$result)
                echo("\n\nMessage not delivered.\n\n");
            else
                echo("\n\nMessage successfully delivered.\n\n");

            // Close the connection to the server
            fclose($fp);
        }
    }
}


?>

When Execution of this class will be completed then it will go back to file A and it will continue execution after sending notification.

But here it will take time to send notification (around 3-5-7 seconds) and for that time user has to wait which is not a good idea.

So what I want to do is that send notification in Background process instead of main thread.So user don't has to wait unnecessarily.

Please note that I don't want to use Cron.

I found that exec/shell_exec/passthru command can help me. But which command I used out of these three commands in this case?

Please Guide me on this. Any help will be appreciated.

Ponting
  • 2,248
  • 8
  • 33
  • 61

3 Answers3

5
passthru("/usr/bin/php /path/to/yourFile.php >> /path/to/log_file.log 2>&1 &");

There are a few thing that are important here.

First of all: put the full path to the php binary, because this command will run under the apache user, and you will probably not have command alias like php set in that user.

Seccond: Note 2 things at the end of the command string: the 2>&1 and the &. The 2>&1 is for redirecting errors to the standard IO. And the most important thing is the & at the end of the command string, which tells the terminal not to wait for a response.

tomrozb
  • 25,773
  • 31
  • 101
  • 122
  • Thanks. But What do you mean by passthru ? Do you want to write exec()? – Ponting Sep 04 '13 at 07:53
  • passthru() is a PHP function but it's raison d'etre is to return binary data from the command, hence nothing appropiate for your usecase. – Clarence Sep 04 '13 at 08:21
  • @Clarence : And Why I can't use exec()? Because I saw that passthru is used only when o/p is binary data.Is it right? – Ponting Sep 04 '13 at 08:39
  • @Clarence : Please answer my question as soon as possible.Because I need it urgently.Thanks. – Ponting Sep 04 '13 at 10:19
  • 1
    You could use exec() with a & at the end to run the command in background as well. You would have no control over how many processes are spawned though. – Clarence Sep 04 '13 at 17:48
  • Ok,Thank you. If I don't want to print output to log_file then? I know dev/null can help me.But I don't know correct syntax or structure. – Ponting Sep 06 '13 at 08:43
0

There are a few options here:

  • You can fork a separate PHP process with pcntl_fork (http://php.net/manual/en/function.pcntl-fork.php)
  • You can use a cronjob to check for unsent modifications which you do not want to (you failed to mention WHY, this is why I mention it)
  • You can use a job queue system for it. By far the best solution but takes some time to get started. Gearman is the one I have experience with and that works like a charm.
Clarence
  • 2,944
  • 18
  • 16
  • I don't want to use Cron because I wanted to send notification instantly without waiting. – Ponting Sep 04 '13 at 07:40
  • See, there's the problem. You do not want to use a cronjob because you don't know how to make that work for your demands. Your goals can easily be solved by creating a cronjob that sleeps for X seconds/millseconds between each check for a new message and then get's killed before the next cronjob starts the script. One could argue a daemon would be better then, but that usually comes with alot of extra pitfalls and is for your usecase as complicated as setting up a proper job queue, just less stable and extendable. – Clarence Sep 04 '13 at 08:25
  • See,In my Application(iOS) I am finding new matches(from database) for current user on certain occurrence and want to send notification instantly to that new matches. So If I will use Cron(If Cron will run after every 5 minutes) then I will have to wait for 5 minutes to send notification.It is not feasible for the criteria of the application. – Ponting Sep 04 '13 at 08:37
  • You could run the script every 5 minutes and sleep(1) in a loop and it would be checked every second .. – Clarence Sep 04 '13 at 17:49
0

Follow the instructions here to run a PHP script in the background:

php execute a background process

It requires the use of shell_exec to call the script from File A, so you will have to create a new file for that code to be called. It also assumes you are using linux

Community
  • 1
  • 1
Matt
  • 71
  • 4
  • thank you.But how can I pass parameter as an argument in shell_exec command (i.e.$token,$count in my question) ? – Ponting Sep 04 '13 at 10:28
  • That's in the manual and has been answered many times before, for example: http://stackoverflow.com/questions/6763997/shell-run-execute-php-script-with-parameters – Clarence Sep 05 '13 at 06:19