Heim > php教程 > php手册 > Hauptteil

PHP引用以及误区

WBOY
Freigeben: 2016-06-06 20:07:22
Original
881 Leute haben es durchsucht

什么是引用 PHP中的引用可以理解成变量的别名。由于PHP的变量名是存储在符号表(symbol table)中的,变量内容是存储在堆中,引用就是用符号表中的不同符号(symbol)名称来访问同一存储内容,和Unix文件系统中的hardlink是同一个概念,比如: ?php$a = 1;$b = $

什么是引用

PHP中的引用可以理解成变量的别名。由于PHP的变量名是存储在符号表(symbol table)中的,变量内容是存储在堆中,引用就是用符号表中的不同符号(symbol)名称来访问同一存储内容,和Unix文件系统中的hardlink是同一个概念,比如:

<code><?php $a = 1;
$b = &$a; //$a与$b指向同一内容
$b = 2;
echo $b; //2
echo $a; //2
</code></code>
Nach dem Login kopieren

传递引用

引用传递很简单,就是一个「&」符号,比如:

<code><?php function foo(&$a) {
  $a = 2;
}
$b = 1;
foo($b);
echo $b; //2
</code></code>
Nach dem Login kopieren

返回引用

大多数情况下并不需要返回引用来提高性能,zend引擎会自己进行优化,但是如果你非得返回引用得话,可以按照以下方式来返回引用:

<code><?php class foo {
    public $value = 42;
    public function &getValue() { // 需要一个"&"
        return $this->value;
    }
}
$obj = new foo;
$myValue = &$obj->getValue(); // 还需要一个"&",$myValue是对class foo中的$value的引用
$obj->value = 2;              // 修改对象的$value属性
echo $myValue;                // 输出2,$myValue与class foo中的$value值相同
</code>
Nach dem Login kopieren

与指针的区别

引用与指针很像,但是其并不是指针,看如下的代码:

<code><?php $a = 0;
    $b = &a;
    echo $a; //0
    unset($b);
    echo $a; //0
</code></code>
Nach dem Login kopieren

由于$b只是$a的别名,所以即使$b被释放了,$a没有任何影响,但是指针可不是这样的,看如下代码:

<code>#include <stdio.h>
int main(int argc, char const *argv[]) {
    int a = 0;
    int* b = &a;
    printf("%i\n", a); //0
    free(b);
    printf("%i\n", a); //*** error for object 0x7fff6350da08: pointer being freed was not allocated
}
</stdio.h></code>
Nach dem Login kopieren

由于b是指向a的指针,所以释放了b的内存之后,再访问a就会出现错误,比较明显的说明了PHP引用与C指针的区别。

对象与引用

在PHP中使用对象的时候,大家总是被告知“对象是按照引用传递的”,其实这是个误区。PHP的对象变量存储的是此对象的一个标示符,在传递对象的时候,其实传递的就是这个标示符,而并不是引用,看如下代码:

<code><?php $a = new A;
$b = $a;    
$b->testA = 2;
/*
 * 此时$a,$b的关系:
 *        +-----------+      +-----------------+
 * $a --> | object id | ---> | object(Class A) |
 *        +-----------+      +-----------------+
 *                               ^
 *        +-----------+          |
 * $b --> | object id | ---------+
 *        +-----------+    
 *
 *
 */
$c = new B;
$a = $c;
$a->testB = "Changed Class B";
/*
 * 此时$a,$b,$c的关系:
 *        +-----------+      +-----------------+
 * $b --> | object id | ---> | object(Class A) |
 *        +-----------+      +-----------------+
 *                               
 *        +------------+          
 * $a --> | object id2 | -------------+
 *        +------------+              |
 *                                    v
 *        +------------+      +-----------------+
 * $c --> | object id2 | ---> | object(Class B) |
 *        +------------+      +-----------------+
 */
echo "object a: "; var_dump($a); //["testB"]=> string(15) "Changed Class B"
echo "object b: "; var_dump($b); //["testA"] => int(2)
echo "object c: "; var_dump($c); //["testB"]=> string(15) "Changed Class B"
</code>
Nach dem Login kopieren

如果对象是按照引用传递的,那么$a, $b, $c输出的内容应该一样,事实上结果并非如此。 看下面通过引用传递对象的列子:

<code><?php $aa = new A;
$bb = &$aa;  // 引用 
$bb->testA = 2;
/*
 * 此时$aa, $bb的关系:
 *
 *         +-----------+      +-----------------+
 * $bb --> | object id | ---> | object(Class A) |
 *         +-----------+      +-----------------+
 *              ^                  
 *              |
 * $aa ---------+ 
 *
 *
 */
$cc = new B;
$aa = $cc;
$aa->testB = "Changed Class B";
/*
 * 此时$aa, $bb, $cc的关系:
 *
 *         +-----------+      +-----------------+
 *         | object id | ---> | object(Class A) |
 *         +-----------+      +-----------------+
 *              
 * $bb ---->-----+      
 *               |
 * $aa ---->-----+
 *               |  
 *               v   
 *         +------------+      
 *         | object id2 | --------------+ 
 *         +------------+               |
 *                                      v
 *         +------------+      +-----------------+
 * $cc --> | object id2 | ---> | object(Class B) |
 *         +------------+      +-----------------+
 */
echo "object aa: "; var_dump($aa); //["testB"]=>string(15) "Changed Class B"
echo "object bb: "; var_dump($bb); //["testB"]=>string(15) "Changed Class B"
echo "object cc: "; var_dump($cc); //["testB"]=>string(15) "Changed Class B"
</code>
Nach dem Login kopieren

此时$aa,$bb,$cc三者内容完全一样,所以可以看出对象并不是按照引用传递,要尽快走出这个误区。

参考:

http://www.php.net/manual/en/language.references.php http://www.php.net/manual/en/language.oop5.references.php

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!