php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #20525 variable references not working correctly
Submitted: 2002-11-20 17:55 UTC Modified: 2002-12-04 18:16 UTC
Votes:1
Avg. Score:1.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: bmichael at goldparrot dot com Assigned:
Status: No Feedback Package: Variables related
PHP Version: 4.2.3 OS: Windows 2000
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: bmichael at goldparrot dot com
New email:
PHP Version: OS:

 

 [2002-11-20 17:55 UTC] bmichael at goldparrot dot com
The variable reference is not working as I would understand it should. The example that follows is long, but just cut and paste then read the output. 

Years of "C" programming says this should work.

Try example first then, look for the following lines in the
code:
   //*****NOTE****JUST DELETE THE & symbol TO MAKE WORK
and remove the & symbol to see the correct output.

CODE STARTS HERE
**********************************************************
<?php

 

  class A
  {
     var $name;
     var $order;
  }
  
  class B
  {
     var $name;
     var $list_array;
  }

  class C_LIST {

      var $c_list;

      function print_test($call,$cname) 
      { 
        // call: the variable you want to print_r 
        // cname: the label for your debugging output 
    
        echo $cname . ":<pre>"; 
   
       print_r($call); 
       if ( is_array($call)) 
       { 
          reset($call); 
       } 
       echo "</pre><hr>";
     }      
      

     function test()
     {
       //new instantiated array in memory
       $local_c_list = array(); 

       //array indicies for 
       $i = 0;
       $j = 0;

       //array indicies for $x (see below)
       $k = 0;
     

       $x = array(0 => array(0 => "A_First", 1 => "B_First", 2 => 1),
                  1 => array(0 => "A_First", 1 => "B_Second", 2 => 2),
                  2 => array(0 => "A_First", 1 => "B_Third",2 => 3),
                  3 => array(0 => "A_Second",1 => "B_First",2 => 1),
                  4 => array(0 => "A_Second",1 => "B_Second",2 => 2),
                  5 => array(0 => "A_Second",1 => "B_Third",2 => 3)
                  );
        //loop through in array of x, e.g. x[0][$l]
          for ($k = 0; $k < 6; $k = $k + 1)
           {
               $b_name  = $x[$k][0];
               $a_name 	= $x[$k][1];
               $a_order = $x[$k][2];
            

               if ((!isset($b)) || (!isset($b->name)) || ($b_name != $b->name))
               {
			      //attach the A record to the main list
			      // starting on the second A record found

                  if (isset($b->name))
                  {
                     //set the local_list to the reference of b
                     //this avoids memory copies
           		   //*****NOTE****JUST DELETE THE & symbol TO MAKE WORK

			         $local_c_list[$i] = &$b;
        	         $i = $i + 1;
        	         $j = 0;
        	      }
        	
                  $b = new B();
			
            	  $b->name = $b_name;
                  $b->list_array = array();
                  $this->print_test($b,"An element");

               }  //end if no B exists or we are beginning another B name

           //Create new A record
           $a = new A();
           $a->name = $a_name;
           $a->order = $a_order;

		   
 	       $this->print_test($a,"An item");         
        
           //Set $b->list_array[$a->order] = &$a  -- the reference of $a
		   //*****NOTE****JUST DELETE THE & symbol TO MAKE WORK
  		   $b->list_array[$j] = &$a;
  		   $j = $j + 1;
           $this->print_test($b,"A list"); 
         } //end for k loops
      

      $this->c_list = $local_c_list;
    
     return;
   } //end test
   
   
} //end class   


    $the_list = new C_LIST();
    $the_list->test();
    
    $the_list->print_test($the_list,"Test");
?>

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-11-21 02:40 UTC] jan@php.net
can you please submit a short script along with some explaination what it does, what not and what it should do in your opinion. Also make sure you have read http://www.php.net/manual/en/language.references.php
and notice that the & works slightly different than in C.
 [2002-11-21 09:46 UTC] bmichael at goldparrot dot com
Script was already included.

Just cut and paste the PHP code into a text editor and save.
Then run.

The script will cycle through and array, building objects out of the array.  It dumps the values of the objects at certain steps.  You will see the difference if you follow the instructions below.

Run Script once and look at output.  You will notice that the dump of the B class will contain repeat elements (actually, it seems to contain only the last element of the array that was visited).

Edit Script, deleting the & symbol where I have placed a comment (***NOTE).
Run Script and look at output. You will see the output is as you would expect.

Thanks.  If you need more info, you can go to my website www.goldparrot.com and get my contact information to call me.

Thanks again.
 [2002-11-21 09:59 UTC] jan@php.net
Hey,
I should have emphesized on 'short', currently I just don't have the passion to go through that code in depth without you showing that you have read the docs. And please come up with a short, self-contained, easy to read and unterstand script, thanks a lot for your interest in PHP!

--
Jan
 [2002-11-22 10:31 UTC] bmichael at goldparrot dot com
I don't want to sound rude, but just run the script as is and you will see the problem.

This is about as short as I want to get the script so that you see the problem in depth.

It will take you no amount of time to cut and paste the section into a new doc and run it. The difference in output will be self explanatory.

So if you would,.....just run the script provided.
 [2002-11-22 10:55 UTC] bmichael at goldparrot dot com
Also, please look at output from bottom up.  This will make it easier to understand what is happening.

If you want less output, just comment out the "print_test" functions.

I am included the last set of lines from the output and have noted the differences between runs with ********

You will notice that in the proper code, the B_FIRST, B_SECOND and B_THIRD objects are stored properly.

In the code using the & reference symbol, only the B_THIRD object is stored.  It is stored three seperate times.

The proper result should be :

Test:
c_list Object
(
    [c_list] => Array
        (
            [0] => b Object
                (
                    [name] => A_First
                    [list_array] => Array
                        (
                            [0] => a Object
                                (
********                            [name] => B_First
                                    [order] => 1
                                )

                            [1] => a Object
                                (
********                            [name] => B_Second
                                    [order] => 2
                                )

                            [2] => a Object
                                (
********                            [name] => B_Third
                                    [order] => 3
                                )
 ))))


Output from BAD calls using the & reference symbol will look like this:

c_list Object
(
    [c_list] => Array
        (
            [0] => b Object
                (
                    [name] => A_Second
                    [list_array] => Array
                        (
                            [0] => a Object
                                (
********                            [name] => B_Third 
                                    [order] => 3
                                )

                            [1] => a Object
                                (
********                            [name] => B_Third
                                    [order] => 3
                                )

                            [2] => a Object
                                (
********                            [name] => B_Third
                                    [order] => 3
                                )

                        ))))



Hope this discussion is alieviates some of your time crunch.

Thanks for those of us who depend on PHP for our businesses.
 [2002-11-23 09:07 UTC] jan@php.net
when the output is so self explainatory, I'd like to see how it is produced, hence I have to go through your code. I won't do this, since I am sure you can shorten that to 10-15 LOC. Also, I asked you twice to read the docs on references[1] and you did not reply to that by no means. The '&' operator works different in PHP than in C. Make, at first, sure, the 'bug' is  due to this confusion, thank you.

[1] http://www.php.net/manual/en/language.references.php
Jan
P.S. I don't want to sound rude as well :)
 [2002-12-04 18:16 UTC] sniper@php.net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Open". Thank you.


 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Mon Dec 06 23:03:35 2021 UTC