php 变量/方法/类 的引用和传值分析

a_pro = 'b';
echo $a->a_pro." | ".$b->a_pro.PHP_EOL; // b | b */

/*$a = new a();
$b = &$a;//引用 和 赋值 一样
$b->a_pro = 'c';
echo $a->a_pro." | ".$b->a_pro.PHP_EOL;  // c | c */

/*$a = new a();
$b = clone $a; //克隆对象就是 简单的new一个其他的对象,不过比new 更快
$b->a_pro = 'd';
echo $a->a_pro." | ".$b->a_pro.PHP_EOL; // a | d */


//静态变量的使用
//PHP中static变量的使用范围不仅可以在类,方法或变量前面添加static修饰符,我们甚至还能给函数内部变量添加static关键字。添加了static修饰符的变量即使在该函数执行完毕值仍然不会丢失,也就是说,在下一次调用这个函数时,变量仍然记得原来的值。如:
/*function test()
{
  static $var = 0;//静态变量的声明,当函数执行完毕,仍然存在,下次进来声明发现存在,就忽略,而不是替换值
  $var++;
  echo $var.' ';
}

test();
test();
test();*/


//方法引用
//下面解释下: 通过这种方式$a=test();得到的其实不是函数的引用返回,这跟普通的函数调用没有区别 至于原因: 这是PHP的规定的,PHP规定通过$a=&test(); 方式得到的才是函数的引用返回至于什么是引用返回呢(PHP手册上说:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。) 这句狗屁话 害我半天没看懂用上面的例子来解释就是$a=test()方式调用函数,只是将函数的值赋给$a而已, 而$a做任何改变 都不会影响到函数中的$b而通过$a=&test()方式调用函数呢, 他的作用是 将return $b中的 $b变量的内存地址与$a变量的内存地址 指向了同一个地方即产生了相当于这样的效果($a=&$b;) 所以改变$a的值 也同时改变了$b的值 所以在执行了$a=&test();$a=5;以后,$b的值变为了5这里是为了让大家理解函数的引用返回才使用静态变量的,其实函数的引用返回多用在对象中
/*function &test1()
{
    static $b=0;//申明一个静态变量
    $b++;
    echo $b;
    return $b;
}
$a=test1();//这条语句会输出 $b的值 为1
$a=5;
$a=test1();//这条语句会输出 $b的值 为2
$a=&test1();//这条语句会输出 $b的值 为3
$a=5;
$a=test1();//这条语句会输出 $b的值 为6*/


//类里面的方法引用
class test {
    public $a = 1;
    public static $b = 2;

    public function a(){
        return $this->a;
    }

    public function &b(){
        return self::$b;
    }

    public function &c(){
        return $this->a;
    }
}

$test = new test();

$res_a = $test->a();

/*$res_b = $test->b();
$res_b = 90;
var_dump($test->a,test::$b);die();  // 1 2*/

/*$res_b = &$test->b();
$res_b = 100;
var_dump($test->a,test::$b);die();   //  1 100*/

/*$res_b = $test->c();
$res_b = 90;
var_dump($test->a,test::$b);die(); // 1 2*/

/*$res_b = &$test->c();
$res_b = 90;
var_dump($test->a,test::$b);die(); // 90 2*/

/*$res_b = &$test->a();
$res_b = 90;
var_dump($test->a,test::$b); die(); //a方法没有引用,这样会报notice  1 2*/


class App {
    public $c = 0;
    public static $d;
    public function __construct()
    {
        self::$d = new Bpp();
    }

    public function &__get($name)
    {   
        return self::$d->{$name};
    }

    public function __set($name, $value)
    {
        self::$d->{$name} = $value;
    }
}

class Bpp {
    public $a = 1;

    public function &__get($name)
    {   
        return $this->{$name};
    }

    public function __set($name,$val)
    {   
        $this->{$name} = $val;
    }
}

$a = new App();

//var_dump($a,App::$d); die();  
/*
object(App)#2 (1) {
  ["c"]=>
  int(0)
}
object(Bpp)#3 (2) {
  ["a"]=>
  int(1)
  ["test"]=>
  string(3) "zjx"
}*/

/*$e = $a->b; //如果没有&__get()  会报错  Undefined property: Bpp::$b
$e = 100;
var_dump($e,App::$d);die();*/
/*int(100)
object(Bpp)#3 (3) {
  ["a"]=>
  int(1)
  ["test"]=>
  string(3) "zjx"
  ["b"]=>
  NULL
}*/


/*__get()  方法前面加上& 可以在里面属性不存在的情况下增加对象的属性成员,但是值为null,  如果外部的调用被引用,并且被赋值,则会一同修改*/

/*$e = &$a->b;
$e = 100;
var_dump($e,App::$d);die();*/
/*int(100)
object(Bpp)#3 (3) {
  ["a"]=>
  int(1)
  ["test"]=>
  string(3) "zjx"
  ["b"]=>
  &int(100)
}
*/

/*$a->b = 100;  //相当于向对象里添加属性
var_dump(App::$d);die();*/
/*object(Bpp)#3 (2) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(100)
}*/



/*下面这种情况,并不是简单的set赋值,他会首先解析$a->load调用__get方法,如果__get()没有被引用,则实际返回的元素不存在,会报错
Undefined property: Bpp::$load 并且返回值也不能承接['name'] 数据,也会报错 Indirect modification of overloaded property Bpp::$load has no effect。  加上引用之后,先是在类上增加load的成员变量,然后对该变量进行赋值,值为数组类型*/
$a->load['name'] = 'test';
var_dump(App::$d);
/*object(Bpp)#3 (2) {
  ["a"]=>
  int(1)
  ["load"]=>
  array(1) {
    ["name"]=>
    string(4) "test"
  }
}*/

/*$d = ['a', 'b', 'c'];

foreach (k=>v = &k];
print_r($d);
}*/

//print_r($d); b b c
/Array
(
[0] => a
[1] => b
[2] => c
)
Array
(
[0] => b
[1] => b
[2] => c
)
Array
(
[0] => b
[1] => c
[2] => c
)
/

你可能感兴趣的:(php 变量/方法/类 的引用和传值分析)