echo 和 print 區別:
- echo - 可以輸出一個或多個字符串
- print - 只允許輸出一個字符串,返回值總為 1
提示:echo 輸出的速度比 print 快, echo 沒有返回值,print有返回值1。
- 變量名必須以字母或者下劃線字符開始
- 變量名只能包含字母數字字符以及下劃線(A-z、0-9 和 _ )
- 變量名是區分大小寫的($y 和 $Y 是兩個不同的變量)
PHP 是一門弱類型語言
PHP 會根據變量的值,自動把變量轉換為正確的數據類型。
在強類型的編程語言中,我們必須在使用變量前先聲明(定義)變量的類型和名稱。
在所有函數外部定義的變量,擁有全局作用域。除了函數外,全局變量可以被腳本中的任何部分訪問,要在一個函數中訪問一個全局變量,需要使用 global 關鍵字。
當一個函數完成時,它的所有變量通常都會被刪除。然而,有時候您希望某個局部變量不要被刪除。
要做到這一點,請在您第一次聲明變量時使用 static 關鍵字:
PHP EOF(heredoc) 使用說明
- 1. 必須後接分號,否則編譯通不過。
- 2. EOF 可以用任意其它字符代替,只需保證結束標識與開始標識一致。
- 3. 結束標識必須頂格獨自佔一行(即必須從行首開始,前後不能銜接任何空白和字符)。
- 4. 開始標識可以不帶引號或帶單雙引號,不帶引號與帶雙引號效果一致,解釋內嵌的變量和轉義符號,帶單引號則不解釋內嵌的變量和轉義符號。
- 5. 當內容需要內嵌引號(單引號或雙引號)時,不需要加轉義符,本身對單雙引號轉義,此處相當與q和qq的用法。
- 1.以 <<
- 2.開始標記和結束標記相同,比如常用大寫的 EOT、EOD、EOF 來表示,但是不只限於那幾個(也可以用:JSON、HTML等),只要保證開始標記和結束標記不在正文中出現即可。
- 3.位於開始標記和結束標記之間的變量可以被正常解析,但是函數則不可以。在 heredoc 中,變量不需要用連接符 . 或 , 來拼接
整型可以用三種格式來指定:十進制, 十六進制( 以 0x 為前綴)或八進制(前綴為 0)。
可以通過設置變量值為 NULL 來清空變量數據:
一個常量由英文字母、下劃線、和數字組成,但數字不能作為首字母出現。 (常量名不需要加 $ 修飾符)。
注意: 常量在整個腳本中都可以使用。
strpos() 函數用於在字符串內查找一個字符或一段指定的文本。
如果在字符串中找到匹配,該函數會返回第一個匹配的字符位置。如果未找到匹配,則返回 FALSE。
自 PHP 5.3 起,可以省略三元運算符中間那部分。表達式 expr1 ?: expr3 在 expr1 求值為 TRUE 時返回 expr1,否則返回 expr3。
注意:PHP_EOL 是一個換行符,兼容更大平臺。
運算符的等級
必須要注意的是 elseif 與 else if 只有在使用花括號的情況下才認為是完全相同。如果用冒號來定義 if/elseif 條件,那就不能用兩個單詞的 else if,否則 PHP 會產生解析錯誤。 詳見 http://php.net/manual/zh/control-structures.elseif.php
- 數值數組 - 帶有數字 ID 鍵的數組
- 關聯數組 - 帶有指定的鍵的數組,每個鍵關聯一個值
- 多維數組 - 包含一個或多個數組的數組
- sort() - 對數組進行升序排列
- rsort() - 對數組進行降序排列
- asort() - 根據關聯數組的值,對數組進行升序排列
- ksort() - 根據關聯數組的鍵,對數組進行升序排列
- arsort() - 根據關聯數組的值,對數組進行降序排列
- krsort() - 根據關聯數組的鍵,對數組進行降序排列
PHP 超級全局變量列表:
- $GLOBALS
- $_SERVER
- $_REQUEST
- $_POST
- $_GET
- $_FILES
- $_ENV
- $_COOKIE
- $_SESSION
do...while 語句
- 函數名稱以字母或下劃線開頭(不能以數字開頭)
PHP 魔術常量
PHP 向它運行的任何腳本提供了大量的預定義常量。
不過很多常量都是由不同的擴展庫定義的,只有在加載了這些擴展庫時才會出現,或者動態加載後,或者在編譯時已經包括進去了。
有八個魔術常量它們的值隨著它們在代碼中的位置改變而改變。
例如 __LINE__ 的值就依賴於它在腳本中所處的行來決定。這些特殊的常量不區分大小寫
__LINE__
__FILE__
__DIR__
__FUNCTION__
__CLASS__
__TRAIT__
__METHOD__
__NAMESPACE__
自 PHP 5.4.0 起,PHP 實現了代碼複用的一個方法,稱為 traits
優先順序是當前類中的方法會覆蓋 trait 方法,而 trait 方法又覆蓋了基類中的方法
PHP 命名空間(namespace)是在PHP 5.3中加入的
PHP 命名空間可以解決以下兩類問題:
- 用戶編寫的代碼與PHP內部的類/函數/常量或第三方類/函數/常量之間的名字衝突。
- 為很長的標識符名稱(通常是為了緩解第一類問題而定義的)創建一個別名(或簡短)的名稱,提高源代碼的可讀性。
如果一個文件中包含命名空間,它必須在其它所有代碼之前聲明命名空間
在聲明命名空間之前唯一合法的代碼是用於定義源文件編碼方式的 declare 語句
declare(encoding='UTF-8'); //定義多個命名空間和不包含在命名空間中的代碼
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace MyProject; // 命名空間前出現了“” 會致命錯誤 - 命名空間必須是程序腳本的第一條語句
?>
對象的3大特性:封裝、繼承,多態
- public(公有):公有的類成員可以在任何地方被訪問。
- protected(受保護):受保護的類成員則可以被其自身以及其子類和父類訪問。
- private(私有):私有的類成員則只能被其定義所在的類訪問。
PHP 不會在子類的構造方法中自動的調用父類的構造方法。要執行父類的構造方法,需要在子類的構造方法中調用 parent::__construct(),但是如果子類沒有構造方法的話會自動繼承父類的構造方法
PHP 5 新增了一個 final 關鍵字。如果父類中的方法被聲明為 final,則子類無法覆蓋該方法。如果一個類被聲明為 final,則不能被繼承
聲明類屬性或方法為 static(靜態),就可以不實例化類而直接訪問。
靜態屬性不能通過一個類已實例化的對象來訪問(但靜態方法可以)。
由於靜態方法不需要通過對象即可調用,所以偽變量 $this 在靜態方法中不可用。
靜態屬性不可以由對象通過 -> 操作符來訪問。
自 PHP 5.3.0 起,可以用一個變量來動態調用類。但該變量的值不能為關鍵字 self,parent 或 static。
class Foo {
public static $my_static = 'foo';
public function staticValue() {
return self::$my_static;
}
public static function getValue() {
return self::$my_static;
}
}
print Foo::$my_static . PHP_EOL;
$foo = new Foo();
print $foo->staticValue() . PHP_EOL;
print $foo::staticValue() . PHP_EOL;
print $foo->getValue() . PHP_EOL;
print $foo::getValue() . PHP_EOL;
?>
可以把在類中始終保持不變的值定義為常量。在定義和使用常量的時候不需要使用 $ 符號
接口
使用接口(interface),可以指定某個類必須實現哪些方法,但不需要定義這些方法的具體內容。
接口是通過 interface 關鍵字來定義的,就像定義一個標準的類一樣,但其中定義所有的方法都是空的。
接口中定義的所有方法都必須是公有,這是接口的特性。
要實現一個接口,使用 implements 操作符。類中必須實現接口中定義的所有方法,否則會報一個致命錯誤。類可以實現多個接口,用逗號來分隔多個接口的名稱。
抽象類
任何一個類,如果它裡面至少有一個方法是被聲明為抽象的,那麼這個類就必須被聲明為抽象的。
定義為抽象的類不能被實例化。
被定義為抽象的方法只是聲明瞭其調用方式(參數),不能定義其具體的功能實現。
繼承一個抽象類的時候,子類必須定義父類中的所有抽象方法;另外,這些方法的訪問控制必須和父類中一樣(或者更為寬鬆)。例如某個抽象方法被聲明為受保護的,那麼子類中實現的方法就應該聲明為受保護的或者公有的,而不能定義為私有的。
子類方法可以包含父類抽象方法中不存在的可選參數。
抽象類和接口的概念要分清楚,容易混淆
命名空間的理解有深度,需要花點力氣學習下
PHP 命名空間中的類名可以通過三種方式引用:
- 非限定名稱,或不包含前綴的類名稱,例如 $a=new foo(); 或 foo::staticmethod();。如果當前命名空間是 currentnamespace,foo 將被解析為 currentnamespace\foo。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,則 foo 會被解析為foo。 警告:如果命名空間中的函數或常量未定義,則該非限定的函數名稱或常量名稱會被解析為全局函數名稱或常量名稱。
- 限定名稱,或包含前綴的名稱,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果當前的命名空間是 currentnamespace,則 foo 會被解析為 currentnamespace\subnamespace\foo。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,foo 會被解析為subnamespace\foo。
- 完全限定名稱,或包含了全局前綴操作符的名稱,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在這種情況下,foo 總是被解析為代碼中的文字名(literal name)currentnamespace\foo。
注意訪問任意全局類、函數或常量,都可以使用完全限定名稱,例如 \strlen() 或 \Exception 或 \INI_ALL。
在命名空間內部訪問全局類、函數和常量:
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
$a = \strlen('hi'); // 調用全局函數strlen
$b = \INI_ALL; // 訪問全局常量 INI_ALL
$c = new \Exception('error'); // 實例化全局類 Exception
?>
關鍵字 namespace 可用來顯式訪問當前命名空間或子命名空間中的元素。它等價於類中的 self 操作符。
namespace操作符,命名空間中的代碼
namespace MyProject;
use blah\blah as mine; // see "Using namespaces: importing/aliasing"
blah\mine(); // calls function blah\blah\mine()
namespace\blah\mine(); // calls function MyProject\blah\mine()
namespace\func(); // calls function MyProject\func()
namespace\sub\func(); // calls function MyProject\sub\func()
namespace\cname::method(); // calls static method "method" of class MyProject\cname
$a = new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname
$b = namespace\CONSTANT; // assigns value of constant MyProject\CONSTANT to $b
?>
使用命名空間:別名/導入
PHP 命名空間支持 有兩種使用別名或導入方式:為類名稱使用別名,或為命名空間名稱使用別名。
在PHP中,別名是通過操作符 use 來實現的. 下面是一個使用所有可能的三種導入方式的例子:
1、使用use操作符導入/使用別名
namespace foo;
use My\Full\Classname as Another;
// 下面的例子與 use My\Full\NSname as NSname 相同
use My\Full\NSname;
// 導入一個全局類
use \ArrayObject;
$obj = new namespace\Another; // 實例化 foo\Another 對象
$obj = new Another; // 實例化 My\Full\Classname 對象
NSname\subns\func(); // 調用函數 My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // 實例化 ArrayObject 對象
// 如果不使用 "use \ArrayObject" ,則實例化一個 foo\ArrayObject 對象
?>
導入操作是在編譯執行的,但動態的類名稱、函數名稱或常量名稱則不是。
3、導入和動態名稱
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // 實例化一個 My\Full\Classname 對象
$a = 'Another';
$obj = new $a; // 實際化一個 Another 對象
?>
全局空間
如果沒有定義任何命名空間,所有的類與函數的定義都是在全局空間,與 PHP 引入命名空間概念前一樣。在名稱前加上前綴 \ 表示該名稱是全局空間中的名稱,即使該名稱位於其它的命名空間中時也是如此。
使用全局空間說明
namespace A\B\C;
/* 這個函數是 A\B\C\fopen */
function fopen() {
/* ... */
$f = \fopen(...); // 調用全局的fopen函數
return $f;
}
?>
名稱解析遵循下列規則:
- 對完全限定名稱的函數,類和常量的調用在編譯時解析。例如 new \A\B 解析為類 A\B。
- 所有的非限定名稱和限定名稱(非完全限定名稱)根據當前的導入規則在編譯時進行轉換。例如,如果命名空間 A\B\C 被導入為 C,那麼對 C\D\e() 的調用就會被轉換為 A\B\C\D\e()。
- 在命名空間內部,所有的沒有根據導入規則轉換的限定名稱均會在其前面加上當前的命名空間名稱。例如,在命名空間 A\B 內部調用 C\D\e(),則 C\D\e() 會被轉換為 A\B\C\D\e() 。
- 非限定類名根據當前的導入規則在編譯時轉換(用全名代替短的導入名稱)。例如,如果命名空間 A\B\C 導入為C,則 new C() 被轉換為 new A\B\C() 。
- 在命名空間內部(例如A\B),對非限定名稱的函數調用是在運行時解析的。例如對函數 foo() 的調用是這樣解析的:
- 在當前命名空間中查找名為 A\B\foo() 的函數
- 嘗試查找並調用 全局(global) 空間中的函數 foo()。
- 在命名空間(例如A\B)內部對非限定名稱或限定名稱類(非完全限定名稱)的調用是在運行時解析的。下面是調用 new C() 及 new D\E() 的解析過程: new C()的解析:
- 在當前命名空間中查找A\B\C類。
- 嘗試自動裝載類A\B\C。
- new D\E()的解析:
- 在類名稱前面加上當前命名空間名稱變成:A\B\D\E,然後查找該類。
- 嘗試自動裝載類 A\B\D\E。
- 為了引用全局命名空間中的全局類,必須使用完全限定名稱 new \C()。
閱讀更多 美食代碼喵 的文章