一. 變量定義
<?php
function foo() {
return 1;
}
if(!$a = foo()) print 'x';
等價於:
<?php
function foo() {
return 1;
}
$a = foo();
if(!$a) print 'x';
二. 全局和局部
PHP裏面只有全局作用域和函數作用域,沒有塊作用域例如,循環語句內定義的變量,其作用域認爲是外部的,即循環體結束時依然有效
<?php
$a = 1;
for($j=1; $j<5; $j++) {
$a = $a + $j;
}
echo $a . PHP_EOL; //打印出6
echo $j . PHP_EOL; //打印出5
--------------------------------------------
如果在函數中將變量設置爲global,則表示接下來該變量改爲取全局的那個
<?php
$a = 1;
function F() {
$a = 2; //局部變量屏蔽全局變量
echo "$a"; //使用本函數內的局部變量$a
echo PHP_EOL;
global $a; //接下來都是使用全局變量$a
echo "$a";
}
F();
使用global關鍵字
<?php
$x = 10;
$y = 20;
function test() {
global $x,$y; //表示使用全局變量$x和$y
$y = $x + $y;
}
test();
echo $y; //輸出30
-----------------------------------
<?php
$var = 1;
function foo() {
global $var;
unset($var); // unset local $a, the global $a is still there.
//var_dump($var); // Undefined variable: var
var_dump($GLOBALS['var']);
}
foo();
var_dump($var);
將上面那個和這下面這個代碼進行對比:
<?php
$var = 1;
function bar() {
global $var;
unset($GLOBALS['var']); // 解除全局的$a, 局部的$a依然在
var_dump($var);
//var_dump($GLOBALS['var']); // Undefined index: var
}
foo();
//var_dump($var); // Undefined variable: var
'unset($var);'類似於C語言中 'var = NULL;'(假設var是個指針變量), 不同於 'free(var);'
-------------------------------------
<?php
function F() {
$a = 0;
$b = 1;
$GLOBALS['a'] = &$b; // 注意點(1)方括號內是'a',寫成"a"或'$a'都會報錯 (2)$b前面有&符號
echo "$a" . PHP_EOL;
echo "$GLOBALS[a]" . PHP_EOL; //相當於輸出$b
$b = 2;
echo "$GLOBALS[a]" . PHP_EOL; //相當於輸出$b
}
F();
echo "$a" . PHP_EOL; //在之前曾經定義了超級全局變量$GLOBALS['a']
GLOBALS['variable'] 和 global關鍵字 的作用是不一樣的
<?php
function F() {
$GLOBALS['a'] = 1; //改爲"global $a = 1;"就會報錯,因爲函數外並沒有定義$a
}
F();
echo "$a" . PHP_EOL; //因爲F()函數中定義了$GLOBALS['a']
三. 靜態變量
基類實例共享的靜態成員變量,與子類實例共享的靜態成員變量,兩者互不影響
<?php
class Base {
function test($delta = 0) {
static $v = 0;
$v += $delta;
return $v;
}
}
class Derived extends Base {}
$base1 = new Base();
$base2 = new Base();
$derived1 = new Derived();
$derived2 = new Derived();
$base1->test(3);
$base2->test(4);
$derived1->test(5);
$derived2->test(6);
var_dump([ $base1->test(), $base2->test(), $derived1->test(), $derived2->test() ]);
結果是 array(4) { [0]=> int(7) [1]=> int(7) [2]=> int(11) [3]=> int(11) }
基類 $base1和$base2共享同一個靜態變量$v,子類 derived1和$derived2 共享另外的同一個靜態變量 $v
----------------------------------------------
在一個函數中如果多次聲明靜態變量,以最後一次爲準
<?php
function Test(){
static $count = 0;
echo $count;
static $count = 1;
echo $count;
static $count = 2;
echo $count;
}
Test();
結果是輸出三個222
------------------------------------------------------
PHP中的靜態變量只能使用"self::"或者"類名::"訪問,不能使用"$this"訪問;反之,類的成員變量未聲明爲const及static時,只能使用"$this"訪問,不能用"::"訪問
<?php
class Test_Class {
static $a = 0;
public function ReturnVar(){
return $this->a; //$this->a改爲self::$a才能編譯通過
}
}
$b = new Test_Class();
echo $b->ReturnVar();
實例可以調用靜態方法,但是靜態方法中不可以有$this
<?php
class F {
public static function Var() {
echo "Var";
}
}
$b = new F();
echo $b->Var() . PHP_EOL; //輸出Var
-------------------------------------
<?php
class example {
public static $s = 'unchanged';
public function set() {
$s = 'a';
echo $this::$s; //換成$this->s則報錯
echo PHP_EOL;
echo $s;
}
}
$o = new example;
$o->set();
四. 文件包含
include()函數,與調用者是同一個作用域。如果在函數中使用include(),則被包含文件會把函數的作用域當作是被包含文件的全局作用域
<?php
$foo = 'aaa';
$bar = include('include.php');
echo($foo.' / '.$bar);
include.php代碼:
<?php
$foo = 'bbb';
return $foo;
輸出結果是 bbb / bbb,而不是 aaa / bbb
-------------------------------------
// b.php
<?php
$b = "something";
function b() {
global $b;
$b = "something new";
}
b();
echo $b;
直接運行b.php的輸出結果是"something new"。那如果運行下面的a.php,當然a.php和b.php在同一目錄下。
// a.php
<?php
function a() {
include("b.php");
}
a();
本意是想輸出"something new",但實際上卻是輸出"something"。
把include的文件內容代入,相當於下面的代碼:
<?php
function a() {
$b = "something";
function b() {
global $b;
$b = "something new";
}
b();
echo $b;
}
a();
第5行的$b取的是整個a.php文件中的全局$b,而不是第3行定義的$b,所以並沒有改變第3行的$b的值,於是第9行執行echo $b時,輸出的是"something"。
解決方法,將b.php中的"$b = something;"前加入一行"global $b;",就會輸出"something new"了。
使用require() 、require_once()、 include_once()的效果,跟include()的一樣。