php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #12030 function pass by reference isn't consistent.
Submitted: 2001-07-10 21:46 UTC Modified: 2001-07-17 11:49 UTC
From: wboring at ensim dot com Assigned:
Status: Closed Package: Variables related
PHP Version: 4.0.4pl1 OS: Linux redhat 7.1
Private report: No CVE-ID: None
 [2001-07-10 21:46 UTC] wboring at ensim dot com
<?php

//This script demonstrates a problem that I'm
//having w/ php.  It shows that adding a
//reference of a var to an array inside a
//function doesn't actually add a reference,
//but a copy of the object.


//I have a simple class called foo
//which contains 1 member $content,
//and 2 methods: push_works() and
//push_doesnt().

//both push_* functions are used to
//illustrate my problem of stuffing a
//variable reference inside an array.

//NOTE: this is not specific to objects
//and object methods.  This same problem
//will happen if you use a function push()
//and a global (dumb) for the $content array.


function xmp_var_dump($var) {
    echo "<xmp>";
    var_dump( $var );
    echo "</xmp>";
}


//our test class.
//nothing but a container to hold
//the content array.
//this is an example of large class
//that I do the same thing w/
class foo {
    var $content = array();

    //both of these "push" functions
    //illustrate the idea of adding
    //some content to an array.
    //both should work, but only 1 does.

    //personally I would prefer the
    //syntax of the push_doesnt()
    //function, so the caller doesn't
    //have to pass the var with the &
    //in front.


    //this function works if the caller
    //passes the var by reference.
    //ie $foo->push_works( &$my_str );
    function push_works( $content ) {
        array_push($this->content, &$content);
    }

    //this function SHOULD work since it
    //declares its parameter as a reference.
    //the caller would not have to pass the
    //var by reference.
    //ie $foo->push_doesnt( $my_str );
    function push_doesnt( &$content ) {
        array_push($this->content, $content);
    }


}

//create the container classes
//$foo will contain $bar later.
$foo = new foo;

//You should never see the current
//contents of this string,
//since we want to pass it by reference,
//and then change it b4 we dump it out.
$my_str = "You shouldn't even see this string.";

//notice I have to prepend & to the
//push_works() function or it doesn't
//work, which makes sense because
//the parameter is defined as by value.
//
$foo->push_works( &$my_str );

//this function should work, since
//the parameter is defined as by
//reference.
$foo->push_doesnt( $my_str );

//one more try prepending the &
//to push_doesnt, which I shouldn't
//have to do anyways, since the
//parameter is defined as by reference.
//This still doesn't work.
$foo->push_doesnt( &$my_str );

$my_str = "this is what you should read!";


//at this point the DESIRED result is
//3 elements in the $foo->content array
//that are all references to $my_str.
xmp_var_dump( $foo );

xmp_var_dump( phpversion() );
?>

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-07-10 22:01 UTC] wboring at ensim dot com
forgot to add the output of the script.

object(foo)(1) {
  ["content"]=>
  array(3) {
    [0]=>
    &string(29) "this is what you should read!"
    [1]=>
    string(35) "You shouldn't even see this string."
    [2]=>
    string(35) "You shouldn't even see this string."
  }
}

string(8) "4.0.4pl1"


 [2001-07-17 11:49 UTC] stas@php.net
No, it should not work this way. When you pass the variable array_push in push_doesnt, you are actually passing a copy. 
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Nov 16 01:01:36 2019 UTC