引用的传递
//@date: 2013-02-19 //引用的传递 //可以将一个变量通用引用传递给函数,这样该函数就可以修改其参数的值 // function foo(&$var) // { // $var++; // } // $a = 5; // foo($a); // echo $a; // class Obj // { // protected $var; // public function __construct($_var) // { // $this->var = 2; // } // public function setVar($_var) // { // $this->var = $_var; // } // public function getVar() // { // return $this->var; // } // } // function foo(&$obj) // { // $obj->setVar(22); // } // $obj = new Obj(11); // echo $obj->getvar()."<BR><BR>"; // foo($p = new Obj(11)); // echo $p->getvar(); //从函数中返回一个引用 // function &bar() // { // $a = 5; // return $a; // } // function foo(&$var) // { // $var++; // echo $var; // } // foo(bar()); //任何其它表达试都不能通过引用传递,结果未定义 // function bar() // { // $a = 5; // return $a; // } // function foo(&$var) // { // $var++; // echo $var; // } // foo(bar()); // 自 PHP 5.0.5 起导致致命错误 // //靠,我这里并没有报错啊 // $ss = 5; // foo($ss); //表达式,不是变量 (我这里并没有提示错主) // echo $ss; // //foo(55);// 导致致命错误(我这里也是错误) // $a = 123.456; // $b = 'bacdef'; // function swap(&$str1, &$str2) // { // $w = $str1; // $str1 = $str2; // $str2 = $w; // } // echo "a={$a},b={$b}<BR><BR>"; // swap($a,$b); // echo "a={$a},b={$b}<BR><BR>"; // class Foo{ } // class Bar{ } // //返回一个Bar类的引用 // function &createBar() // { // return new Bar; // } // function setBar(&$obj) // { // echo get_class($obj)."<BR><BR>"; // $obj = &createBar(); // echo get_class($obj)."<BR><BR>"; // } // $test = new Foo; // setBar($test); //Foo Bar; // echo get_class($test); //Bar; // class z // { // public $var = ''; // } // function f(&$obj1, $obj2, $obj3, $obj4) // { // $obj1->var = null; //这里更新的是原来的obj1 // //var_dump($obj1); //object(z)#1 (1) { ["var"]=> NULL } // $obj2->var = null; //这里并没用地址传递,怎么也能更新obj2的值呢? // //是因为是对象传递进去的吗? // //var_dump($obj2); object(z)#1 (1) { ["var"]=> NULL } // $obj3 = new z; //$obj3算是重新定义了 // $obj3->var = null; // //var_dump($obj3); //object(z)#5 (1) { ["var"]=> NULL } // $obj4 = clone $obj4; //$obj4也是重新开辟的空间了 // $obj4->var = null; // //var_dump($obj4); object(z)#6 (1) { ["var"]=> NULL } // } // $a = new z(); // $b = new z(); // $c = new z(); // $d = new z(); // f($a,$b,$c,$d); // // var_dump($a);echo "<BR><BR>"; // // var_dump($b);echo "<BR><BR>"; // // var_dump($c);echo "<BR><BR>"; // // var_dump($d);echo "<BR><BR>"; // //实例说明一些问题 // class z // { // public $var = ''; // } // $a = new z(); // $b = &$a; //b=a; // $c = $a; //c重新复制了一分给c // //这里理解错了,c也是指向的一个$a的地址 // //$c = clone $a; 如果语句这样写的话,那么就是吉隆一个z对象了 // $a->var = null; // var_dump($a); // print "<BR>"; //null // var_dump($b); // print "<BR>"; //null // var_dump($c); // print "<BR>"; //null // $a = 2; //重新将变量a指向一个2的内存空间 // var_dump($a); // print "<BR>"; //int(2) // var_dump($b); // print "<BR>"; //obj int(2):ok // //error 因为$b是一个$a的引用,也就是绑定在一起的地址 // //$a一改变,$b也就改变 // var_dump($c); // print "<BR>"; //obj // function a(&$a, &$b) // { // $a = &$b; //这种分配地址的方式是错误的,因为&b已经是引用传递了 // //$a = $b; // } // $a = 1; // $b = 2; // a($a,$b); // $b = 3; // print $a; //3 //如果你希望输出为3,你错了。 $ a中保持不变,并输出为1。参考未分配给$ a。 // $a = 1; // $b = 2; // $a = &$b; //a=2; // $b = 3; //这里又是重新给$b赋值 // print $a; //2 ok:3 // //实际上输出3。 // //但是,怎么样的对象呢?对象,你可能会认为,总是通过引用传递。因此,这应该努力! //function a(&$a, &$b) // function a($a, $b) // { // $a = $b; // $a->i = 11; //这里修改也是白改的,因为$a现在只是一个副本了 // } // $a = new StdClass; // $a->i = 1; // $b = new StdClass; // $b->i = 2; // a($a, $b); // $b->i = 3; // print $a->i;//1 // $a = 1; // $b = 2; // $a1 = &$a; // $b1 = &$b; // $a1 = &$b1; // $b = 3; // print $a; //1 // class DelayedChange // { // private $changeTarget; // public function prepareForChange(&$target) // { // $this->changeTarget = $target; // } // public function change($value) // { // $this->changeTarget = $value; // //注意这里了, // } // } // $testVar = "value 1"; // $obj = new DelayedChange(); // $obj->prepareForChange($testVar); // echo $testVar."<BR><BR>"; //value 1 // $obj->change("value 2"); // echo $testVar."<BR><BR>"; //value 1; // function foo(&$a=NULL) // { // if($a === NULL) // echo "NULL\n"; // else // echo "$a\n"; // } // foo(); //null // //foo(5); //5 这里提示错误,不能这样传递变量进去 // $number = 5; // foo($number); // //foo(NULL); //null error //有人提到,通过参考并不如预期般在call_user_func()。 // $string = "string"; // function change(&$str) // { // $str = 'str'; // } // //call_user_func('change', $string); // //echo $string; //str //实例上是string // change($string); // echo $string; //这样才是str // //在这里我们可以假设call_user_func如下 // function call_user_funct($func,$param) // { // $func($param); // } // function foo(&$a=5) // { // $a +=2; // print "\n In foo=>$a"; // } // function bar(&$a=0) // { // $a +=5; // print "\n In bar=>$a"; // } // $a; // $b; // var_dump($a,$b); //null null // echo "<BR><BR>"; // foo(); // bar(); // var_dump($a,$b); //null null // echo "<BR><BR>"; // foo($a); // bar($b); // var_dump($a,$b); //int(2) int(2); // echo "<BR><BR>"; // //如果你不使用任何操作(不变量,没有固定的),然后创建一个新的变量与空或默认参数。 // //如果传递一个空参数,那么这个变量(空)使用,即使有指定的默认值。 // function ifnull(&$v, $default) // { // if(isset($v)) // return $v; // return $default; // } // $p = array(); // $p['apple'] = 3; // echo ifnull($p['apple'], 3)."<BR><BR>"; //3 // var_dump($p); // echo "<BR><BR>"; // echo ifnull($p['pear'], 5)."<BR><BR>"; //5 // //这里过后就已经有 array(2) { ["apple"]=> NULL ["pear"]=> NULL } // var_dump($p); // echo "<BR><BR>"; // if(isset($p['pear'])) // echo "yes"; // else // echo "pear not set<BR><BR>"; //pear not set // var_dump($p); //但这里判断还是不存在,因为pear为null也就是空不存在的意思 // //但查看key已经是存在的了 // if(array_key_exists('pear', $p)) // echo "yes"; // else // echo "pear not set"; // function f($a = array('default value')) // { // $a[0].=" processed<BR>"; // echo $a[0]; // } // f(); // $b="foo"; // f(array(&$b)); // echo $b; // $array1 = array('test', 'test2'); // function AddTo($key,$val, &$array = null) // { // if($array == null) // { // $array = &$_POST; // } // $array[$key] = $val; // } // AddTo("indirect test", "test", $array1); // AddTo("indirect POST test", "test"); // echo "array 1"; // print_r($array1); // echo "<BR><BR>"; // echo "_POST"; // print_r($_POST); // class TestRunner // { // var $passed; // var $failed; // var $tests; // function TestRunner() // { // $this->passed = 0; // $this->failed = 0; // $this->tests = array(); // } // function addTest($test) // { // $this->tests[] = $test; // } // function signalFaild() // { // $this->failed ++; // } // function runTests() // { // foreach($this->tests as $i=>$eachName) // { // call_user_func($eachName, &$this); // // // // function call_user_funs($eachName, &$tihs) // // { // // $eachName($this); // // } // } // } // function report() // { // echo count($this->tests)." run, ".$this->passed." passed, ".$this->failed." failed"; // } // } // function testNullStringIsEmpty($testRunner) // { // $testRunner->signalFaild(); // } // $testRunner = new TestRunner(); // $testRunner->addTest("testNullStringIsEmpty"); // $testRunner->runTests(); // $testRunner->report(); //1 run, 0 passwd, 1 failed; // function tst(&$arr, $r) // { // array_push($arr, &$r); // } // $arr0 = array(); // $arr1 = array(1,2,3); // tst($arr0, &$arr1); // //print_r($arr0); //array(0=>array(1,2,3)) // array_push($arr0, 5); // array_push($arr1, 18); // print_r($arr1); //aray(1,2,3,18); // echo "<BR><BR>"; // print_r($arr0);//array(0=>array(1,2,3,18), 1=>5); // function tst(&$arr, &$r) // { // array_push($arr, &$r); // } // $arr0 = array(); // $arr1 = array(1,2,3); // tst($arr0, &$arr1); // //print_r($arr0); //array(0=>array(1,2,3)) // array_push($arr0, 5); // array_push($arr1, 18); // print_r($arr1); //aray(1,2,3,18); // echo "<BR><BR>"; // print_r($arr0);//array(0=>array(1,2,3,18), 1=>5); // $arr = array(); // call_user_func(array("ClassName", "functionName"), $param1, $param2, $arr); // print_r($arr); // class ClassName // { // public function functionName($param1, $param2, &$arr) // { // $arr[0] = "apple"; // $arr[1] = "banana"; // print_r($arr); // } // } // //类似于 // $arr = Array(); // ClassName::functionName($param1,$param2,$arr); // print($arr); // function f1(&$num) // { // $num++; // } // function f2(&$num) // { // $num1 = $num; //这里是不行的 // //$num1 = &$num; 这样才行 // $num1++; // } // function f3(&$num) // { // $num1 = &$num; // $num1++; // } // $myNum = 0; // f1($myNum); // echo "is myNum:{$myNum}<BR><BR>"; //1 // f2($myNum); // echo "is myNum:{$myNum}<BR><BR>"; //1 // f3($myNum); // echo "is myNum:{$myNum}<BR><BR>"; //2 // function foo(&$var) // { // $var ++; // return $var; // } // function &bar() // { // $a = 5; // return $a; // } // echo foo(bar()); //6 class talker { private $data = "Hi"; public function &get() { return $this->data; } public function out() { echo $this->data; } } $aa = new talker(); $d = &$aa->get(); $aa->out(); //Hi echo "<BR><BR>"; $d = "How"; $aa->out(); //How echo "<BR><BR>"; $d = "Are"; $aa->out(); //Are echo "<BR><BR>"; $d = "You"; $aa->out(); //You echo "<BR><BR>";