2

I have a file, Notification.php, which is a class. Its structure is like this:

Class Notificaiton
{
    public function sendNotification($token,$count)
    {
       // Here is the code for sending push notification(APNS)
    }      
}

Normally, if I want to call this function from another PHP file then I have to make an object of class and then call its method as below:

$notification = new Notification();   
$notification->sendNotification($token,$value);

But what I want to do is to call this in background process. So I used exec() command as below :

exec("/usr/bin/php /path/to/Notification.php >> /path/to/log_file.log 2>&1 &");

Here I wonder how can I call function(sendNotificaiton()) of file(Notification.php) and pass arguments as parameter: $token and $count ?

I found that exec/shell_exec/passthru commands 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
  • If you're looking for asynchronous execution, exec is not your only option. You might consider multithreading. See this for pros and cons: http://stackoverflow.com/questions/209774/does-php-have-threading/14201579#14201579 – Francois Bourgeois Sep 09 '13 at 15:49

5 Answers5

6

Its better to create one more php file and call the method in it. like

notificationCall.php:

<?php
include 'notification.php';

$token = $argv[1];
$count = $arg2[2];
$notification = new Notification();   
$notification->sendNotification($token,$count);
?>

exec("/usr/bin/php /path/to/notificationCall.php token count >> /path/to/log_file.log 2>&1 &");

rams0610
  • 1,041
  • 10
  • 8
  • Thank you.It works perfect.I found that `exec/shell_exec/passthru commands` can help me. But which command I used out of these three commands in this case? – Ponting Sep 04 '13 at 12:12
  • I can not see anything related to passthru on the site you mention. – Ponting Sep 05 '13 at 05:25
2

Add construct method to Notification class, like so:

function __construct() {
    if(isset($_GET['action']) && $_GET['action']=='sendnotification') {
        $this->sendNotification();
    }
}

Then run your exec command like so:

exec("/usr/bin/php /path/to/Notification.php?action=sendnotification >>
/path/to/log_file.log 2>&1");

$token and $count can also be provided as GET parameters within exec command.

ZurabWeb
  • 1,241
  • 1
  • 12
  • 21
2

I would prefer to not have a separate script merely to call command line execution.

testNotification.php

<?php
include_once 'Notification.php';
use Bubba\Util\Notification;

$Notification = new Notification();
$Notification->sendNotification('some1token', 33);

This assumes our Notification class file is in the same directory, although it is expected it would be in a library directory that is not web accessible.

Notification.php

<?php
namespace Bubba\Util;

if (Notification::isCommandLineInterface()){
    $shortopts  = "";
    $shortopts .= "t:";  // The Token, Required value
    $shortopts .= "c:";  // The Count, Required value
    $options = getopt($shortopts);

    $Notification = new Notification();
    $Notification->sendNotification($options['t'], $options['c']);
    exit;
}

class Notification {
    protected $_token;
    protected $_count;

    public function __construct() {
    }

    public function sendNotification($token = NULL, $count = NULL){
        $this->setCount($count);
        $this->setToken($token);

        // If we are running from the command line
        // then we just want to send the notification
        if ($this->isCommandLineInterface()){
            print "I am notifying you with [{$this->_token}] that the count is [{$this->_count}]\n";
        }else{
            $cmd = '/usr/bin/php ' . __FILE__ . " -t='{$this->_token}' -c={$this->_count} >> notification.log 2>&1 &";
            exec($cmd );
        }
    }

    /**
     * Do some appropo validation, you don't want stuff injected
     * @param string $token
     */
    protected function validateToken($token){
        if (empty($token) || !is_string($token)){
            $this->_token = NULL;
        }
    }

    /**
     * Do some appropo validation, you don't want stuff injected
     * @param string $token
     */
    protected function validateCount($count){
        if (empty($count) || !is_numeric($count)){
            $this->_count = 0;
        }
    }


    /**
     * Determine if this is running on the command line or not.
     * @return boolean
     */
    public static function isCommandLineInterface(){
        return (php_sapi_name() === 'cli');
    }

    /**
     * @return the $_token
     */
    public function getToken() {
        return $this->_token;
    }

    /**
     * @return the $_count
     */
    public function getCount() {
        return $this->_count;
    }

    /**
     * @param NULL $_token
     */
    public function setToken($_token) {
        $this->validateToken($_token);
        $this->_token = $_token;
    }

    /**
     * @param number $_count
     */
    public function setCount($_count) {
        $this->validateCount($_count);
        $this->_count = $_count;
    }
}

In this case, you can merely browse to http://your.localhost.net/testNotification.php and testNotification will instantiate the Notification object, and call the notify function. The notify function will realize it is not a CLI call, so it will make the exec call and return immediately. The exec call will load the Notifcation.php file, and realize that it is running from the CLI, thus it will instantiate itself, grab appropriate command line options, send the notification, and exit.

You can verify that by noticing a new notification.log in the same directory with the appropriate notification message.

bubba
  • 3,839
  • 21
  • 25
1

You example is very simple and perhaps this is killing a fly with a bazooka but how about something like: http://www.gearman.org/ or http://www.rabbitmq.com/. Those services are perfect for running stuff in the background.

Lukasz Kujawa
  • 3,026
  • 1
  • 28
  • 43
1

In CPanel with linux web servers I have used bellow codes

A)

/usr/bin/php -q /home/username/public_html/path/to/Notification.php

AND B)

 lynx --dump http://yourlink.com/path/to/Notification.php > /path/to/log_file.log

For me in some servers works the method A and in some servers works the method B. You can try both. I hope it helps you.

A. Zalonis
  • 1,599
  • 6
  • 26
  • 41