変数の参照と代入はしっかりできているつもりだったのですが、私の理解を完全に覆す以下の問題に遭遇しました
<?php $str = 'WangChuanbo'; $s = &$str; unset($str); echo $s,'hello world';?>
張飛の姓は張飛、名は易徳です
つまり、張飛と張一徳は同一人物です
あなたは張飛を殺しましたが、あなたはただ張飛という名前を世界から消し去り、その人は今でも張一徳という名前で歩き回っています
つまり、張飛と張一徳は同一人物ということになります
あなたが殺した張飛、でもあなたは張飛という名前を世界から消し去っただけで、その人は今でも張一徳というタイトルで回っています
それは理にかなっていて、少しは理解できますが、まだ完全ではありません。 PHPの参照機構とCのポインタには違いがあると言われますが、本質的な違いが分かりません。
Windows システムでは、
E ドライブ上のファイルをデスクトップにコピーすることは、どちらが変更されても、もう一方は変更されません。 . が変更されます; デスクトップにショートカットを作成すると、どちらが変更されても、もう一方も変更されます
これはまったく説明がつかないので、混乱します
$s = &$str; のバインディングは
$s と $str の両方が同じ場所 C を指すことを意味します
設定を解除した後、$str は C を見つけることができません
別の例を挙げましょう
Small Zhang は聞きましたシャオ・リーは、宝は海の上にあると言います
シャオ・リーは記憶を失っていますが、シャオ・チャンは宝が海にあることをまだ知っていました
C++ では、参照とはメモリのアドレスさえも同じであることを意味します
最終的には、それは定数ポインタです
確かに、PHP の参照メカニズムは C のポインタと非常によく似ています。ポインタの動作を無視した場合、少なくともパフォーマンスは最高です。ポインタと同じです
まず、変数の設定を解除しても、それがメモリから消去されるわけではありません。 PHPのガベージコレクションはGCで完結!
参照の設定を解除すると、変数名と変数の内容の間のバインディングが解除されるだけです
$s と $str の両方が同じ場所 C を指すことを意味します
設定解除後 $ Cは str では見つかりません 別の例を挙げましょう
シャオ・チャンはシャオ・リーが宝が海にあると言っているのを聞きました
シャオ・リーは記憶を失っていますが、シャオ・チャンは宝が海にあることをまだ知っています
C++ 、引用の意味 メモリアドレスさえ同じです
結局のところ、それは定数ポインタです
あなたの説明を受けて、私は実験しました
$str = 'WangChuanbo';$s = &$str;$s = 'new';echo $str;
もちろん、このように理解することに固執する場合は、笑
Fドライブにfffフォルダーがあるので、右クリックして「送信 => デスクトップショートカット」をクリックします
それから名前を変更します それをaaa、doと呼んでくださいもう一度、名前を bbb に変更します
aaa を開いてその中に txt を作成し、次に bbb を開くとその中に txt があります
それはそういうことではないでしょうか
简单的说
C的指针 指向的是内存中特定的地址
C的指针 有个数据类型的概念,因此指针是可以参与运算的
php代码并没有给编译成机器码,所以没就访问内存地址一说
的确php的引用机制和C的指针极其相似,如果不计指针的运算,那么至少在表现上与指针是一样的
有两篇博文我读了几遍,发现每个人都有自己的见解,于是就想把这个问题搞透,
参考一: http://www.nowamagic.net/php/php_ReferenceOperator.php
很多人误解php中的引用跟C当中的指针一样,事实上并非如此,而且很大差别。C语言中的指针除了在数组传递过程中不用显式申明外,其他都需要使用*进行定义,而php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的
参考二、 http://blog.csdn.net/woods2001/article/details/7569099
发现越来越困惑了
6楼说的对 要理解这个你需要理解PHP的垃圾回收机制
PHP 的变量并不像C/C++一样 PHP的变量存储在ZVAL机构中 结构体定义如下
typedef struct _zval_struct zval;
...
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
zval结构体中有四个字段,其含义分别为:
属性名 含义 默认值
refcount__gc 表示引用计数 1
is_ref__gc 表示是否为引用 0
value 存储变量的值
type 变量具体的类型
unset() 并不会直接销毁变量 只有当refcount=0时才会被PHP的垃圾回收机制回收
$a = 10;
xdebug_debug_zval('a');
//output: a: (refcount=1, is_ref=0)=10
$b = &$a;
xdebug_debug_zval('a');
//output: a: (refcount=2, is_ref=1)=10
$a = 20;
xdebug_debug_zval('a');
//output: a: (refcount=2, is_ref=1)=20
unset($b);
xdebug_debug_zval('a');
//output: a: (refcount=1, is_ref=0)=20
本帖将会 继续加分,希望大家踊跃发言, 百家争鸣,方才百花齐放
其实很多人在解释引用时都喜欢那php的底层实现来说事,其实这是不对的
解释要用浅显的道理,而非深层次的原理来说明。否则就是越说越乱
就像任何 C 语言书中都不会用汇编语言来解释指针,因为高层都还没明白,底层怎么能明白
php 的引用从表现上看,就如同指针一样。所以把它看成“指针”并无大碍
只是你不要把引用当做“指针”来运算就可以了
换一种方式来理解的话就是
指针是按门牌号码来进出商业街上的每家店铺,所以他可以明确的知道下一家在哪里
引用是按店铺的招牌来进出的,因此他并不能知道旁边的是谁
除此之外,两者的表现并无区别
学习了!
下面希望不要记错:
记忆中php的引用是+1机制,就是每当多一个引用计数器就+1,unset一个就-1
只要变量还有某个单元在使用(不为0),则有效的相关变量名仍然可用
关于这个知识点,我想说三个点:
第一:只有变量才可以有地址,值没有,函数中如果有变量前加&,必须传变量;
$a=100; function myfun(&a){ // &后面必须是变量,直接写100不行,必须把100赋给变量$a,写$a $a++; return $a; } echo myfun($a); //101, 如果写成myfun(100),是错误的
$a="aaaaaaaa"; $b=&$a; unset($b);//unset($b),只删除引用关系,并没有删除值 echo $a; //aaaaaaaa
$a="aaaaaaaaa"; $c="ccccccccc"; $b=&$a; $b=&$c; var_dump($b);// string(9) "ccccccccc"
在网上帮你找个图片 你看下
这个问题我也在问
私もこの質問をしています
どう理解できますか?