波哥教你學PHP7之四:PHP變量與常量

變量

自定義變量

PHP變量用$加變量名來表示,注意變量名區分大小寫,這意味著,如下兩個變量是不一樣的。

$a = 'abc';
$A = 'def';

var_dump($a, $A);

有效的變量名是字母下劃線開頭,后面任意位字母下劃線數字。

$__abc = ''; // 合法
$A__   = ''; // 合法
$中國   = '我的中國心'; // 合法,但不建議用
$.abc  = ''; // 不合法
$ab*   = ''; // 不合法

$this 是一個特殊的變量,不能被賦值。在《類與對象》里,表示自己。

Class Human {
    public $populationNumber = 72; /* populationNumber 作為類變量定義時前有 $ 符號 */

    public function print($str) {
        echo $str;
    }

    public function population()
    {
        $populationNumber = $this->populationNumber; /* populationNumber 用 $this 調用時無 $ 符號 */
        $this->print("世界人口太多了,目前有{$populationNumber}億了\n");
    }
}

(new Human())->population();

未定義值時,變量實際為NULL
變量的引用示例。打印出來的$var1和$var2變量是一樣的。

$var1 = '中國';
$var2 = &$var1;
$var1 = $var1 . '風景很好' . "\n";

echo $var1;
echo $var2;

預定義變量

預定義變量,可以直接使用。為PHP內置的一些變量。后續教程會慢慢用到這些預定義變量。
比較常用的為$_GET、$_POST、$_SESSION、$_COOKIE、$_SERVER。后續會在實際的應用場景中一一演示。

  1. $GLOBALS — 引用全局作用域中可用的全部變量
  2. $_SERVER — 服務器和執行環境信息
  3. $_GET — HTTP GET 變量
  4. $_POST — HTTP POST 變量
  5. $_FILES — HTTP 文件上傳變量
  6. $_REQUEST — HTTP Request 變量
  7. $_SESSION — Session 變量
  8. $_ENV — 環境變量
  9. $_COOKIE — HTTP Cookies
  10. $php_errormsg — 前一個錯誤信息
  11. $HTTP_RAW_POST_DATA — 原生POST數據
  12. $http_response_header — HTTP 響應頭
  13. $argc — 傳遞給腳本的參數數目
  14. $argv — 傳遞給腳本的參數數組

預定義變量示例,請在瀏覽器中訪問 http://localhost/phpstudy/example_17.php?name=Mary&age=18

<?php
/* example_17.php */

/* 預定義變量 */

var_dump('<pre>', $_GET);
var_dump('<pre>', $_SERVER);

可變變量

可變變量就是把一個變量的值作為變量的名稱,在一些場景下會用到。具體說明見如下代碼

/* 可變變量 */

$hello = 'kitty';
$$hello = "is a Cat"; // 實際上定義了一個變量  $kitty

echo "$hello ${$hello} \n";
echo "$hello $kitty \n";

/* 可變類屬性 */
class V
{
    public $a = 'I am a';
    public $b = ['I am b0', 'I am b1', 'I am b2'];
    public $c = 'I am c';
    public $abc = 'I am abc';
}

$v = new V();
$attr1 = 'a';
$attr2 = ['a', 'b', 'c', 'd'];
$attr3 = 'abc';

echo $v->$attr1 . "\n"; // $attr1 是 a 所以 $v->a 就是 I am a
// echo $v->$attr2[0] . "\n"; // only php5
echo $v->{$attr2[0]} . "\n"; // php7 & php5 {$attr2[0]} 是 b
echo $v->$attr3 . "\n";
echo $v->{$attr3[1]}[1] . "\n"; // {$attr3[1]} 是 b 所以 $v->b[1] 就是 I am b1

在命令行下輸出:

kitty is a Cat 
kitty is a Cat 
I am a
I am a
I am abc
I am b1

靜態變量

假設我們想實現一個函數運行一次就自增1,nonStatic方法就無法達到。但使用了靜態變量的 staticVar 就可以實現。靜態變量也可以用于類,S類里的 a 屬性就是靜態屬性,所以不管實例化多少次,只要運行了add就會自動加1。

function nonStatic()
{
    $a = 1;
    echo $a . "\n";
    $a ++;
}

nonStatic(); // 1
nonStatic(); // 1

function staticVar()
{
    static $a = 1;
    echo $a . "\n";
    $a ++;
}

staticVar(); // 1
staticVar(); // 2
staticVar(); // 3

class S
{
    public static $a = 1;

    public function add() {
        echo self::$a . "\n";
        self::$a ++;
    }
}

$s1 = new S();
$s1->add(); // 1

$s2 = new S();
$s2->add(); // 2 

(new S())->add(); // 3

變量的作用域

如下示例可以看到,在函數(類)外層定義的變量,是無法直接在函數內部直接使用的,只有使用特定的關鍵詞或者預定義變量才可以訪問。函數內部定義的變量在外面也無法訪問。
如果使用include require等文件包含函數 比如 a.php 里 包含了 b.php 可以把兩個文件看成一個拼合后的文件,再思考變量的作用域。

/* 變量的作用域 */
$zone1 = 11;
$zone2 = 12;
$zone3 = 13;

function zoneFun() {
    echo $zone1 . "\n"; // 無法訪問到方法外層的 $zone1

    global $zone2; // 用 global 可以使用方法外層的 $zone2
    echo $zone2 . "\n";

    echo $GLOBALS['zone3'] . "\n"; // 也可以直接使用預定義變量 $GLOBALS 來訪問

    $zone4 = 14; // 方法內的局部變量
}

zoneFun();

echo $zone4 . "\n"; // zoneFun函數里定義的變量,方法外層也無法訪問到。

輸出結果如下:

Notice: Undefined variable: zone1

12
13

Notice: Undefined variable: zone4

常量

常量是一種預先定義好,運行時不可以后期再修改的類型。一個常量一旦被定義,就不能再改變或者取消定義。比如圓周率,比如光速,都是一些固定值,提前定義好就行了,可以不用像變量一樣去定義。

一般常量

一般的常量都是用全大寫字母下劃線來表示,并且沒有$前綴。常量是全局變量,可以像$GLOBALS一樣隨處使用。如下示例,我們可以用 define 和 const 來定義常量,可以用 defined 來判斷是否定義了某個常量。get_defined_constants(true)['user'] 可以獲取所有我們在代碼里定義的常量。如果常量名是動態的,也可以用函數 constant() 來獲取常量的值。

<?php
/* example_18.php */

define('PI', 3.1415926);
define('COLOR_LIST', ['red', 'green']); // PHP7 only 之前的版本不可以定義數組
const SEX = ['男', '女'];

// 如果沒有定義 SEX 就再定義一下
if (!defined('SEX')) {
    define('SEX', ['男', '女']);
}

var_dump(constant('PI'));
var_dump(SEX, COLOR_LIST);
var_dump(get_defined_constants(true)['user']);

運行的結果如下:

float(3.1415926)
array(2) {
  [0]=>
  string(3) "男"
  [1]=>
  string(3) "女"
}
array(2) {
  [0]=>
  string(3) "red"
  [1]=>
  string(5) "green"
}
array(3) {
  ["PI"]=>
  float(3.1415926)
  ["COLOR_LIST"]=>
  array(2) {
    [0]=>
    string(3) "red"
    [1]=>
    string(5) "green"
  }
  ["SEX"]=>
  array(2) {
    [0]=>
    string(3) "男"
    [1]=>
    string(3) "女"
  }
}

魔術常量

在PHP運行時,我們可以使用一些魔術常量來方便我們的工作,這些魔術常量是由PHP本身定義的。魔術常量同樣的名字在不同的環境下,得到的結果是不一樣的。如下可以看到魔術常量由兩個下劃線加名稱再加兩個下劃線組成。

__LINE__        文件中的當前行號。
__FILE__        文件的完整路徑和文件名。如果用在被包含文件中,則返回被包含的文件名。
__DIR__         文件所在的目錄。如果用在被包括文件中,則返回被包括的文件所在的目錄。除非是根目錄,否則目錄中名不包括末尾的斜杠。(PHP 5.3.0中新增)
__FUNCTION__    函數名稱(區分大小寫)
__CLASS__       類的名稱(區分大小寫)。類名包括其被聲明的作用區域(例如 Foo\Bar)
__TRAIT__       Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4 起此常量返回 trait 被定義時的名字(區分大小寫)。Trait 名包括其被聲明的作用區域(例如 Foo\Bar)。
__METHOD__      類的方法名(PHP 5.0.0 新加)。返回該方法被定義時的名字(區分大小寫)。
__NAMESPACE__   當前命名空間的名稱(區分大小寫)。此常量是在編譯時定義的(PHP 5.3.0 新增)。

一個比較詳細的例子如下,分析結果,可以更容易的掌握這些魔術常量

<?php
/* example_19.php */
namespace utils;

echo '這是第' . __LINE__ . "行\n";
echo '這是第' . __LINE__ . "行\n";
echo '當前文件目錄:' . __DIR__ . "\n";
echo '當前文件路徑:' . __FILE__ . "\n";

function whatIsMyName()
{
    echo '函數名是:' . __FUNCTION__ . "\n";
}

whatIsMyName();

// Tool trait
trait Tool
{
    public function getBall()
    {
        echo '函數名:' . __FUNCTION__ . "\n";
        echo '類名是:' . __CLASS__ . "\n";
        echo '函數名:' . __METHOD__ . "\n";
        echo '命名空間:' . __NAMESPACE__ . "\n";
        echo 'TRAIT:' . __TRAIT__ . "\n";
    }
}

// 檢查類
class Checker
{
    use Tool;

    public function isQQ()
    {
        echo '函數名:' . __FUNCTION__ . "\n";
        echo '類名是:' . __CLASS__ . "\n";
        echo '函數名:' . __METHOD__ . "\n";
        echo '命名空間:' . __NAMESPACE__ . "\n";

        echo "下面是trait里的結果:\n";
        $this->getBall();
    }
}

(new Checker)->isQQ();

運行結果如下:

這是第5行
這是第6行
當前文件目錄:/phpstudy
當前文件路徑:/phpstudy/example_19.php
函數名是:utils\whatIsMyName
函數名:isQQ
類名是:utils\Checker
函數名:utils\Checker::isQQ
命名空間:utils
下面是trait里的結果:
函數名:getBall
類名是:utils\Checker
函數名:utils\Tool::getBall
命名空間:utils
TRAIT:utils\Tool
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,643評論 2 380

推薦閱讀更多精彩內容

  • 一、php可以做什么 php是一種可以在服務器端運行的編程語言,可以運行在Web服務器端。 php是一門后臺編程語...
    空谷悠閱讀 3,133評論 4 97
  • php基礎 基本語法形式 區分大小寫 主要是指變量名區分大小寫 常量通常也區分,但常量也可以自己設定為不區分(不推...
    代碼與藝術閱讀 1,049評論 1 12
  • php可以做什么 php是一種可以在服務器端運行的編程語言,可以運行在Web服務器端。 php是一門后臺編程語言,...
    dptms閱讀 1,923評論 1 15
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,836評論 18 139
  • php.ini設置,上傳大文件: post_max_size = 128Mupload_max_filesize ...
    bycall閱讀 6,820評論 3 64