php 語言總結:基礎文法 類型 常量 運算子 流程式控制制 函數 類與對象 命名空間 超全域變數 記憶體回收機制
1 基本文法
*php標記
echo "Hello world";
// ... more code
echo "Last statement";
// 指令碼至此結束,並無 PHP 結束標記
注意:如果檔案內容是純 PHP 代碼,最好在檔案末尾刪除 PHP 結束標記。
這可以避免在 PHP 結束標記之後萬一意外加入了空格或者分行符號,會導致 PHP 開始輸出這些空白,
而指令碼中此時並無輸出的意圖。
*從html中分離
This will show if the expression is true.
Otherwise this will show.
2 類型
*簡介
PHP 支援 8 種未經處理資料類型。
四種標量類型:
boolean(布爾型)
integer(整型)
float(浮點型,也稱作 double)
string(字串)
兩種複合類型:
array(數組)
object(對象)
最後是兩種特殊類型:
resource(資源)
NULL(無類型)
Note:查看錶達式的值和類型,用 var_dump() 函數,擷取類型用gettype(),判斷是否為某個類型is_type()
*boolean
要指定一個布爾值,使用關鍵字 TRUE 或 FALSE。兩個都不區分大小寫
當轉換為 boolean 時,以下值被認為是 FALSE:
布爾值 FALSE 本身
整型值 0(零)
浮點型值 0.0(零)
Null 字元串,以及字串 "0"
不包括任何元素的數組
var_dump((bool) ""); // bool(false)
var_dump((bool) 1); // bool(true)
var_dump((bool) -2); // bool(true)
var_dump((bool) "foo"); // bool(true)
var_dump((bool) 2.3e5); // bool(true)
var_dump((bool) array(12)); // bool(true)
var_dump((bool) array()); // bool(false)
var_dump((bool) "false"); // bool(true)
?>
*integer
最大值可以用常量 PHP_INT_MAX 來表示
*float
*string
單引號:不會解析裡面的變數
雙引號:會解析裡面的變數
(如果沒有變數那麼建議使用單引號這樣效率會更高點,因為不用解析裡面的內容)
複雜(花括弧):只需簡單地像在 string 以外的地方那樣寫出運算式,然後用花括弧 { 和 } 把它括起來即可
// 有效,當在字串中使用多重數組時,一定要用括弧將它括起來
echo "This works: {$arr['foo'][3]}";
// 有效
echo "This works: " . $arr['foo'][3];
?>
*array
// 建立一個簡單的數組
$array = array(1, 2, 3, 4, 5);
print_r($array);
// 現在刪除其中的所有元素,但保持數組本身不變:
foreach ($array as $i => $value) {
unset($array[$i]);
}
print_r($array);
//刪除整個數組unset($array)
?>
*object
要建立一個新的對象 object,使用 new 語句執行個體化一個類:
class foo
{
function do_foo()
{
echo "Doing foo.";
}
}
$bar = new foo;
$bar->do_foo();
?>
*resource
像資料庫連接就會返回一個資源
*null
NULL 類型只有一個值,就是不區分大小寫常量 NULL。
在下列情況下一個變數被認為是 NULL:
被賦值為 NULL。
尚未被賦值。
被 unset()。
判斷是否為null,使用is_null()
2 變數
*基礎
$this 是一個特殊的變數,它不能被賦值
變數預設總是傳值賦值,也有引用變數,這就意味著改動新變數將影響到原始的變數
*預定義變數
*變數範圍
在使用者自訂函數中,一個局部函數範圍將被引入。任何用於函數內部的變數按預設情況將被限制在局部函數範圍內
$a = 1; /* global scope */
function Test()
{
echo $a; /* reference to local scope variable */
}
Test();
?>
和 C 語言有一點點不同,在 C 語言中,全域變數在函數中自動生效,除非被局部變數覆蓋。
PHP 中全域變數在函數中使用時必須聲明為 global
$a = 1;
$b = 2;
function Sum()
{
global $a, $b;
$b = $a + $b;
}
Sum();
echo $b;
?>
態變數僅在局部函數域中存在,但當程式執行離開此範圍時,其值並不丟失
function test()
{
static $a = 0;
echo $a;
$a++;
}
?>
*可變變數
$a = 'hello';
$$a = 'world';
echo "$a ${$a}";
//與以下語句輸出完全相同的結果:
echo "$a $hello";
?>
*來自php之外的變數
$_POST $_GET
3 常量
// 合法的常量名
define("FOO", "something");
define("FOO2", "something else");
define("FOO_BAR", "something more");
// 非法的常量名
define("2FOO", "something");
// 下面的定義是合法的,但應該避免這樣做:(自訂常量不要以__開頭)
// 也許將來有一天PHP會定義一個__FOO__的魔術常量
// 這樣就會與你的代碼相衝突
define("__FOO__", "something");
?>
4 運算子
*優先順序
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2
$a = 1;
$b = 2;
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5
?>
*錯誤運算子
支援一個錯誤控制運算子:@,該運算式可能產生的任何錯誤資訊都被忽略掉。
*執行運算子
注意這不是單引號!PHP 將嘗試將反引號中的內容作為外殼命令來執行,並將其輸出資訊返回
使用反引號運算子“`”的效果與函數 shell_exec() 相同。
$output = `ls -al`;
echo "
$output
";
?>
結果:將檔案目錄結構輸出來
*字串串連運算子
有兩個字串(string)運算子。第一個是串連運算子(“.”),它返回其左右參數串連後的字串。
第二個是串連賦值運算子(“.=”),它將右邊參數附加到左邊的參數之後
$a = "Hello ";
$b = $a . "World!"; // now $b contains "Hello World!"
$a = "Hello ";
$a .= "World!"; // now $a contains "Hello World!"
?>
*數組運算子
$a + $b 聯合 $a 和 $b 的聯合。
$a == $b 相等 如果 $a 和 $b 具有相同的鍵/值對則為 TRUE。
$a === $b 全等 如果 $a 和 $b 具有相同的鍵/值對並且順序和類型都相同則為 TRUE。
$a != $b 不等 如果 $a 不等於 $b 則為 TRUE。
$a <> $b 不等 如果 $a 不等於 $b 則為 TRUE。
$a !== $b 不全等 如果 $a 不全等於 $b 則為 TRUE。
+ 運算子把右邊的數組元素附加到左邊的數組後面,兩個數組中都有的鍵名,則只用左邊數組中的,右邊的被忽略。
$a = array("a" => "apple", "b" => "banana");
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
$c = $a + $b; // Union of $a and $b
echo "Union of \$a and \$b: \n";
var_dump($c);
$c = $b + $a; // Union of $b and $a
echo "Union of \$b and \$a: \n";
var_dump($c);
?>
數組中的單元如果具有相同的鍵名和值則比較時相等
$a = array("apple", "banana");
$b = array(1 => "banana", "0" => "apple");
var_dump($a == $b); // bool(true)
var_dump($a === $b); // bool(false)
?>
*類型運算子
instanceof 用於確定一個 PHP 變數是否屬於某一類 class 的執行個體
class MyClass
{
}
class NotMyClass
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof NotMyClass);
?>
五:流程式控制制
*if else
*流程式控制制代替文法
PHP 提供了一些流程式控制制的替代文法,包括 if,while,for,foreach 和 switch。
替代文法的基本形式是把左花括弧({)換成冒號(:),把右花括弧(})分別換成
endif;,endwhile;,endfor;,endforeach; 以及 endswitch;。
A is equal to 5
*while
while (expr):
statement
...
endwhile;
* for
$people = Array(
Array('name' => 'Kalle', 'salt' => 856412),
Array('name' => 'Pierre', 'salt' => 215863)
);
for($i = 0, $size = sizeof($people); $i < $size; ++$i)
{
$people[$i]['salt'] = rand(000000, 999999);
}
?>
*foreach
可以很容易地通過在 $value 之前加上 & 來修改數組的元素。
此方法將以引用賦值而不是拷貝一個值。
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value); // 最後取消掉引用
?>
*require 和 include
require 出錯是會停止指令碼程式,include 會產生警告
require_once和require 基本一樣,唯一的區別是唯一區別是 PHP 會檢查該檔案是否
已經被包含過,如果是則不會再次包含。
六 函數
*可變函數
可變函數類似於可變變數
這意味著如果一個變數名後有圓括弧,PHP 將尋找與變數的值同名的函數,並且嘗試執行它。
可變函數可以用來實現包括回呼函數,函數表在內的一些用途
function foo() {
echo "In foo()
\n";
}
function bar($arg = '') {
echo "In bar(); argument was '$arg'.
\n";
}
// 使用 echo 的封裝函數
function echoit($string)
{
echo $string;
}
$func = 'foo';
$func(); // This calls foo()
$func = 'bar';
$func('test'); // This calls bar()
$func = 'echoit';
$func('test'); // This calls echoit()
?>
*匿名函數
echo preg_replace_callback('~-([a-z])~', function ($match) {
return strtoupper($match[1]);
}, 'hello-world');
// 輸出 helloWorld
?>
七 類與對象
*基本概念
$this 是一個到主叫對象的引用(通常是該方法所從屬的對象)
*屬性
在類的成員方法裡面,可以用 ->(對象運算子):$this->property(其中 property 是該屬性名稱)這種方式來訪問非靜態屬性。
靜態屬性則是用 ::(雙冒號):self::$property 來訪問。更多靜態屬性與非靜態
*類常量
可以把在類中始終保持不變的值定義為常量
class MyClass
{
const constant = 'constant value';
}
?>
*自動載入類
*Static 靜態關鍵字
聲明類屬性或方法為靜態,就可以不執行個體化類而直接存取。靜態屬性不能通過一個類已執行個體化的對象來訪問(但靜態方法可以)
因為靜態方法在編譯前就被載入了,所有就不能訪問非靜態方法,因為他們還不存在
*抽象類別
任何一個類,如果它裡面至少有一個方法是被聲明為抽象的,那麼這個類就必須被聲明為抽象的
*介面
使用介面(interface),可以指定某個類必須實現哪些方法,但不需要定義這些方法的具體內容。
*traits
Trait 和一個類相似,但僅僅旨在用細粒度和一致的方式來組合功能。
Trait 不能通過它自身來執行個體化。它為傳統繼承增加了水平特性的組合;
也就是說,應用類的成員不需要繼承。
trait ezcReflectionReturnInfo {
function getReturnType() { /*1*/ }
function getReturnDescription() { /*2*/ }
}
class ezcReflectionMethod extends ReflectionMethod {
use ezcReflectionReturnInfo;
/* ... */
}
class ezcReflectionFunction extends ReflectionFunction {
use ezcReflectionReturnInfo;
/* ... */
}
?>
*遍曆對象
*final關鍵字
如果父類中的方法被聲明為 final,則子類無法覆蓋該方法。如果一個類被聲明為 final,則不能被繼承。
*對象複製
*對象比較
當使用比較子(==)比較兩個物件變數時,比較的原則是:如果兩個對象的屬性和屬性值 都相等,
而且兩個對象是同一個類的執行個體,那麼這兩個物件變數相等。
而如果使用全等運算子(===),這兩個物件變數一定要指向某個類的同一個執行個體(即同一個對象)。
*後期靜態繫結
*對象和引用
一個關鍵點是“預設情況下對象是通過引用傳遞的”。但其實這不是完全正確的。下面通過一些例子來說明。
*對象系列化
所有php裡面的值都可以使用函數serialize()來返回一個包含位元組流的字串來表示。unserialize()函數能夠重新把字串變回php原來的值。
序列化一個對象將會儲存對象的所有變數,但是不會儲存對象的方法,只會儲存類的名字
八 命名空間
*命名空間概述
使用者編寫的代碼與PHP內部的類/函數/常量或第三方類/函數/常量之間的名字衝突。
namespace my\name; // 參考 "定義命名空間" 小節
class MyClass {}
function myfunction() {}
const MYCONST = 1;
$a = new MyClass;
$c = new \my\name\MyClass; // 參考 "全域空間" 小節
$a = strlen('hi'); // 參考 "使用命名空間:後備全域函數/常量" 小節
$d = namespace\MYCONST; // 參考 "namespace操作符和__NAMESPACE__常量” 小節
$d = __NAMESPACE__ . '\MYCONST';
echo constant($d); // 參考 "命名空間和動態語言特徵" 小節
?>
*namespace關鍵字和__NAMESPACE__常量
namespace MyProject;
echo '"', __NAMESPACE__, '"'; // 輸出 "MyProject"
?>
*全域空間
如果沒有定義任何命名空間,所有的類與函數的定義都是在全域空間,
與 PHP 引入命名空間概念前一樣。在名稱前加上首碼 \ 表示該名稱是
全域空間中的名稱,即使該名稱位於其它的命名空間中時也是如此。
namespace A\B\C;
/* 這個函數是 A\B\C\fopen */
function fopen() {
/* ... */
$f = \fopen(...); // 調用全域的fopen函數
return $f;
}
?>
九 超全域變數
$GLOBALS
$_SERVER
$_GET
$_POST
$_FILES
$_COOKIE
$_SESSION
$_REQUEST
$_ENV
十 記憶體回收機制
* 引用計數器,每個php變數都儲存在一個叫“zval”的變數容器中,除了包含變數的類型和值,
還包括兩個位元組的額外資訊,第一個是“is_ref”是一個bool 值 用來標識是否屬於引用集合
第二個額外的位元組是refcount 用於統計引用次數
$a = "new string";
xdebug_debug_zval('a');
?>
結果:a: (refcount=1, is_ref=0)='new string'
* 如果一個引用計數增加 它將繼續唄使用,如果引用計數減少到0,所在變數容器將唄清零(free)