0

i have a cron Job running following script every 5 min. However it seems that the script doesn't closes the connection once its run . How can I close the connection in this script?

function __construct($config)
{
    $this->server = $config['server'];
    $this->certificate = $config['certificate'];
    $this->passphrase = $config['passphrase'];

    // Create a connection to the database.
    $this->pdo = new PDO(
        'mysql:host=' . $config['db']['host'] . ';dbname=' . $config['db']['dbname'], 
        $config['db']['username'], 
        $config['db']['password'],
        array());

    // If there is an error executing database queries, we want PDO to
    // throw an exception.
    $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // We want the database to handle all strings as UTF-8.
    $this->pdo->query('SET NAMES utf8');
}

// This is the main loop for this script. It polls the database for new
// messages, sends them to APNS, sleeps for a few seconds, and repeats this
// forever (or until a fatal error occurs and the script exits).
function start()
{
    writeToLog('Connecting to ' . $this->server);

    if (!$this->connectToAPNS())
        exit;

    while (true)
    {
        // Do at most 20 messages at a time. Note: we send each message in
        // a separate packet to APNS. It would be more efficient if we 
        // combined several messages into one packet, but this script isn't
        // smart enough to do that. ;-)

        $stmt = $this->pdo->prepare('SELECT * FROM messages WHERE time_sent IS NULL LIMIT 20');
        $stmt->execute();
        $messages = $stmt->fetchAll(PDO::FETCH_OBJ);

        foreach ($messages as $message)
        {
            if ($this->sendNotification($message->id, $message->token, $message->payload))
            {
                $stmt = $this->pdo->prepare('UPDATE messages SET time_sent = NOW() WHERE id = ?');
                $stmt->execute(array($message->id));
            }
            else  // failed to deliver
            {
                $this->reconnectToAPNS();
            }
        }

        unset($messages);           
        sleep(5);
    }
}
Muhammad Umar
  • 11,391
  • 21
  • 91
  • 193

1 Answers1

1

I may have misread, but apparently you are launching every 5 minutes a script that doesn't exit (infinite loop). So you're stacking the instances, until Earth (or more modestly, your server) eventually explodes.

To answer your question, PHP automatically frees all resources, including DB connexions, when the script execution has ended.

When a script runs for a very long time (like infinite), or there are very specific memory considerations, one can manually frees resources using unset($foo) or $foo = null.[1]

DB connexions can be closed and freed this way too, just with unset($this->pdo).


[1] see also What's better at freeing memory with PHP: unset() or $var = null

Community
  • 1
  • 1
Gras Double
  • 15,901
  • 8
  • 56
  • 54
  • `unset($foo);` barely can help reach any *performance* requirement. Performing `unset` is **always** slower than giving php chance to clean for itself. – zerkms Mar 11 '13 at 03:08
  • "The difference is that = null frees the memory immediately, unset() marks it for garbage collection" -- that's not true. Assigning null only changes the variable value (which hold the reference to an object), it has nothing to do with an object itself. The object will be (if it even will) collected on next GC cycle regardless of how you destroyed all the references to it. – zerkms Mar 11 '13 at 03:11
  • I disagree with your 1st comment, for long-running scripts or *specific* memory considerations, it can be useful to unset huge objects that are not used anymore but are still referenced to. About your 2nd comment, if I understood correctly, there is in fact no difference at all GC-wise with objects (not literals)? – Gras Double Mar 11 '13 at 14:18
  • about 1 - "it can be useful to unset huge objects" --- from what perspective? If you have enough memory - just leave it. If you don't - it has nothing to do with performance. "there is in fact no difference at all GC-wise with objects" --- I'm not sure what you mean, but references to objects are passed by values. With `$foo = null` you're just overwriting the variable value which is a reference to an object, and don't affect the object itself at all. So it does practically the same what `unset()` does, so "frees the memory immediately" is just **wrong**. – zerkms Mar 11 '13 at 19:57
  • Understand and agree with all of your points. Fixed my answer and added a quick note [here](http://stackoverflow.com/questions/584960/whats-better-at-freeing-memory-with-php-unset-or-var-null#584982), I hope everything is OK :) – Gras Double Mar 11 '13 at 20:28
  • @zerkms suppose i let the code remain like that, but maybe any problem occurs and this loop stops. That's why i want to put a cron job after specific internal to restart the loop. How can i make the previous loop stop before starting new one? – Muhammad Umar Mar 12 '13 at 06:32
  • @Muhammad Umar: I'm not sure it makes sense to give advice about the code without knowing the original task – zerkms Mar 12 '13 at 06:44
  • @zerkms its apple push notifications. I want my app to constantly look for messages from db and then send them. however what if this loop stops and my notifications will start getting stored in db and won't get transferred. – Muhammad Umar Mar 12 '13 at 06:52