ID:               33977
 User updated by:  kulakov74 at yandex dot ru
 Reported By:      kulakov74 at yandex dot ru
-Status:           Feedback
+Status:           Open
 Bug Type:         Scripting Engine problem
 Operating System: Linux
 PHP Version:      4.4.0
 New Comment:

In order to get the small code, I began deleting and commenting out
parts of the scripts watching for the notice to remain. But at some
point I found that deleting, commenting out a line or any other changes
made the notice disappear. That is the buggy behaviour, I have no idea
why this is so. In order to make the code simple, I made larger parts
of it not executable with if (0) etc, so that you do not have to
understand them even though they are there. The parts are marked as
"not working". The point is if I physically remove them and the script
is smaller (or even if I double a line) the notice is not displayed, so
maybe the size matters. I provide the final code that does display the
notice though it should not, and the script is also available at
http://hotelsys.biz/dev_ref.php (the result) and at
http://hotelsys.biz/dev_ref.php?src=1 (the source code). 

The notice is about return $oNewNode; in function &add(). In the
function, I create $oNewNode=false; to prevent the notice, the 2nd
branch is executed, and then the return goes. Before calling add(),
render() is called. It does almost nothing to the object but is
necessary for the notice to appear.

The code follows

<?

if (isset($_GET["src"])){
        highlight_file("dev_ref.php");
        exit;
        }

error_reporting(E_ALL);

$TextNode=new Node();
$TextNode->render();
$TextNode->add('H', 123);

//------------------------------------------------------------------------

class Node{
        var $hashValues;                //any values
        var $aNodeGroups;               //
        var $sTemplate;                 //
        var $bDisplay=true;     //don't hide
        var $bCleanup=true;     //autodelete subnodes when used
        
//------------------------------------------------------------------------
        
        function Node($hashValues=false, $bCleanup=true){
        $this->hashValues=array();
        }

        function &add($mixKey, $mixVal=array()){
        $oNewNode=false;
        if (is_array($mixKey)){
                if (0){
                        //not working!!!
                        foreach($mixKey as $n => $v) $this->add($n, $v);
                        }
                }
        else if (!is_array($mixVal) || key($mixVal)===0){
                $this->hashValues[$mixKey]=$mixVal;
                }
        else{
                if (0){
                        //not working!!!
                        $oNewNode=&new Node($mixVal, $this->bCleanup);
                        if ([EMAIL PROTECTED]>aNodeGroups[$mixKey]){
                                $this->aNodeGroups[$mixKey]=array();
                                }
                        $this->aNodeGroups[$mixKey][]=&$oNewNode;
                        //--not working!!!
                        }
                }
        return $oNewNode;
        }

        function render(){
        
        if (!$this->bDisplay) return "";
        if ($this->aNodeGroups){
                if (0){
                        //not working!!!
                        foreach($this->aNodeGroups as $GrpName => $aNodes){
                                $bDebug=($GrpName=='Content');
                                $this->_EndPos=0;       $sAccumulator=false;
                                
while(is_string($sTemplate=$this->getGrpTemplate($GrpName))){
                                        if ($sAccumulator===false){
                                                $sAccumulator=''; 
$NodeNum=count($aNodes);
                                                for($i=0; $i<$NodeNum; $i++){
                                                        if ($sTemplate) 
$aNodes[$i]->sTemplate=$sTemplate;
                                                        
$sAccumulator.=$aNodes[$i]->render();
                                                        if ($this->bCleanup) 
$aNodes[$i]=false;
                                                        else 
$aNodes[$i]->sTemplate='';
                                                        }
                                                }
                                        $this->putLastGrpText($sAccumulator);
                                        }
                                }
                        
                        if ($this->bCleanup) $this->aNodeGroups=false;
                        //--not working!!!
                        }
                }

        $Templ=$this->sTemplate;
        
        foreach($this->hashValues as $sKey => $mixVal){
                continue;
                //not working!!!
                $sToken='{{'.$sKey.'}}';
                if (!is_array($mixVal)){
                        $Templ=str_replace($sToken, $mixVal, $Templ);
                        }
                else{
                        $Len=count($mixVal); $sAccumulator='';
                        for($ValNo=0; $ValNo<$Len; $ValNo++){
                                $sAccumulator.=str_replace($sToken, 
$mixVal[$ValNo], $Templ);
                                }
                        $Templ=$sAccumulator;
                        }
                //---not working!!!
                }

        if ($this->bCleanup) $this->hashValues=array();

        return $Templ;
        }
}

?>


Previous Comments:
------------------------------------------------------------------------

[2005-08-03 14:35:08] [EMAIL PROTECTED]

Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc.

If possible, make the script source available online and provide
an URL to it here. Try to avoid embedding huge scripts into the report.

------------------------------------------------------------------------

[2005-08-03 14:24:55] kulakov74 at yandex dot ru

Description:
------------
Our hosting has upgraded to 4.4.0 and we got the famous notice on
returning variable reference. But after fixing my code to comply weith
the notice I found it is still displayed at certain circumstances.
Unfortunately, I could not isolate the code that behaves this way
because of the scripts complexity so I cannot provide a simple code
that reproduces it. While trying to figure out what was the reason I
found that many minor changes, apparently absolutely not relating to
the problem, could prevent the notice from beaing displayed, while
otherwise it is displayed. It could be simple output directly before or
even anywhere in the script, changing the value of the dummy variable
that is returned instead of false, for ex.

$oNewNode=null;
//...
return $oNewNode;

produced the notice while 

$oNewNode=0;

with the same code did not. Logging to a file, changing the line at
which the dummy assignment is done and a lot of other changes randomly
toggle the irrelevant notice off. I have a script that generates pages
html and the same code works with some pages but displays the notice
with others; then changing it results in the contrary thing. Finally, I
found one bug-proof solution that worked everywhere: 

$oNewNode=&$oNewNode;   return $oNewNode;

but overall working around the problem in the 4.4.0 release has left a
very unpleasant feeling of a buggy system. 

Reproduce code:
---------------
This does not reproduce the problem - it's just the piece of code I
worked with and I added all the lines I tried to prevent the notice. 

function &add($mixKey, $mixVal=array()){
//Add: either a pair $mixKey=>$mixVal,
//or a node $mixKey with values $mixVal, or an array of pairs $mixKey

//WORKED BUT NOT ALWAYS
$oNewNode=null; $oNewNode=false;
//WORKED ALMOST ALWAYS
$oNewNode=0; $oNewNode=1; 

//array
if (is_array($mixKey)){
        foreach($mixKey as $n => $v) $this->add($n, $v);
        //WORKED NOT ALWAYS
        $oNewNode=0;
        }
//string or a simple array
else if (!is_array($mixVal) || key($mixVal)===0){
        $this->hashValues[$mixKey]=$mixVal;
        //WORKED NOT ALWAYS
        $oNewNode=0;
        }
//node
else{
        $oNewNode=&new Node($mixVal, $this->bCleanup);
        if ([EMAIL PROTECTED]>aNodeGroups[$mixKey]){
                $this->aNodeGroups[$mixKey]=array();
                }
        $this->aNodeGroups[$mixKey][]=&$oNewNode;
        //THIS FOR A REASON RESULTED IN EVEN MORE NOTICES UNLIKE THE COMMON
RETURN!
        return $oNewNode;
        }

//NO EFFECT FOR A REASON
if (!isset($oNewNode)) $oNewNode=0;

//THE SOLUTION
$oNewNode=&$oNewNode;

return $oNewNode;
}

Expected result:
----------------
No notices

Actual result:
--------------
A few notices for some pages, none for others


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=33977&edit=1

Reply via email to