static關鍵字
static關鍵字的一個重要特性是靜態變量,靜態變量僅在局部函數域中存在,但當程序執行離開此作用域時,其值並不丟失。
<?php function test() { static $a = 0; echo $a; $a++; } ?> test();#0 test();#1 #變量 $a 僅在第一次調用 test() 函數時被初始化
靜態變量與遞歸函數 function test() { static $count = 0; $count++; echo $count; if ($count < 10) { test(); } $count--; echo $count; } test();#輸出爲:1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1 0
- 類中的static,即靜態屬性和靜態方法
- 靜態屬性:可以通過類來訪問,不能通過類的對象來訪問。靜態屬性只能被初始化爲文字或常量,不能使用表達式。所以可以把靜態屬性初始化爲整數或數組,但不能初始化爲另一個變量或函數返回值,也不能指向一個對象。
- 靜態方法:可以通過類來訪問,也可以通過類的對象來訪問。由於靜態方法不需要通過對象即可調用,所以僞變量 $this 在靜態方法中不可用。
<?php
class Test{
public static $a1 = '123';
public static function f1()
{
echo self::$a1;
}
}
echo Test::$a1; #123
echo Test::f1();#123
$test = new Test();
echo $test->a1;#Notice: Undefined property: Test::$a1
echo $test->f1();#123
3.static後期靜態綁定參看
http://blog.csdn.net/ma199385/article/details/50639276
&取址運算符
在 PHP 中引用意味着用不同的名字訪問同一個變量內容,變量名和變量內容是不一樣的, 因此同樣的內容可以有不同的名字。
<?php $a =& $b;$a 和 $b 指向了同一個變量內容 function foo(&$var) { } foo($c); #$c被創建,指向null #如果對一個未定義的變量進行引用賦值、引用參數傳遞或引用返回,則會自動創建該變量。
引用傳遞,一個變量通過引用傳遞給函數,這樣該函數就可以修改其參數的值
<?php function foo(&$var) { $var++; } $a=5; foo($a);#6 ?>
可以進行引用傳遞的方式
- 變量,例如 foo($a)
- New 語句,例如 foo(new foobar())
- 引用返回
引用返回,引用返回用在當函數返回值應該被綁定在一個變量上面時,
<?php class foo { public $value = 42; public function &getValue() { return $this->value; } } $obj = new foo; $myValue = &$obj->getValue();#如果不加&,即爲普通調用 $obj->value = 2; echo $myValue; #2 $myValue = 3; echo $obj->value; #3 #此時$myvalue和類中的屬性$value指向同一個變量內容,
取消引用,當 unset 一個引用,只是斷開了變量名和變量內容之間的綁定。這並不意味着變量內容被銷燬了
<?php $a = 1; $b =& $a; unset($a); #不會 unset $b,只是 $a。
引用定位
global 引用,當用 global $var 聲明一個變量時實際上建立了一個到全局變量的引用。和下面的代碼作用相同。
<?php $var =& $GLOBALS["var"]; ?>
$this
在一個對象的方法中,$this 永遠是調用它的對象的引用。
全局和靜態變量的引用
對於變量的 static 和 global 定義是以引用的方式實現的,所以如果給static或者global的變量賦值一個引用,那麼此變量將不再是global和static類型的了。
<?php
function test_global_ref() {
global $obj;
$obj = &new stdclass;此時$obj不再是全局變量,它由指向全局的變量內容變爲指向局部對象。所以在函數外部調用$obj爲null
}
function test_global_noref() {
global $obj;
$obj = new stdclass;
}
test_global_ref();
var_dump($obj); #NULL
test_global_noref();
var_dump($obj);#object(stdClass)(0) {
}
?>
<?php
function &get_instance_ref() {
static $obj;
echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
// 將一個引用賦值給靜態變量
$obj = &new stdclass;
}
$obj->property++;
return $obj;
}
function &get_instance_noref() {
static $obj;
echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
// 將一個對象賦值給靜態變量
$obj = new stdclass;
}
$obj->property++;
return $obj;
}
$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?>
輸出爲:
#Static object: NULL
#Static object: NULL
#Static object: NULL
#Static object: object(stdClass)(1) {
#["property"]=>
#int(1)
#}