4

Scope-Php

php 作用域

变量

关于变量的赋值方式

变量默认总是传值赋值的,也就是说,如果改变了其中一个变量是不会影响另外一个变量的。但是如果用的是

引用传值,那么这两个变量这是同一个数据的不同别名而已。

当然,在将一个变量赋值给另外一个变量时,只是增加了一个指针对相同数据的引用,同时,当销毁的时候只是销毁了相应的指针,这样做的目的当然是为了不浪费空间。

详细情况得参考php-internals

//片段1
$a = 10;
xdebug_debug_zval('a');
$b = $a;
xdebug_debug_zval('b');

// a: (refcount=1, is_ref=0)=10
// b: (refcount=2, is_ref=0)=10
//从上面可以看出,变量并没有被引用,所以is_ref为0


// 片段2

$aa = 100;
xdebug_debug_zval('aa');
$bb = &$aa;
xdebug_debug_zval('bb');
xdebug_debug_zval('aa');

//aa: (refcount=1, is_ref=0)=100
//bb: (refcount=2, is_ref=1)=100
//aa: (refcount=2, is_ref=1)=100
// 从上面可以看出,当使用引用赋值以后,两个变量是指向同一个数据的,

变量的作用域

对于全局变量而言,zend引擎有一个_zend_executor_globals的结构,这个结构中有一个symbol_table全局符号表,保存了顶层作用域的变量,而想函数或者对象在被调用的时候,会创建active_symbol_table来保存局部变量。如果程序在全局执行的时候,那么他会调用相应的词法表来调取相应的变量。

同时,由于php并不支持JavaScript的原型链,所以每个局部作用域都是相对独立的。

php 仅有的是函数作用域,这也是仅有的一种作用域分离器,这就意味着在一个函数内部的变量使不能被外部访问的,而且在全局的变量也是它不能访问的。这与pythonLEGB规则相比是有了很大的限制的,所以这也许是它的闭包不被广泛接受的原因之一吧。

命名空间

php命名空间是用来解决函数/类/常量或第三方的库所引起的问题的。在php中受此影响的主要是:类,接口,函数,常量。php中使用命名空间中的元素与文件系统的使用方式类似:

  1. 非限定名称,或不包括前缀的类名称。如果有当前的命名空间,那么将会将它归到该命名空间下,如果当前的命名空间是全局空间,那么会被解析为全局函数名称。

  2. 限定名称,包含前缀的名称。如果命名空间有前缀,如subnamespace\foo,由于是相对命名空间,所以会加上
    当前的命名空间;如果是全局那么同上。

  3. 完全限定名称,包含全局前缀操作符的名称。如\subnamespace\foo,那么将会解析为全局的名称,不会加上其他东西,类似与绝对命名空间。

jekyll博客教程