php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #24943 static variables in tick handler persist across multiple invocations
Submitted: 2003-08-04 21:10 UTC Modified: 2005-07-09 00:27 UTC
Votes:4
Avg. Score:3.5 ± 0.5
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: php at ideacode dot com Assigned:
Status: Closed Package: Scripting Engine problem
PHP Version: 5CVS, 4CVS (2004-04-14) OS: * (all SAPIs except CGI!)
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: php at ideacode dot com
New email:
PHP Version: OS:

 

 [2003-08-04 21:10 UTC] php at ideacode dot com
Description:
------------
The values of static variables within a tick handler (registered with register_tick_function) persist across multiple invocations of the script.

You can run and re-run this script as many times as you like; the static variable value keeps growing.

This bug is similar to #11536 and #17283, but those were closed due to lack of response.

Reproduce code:
---------------
      1 function heartbeat($return = false) {
      2     static $static = 0;
      3            $auto   = 0;
      4
      5     if ($return) {
      6         return "static=[$static]\nauto=[$auto]\n";
      7     } else {
      8         $static++;
      9         $auto++;
     10     }
     11
     12 }
     13
     14 register_tick_function('heartbeat');
     15 declare (ticks = 1) {
     16 }
     17 echo heartbeat(true);

Expected result:
----------------
At the end of each run of this script, the value of $static should be 1 and the value of $auto should be 0.

According to the documentation, the tick function (heartbeat) will be called for every tick (1) statements ecxecuted in the declare block, PLUS 1 for the declare close curly (line 16).  Because there are 0 statements in the block, I expect 0/1 + 1 callbacks to hearbeat.

Consequently, $static should have a value of 1 (incremented once) and $auto should have a value of 0 (incremented once but looses value after each call) when explicitly called on line 18.

If you set ticks = 2, I would expect 0/2 + 1 callbacks. Because there are no statements in the block, ANY value of ticks should still execute only once.  Ergo, regardless of the ticks setting, $static should still have a value of 1 and $auto a value of 0.

Actual result:
--------------
At the end of each run of this script, the value of $static increases relative to the value it had at the LAST run, and $auto remains at 0 always.  Furthermore, "LAST" appears to refer to the last value in the particular Apache child. If I set Apache to 1 child only, the value always increases relative to that single value, rather than bouncing around.

In other words, the static variable within heartbeat appears to retain its value ACROSS invocations. While this would otherwise be a nice feature, the value bounces around (ie is not monotonically increasing).

Also, with ticks = 1, the value of the static variable appears to increase by 2 each time: 2, 4, 6, 8, etc. With ticks = 2, $static increases by 1: 1, 2, 3, etc.  With ticks >= 3, $static doesn't increase at all: 0, 0, 0, etc.
(This may be a separate bug, but I'd rather just mention it here)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-08-04 21:37 UTC] php at ideacode dot com
The bug also occurs if you use a member variable within an object and an object method as the callback:

      3 class Foo {
      4     function Foo() {
      5         $this->static = 0;
      6     }
      7
      8     function heartbeat($return = false) {
      9         $auto   = 0;
     10
     11         if ($return) {
     12             return "static=[{$this->static}]\nauto=[$auto]\n";
     13         } else {
     14             $this->static++;
     15             $auto++;
     16         }
     17
     18     }
     19 }
     20 $foo = new Foo();
     21
     22 register_tick_function(array (&$foo, 'heartbeat'));
     23 declare (ticks = 1) {
     24     // no op
     25 }
     26 echo $foo->heartbeat(true);
 [2005-06-19 21:33 UTC] sniper@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php4-STABLE-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php4-win32-STABLE-latest.zip

I can't reproduce.

 [2005-06-27 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2005-07-09 00:27 UTC] php at ideacode dot com
Agreed, closing; cannot reproduce in latest PHP4.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Nov 24 09:01:31 2024 UTC