一篇PHP中動態特性學習筆記,如果你對于PHP 特性不了解的我們可以進入參考本文章,本文章對于PHP動態特性詳細的作了介紹了,好了費話不說了我們來看例子吧,有需要的朋友可參考一下.
本文主要總結給對PHP 特性不了解的新手看的,因此演示代碼占比較多的篇幅,大家看還缺哪些給補充吧,歡迎來郵件或在PHPChina 的《PHPer》雜志版塊糾正錯誤.
動態語言就是能夠在運行時改變程序結構和變量類型的語言,例如:新的類和對象可以被加載和創建,新的函數或方法可以加入和去除等等,比如Smalltalk、Ruby、Python、PHP、Lua、Perl、Groovy 等。反之則是靜態語言,比如C/C++、Java、C#等.
動態語言的動態特性決定它開發的時候需要更少的代碼,有更高的靈活性,PHP的動態特性奠定了它存在的價值,熟悉PHP 的動態特性讓我們更能活用PHP.
1 弱類型變量
動態語言都被設計成弱類型,也就是說變量被賦值以后才能確定它的數據類型,當代碼在實際執行時,才會檢測變量是否被非法使用.
PHP 變量是弱類型變量就意味著,我們不需要聲明變量的類型,在運行時自動檢測變量的類型,并且可以認為改動變量的類型.
2、PHP動態特性
特性1、弱類型變量
PHP變量是弱類型變量就意味著,我們不需要聲明變量的類型,在運行時自動檢測變量的類型,并且可以認為改動變量的類型,代碼如下:
- // PHP弱類型變量例子
- $test = 1;
- print gettype($test) . ": $testn";
- $test = 1.23456789;
- print gettype($test) . ": $testn";
- $test = 'test'; // 變量自動改變類型
- print gettype($test) . ": $testn";
- $test = array('t'=>'HI,I m from an array!');
- settype($test, 'object'); // 改變變量的類型
- print gettype($test) . ": {$test->t}n";
- // 測試變量類型
- if(is_object($test)) {
- print "Test Type: My Type Is object.n";
- } else {
- print gettype($test);
- }
弱類型并不意味著代碼不安全,或者不健壯,極限編程已經給成為一種軟件開發方法,這個方法側重測試,使用全面的單元測試方案來驅動開發過程,通過不同環境下執行所編寫的代碼,就可以保證代碼的安全性和健壯性,經驗證明,在弱類型語言中,綜合運用弱類型和單元測試通常比傳統系統編程語言的類型檢查更好.
特性2、可變變量
一個變量的變量名可以動態的設置和使用代碼如下:
- // 可變變量例子
- $var = 'hi';
- $$var = 'hello';
- print $var;
- print $$var;
- print $hi; // 等價于上一行
特性3、變量函數
這意味著如果一個變量名后有圓括號,PHP 將尋找與變量的值同名的函數,并且將嘗試執行它,除了別的事情以外,這個可以被用于實現回調函數,函數表等等,代碼如下:
- // 變量函數例子
- // 無參數函數
- function a(){
- print "i'm an";
- }
- // 有參數函數
- function b($param) {
- print "i'm b, param: $paramn";
- }
- $x = 'a';
- $x();
- $x = 'b';
- $x('xxxxxxxxxxx');
特性4、可變長度參數列表
調用函數的時候,函數的參數個數可以不一樣,代碼如下:
- function foo() {
- $numargs = func_num_args();
- print "Number of arguments: $numargsn";
- print "the third argument: " . func_get_arg(2) . "n";
- }
- foo(1, 2, '...@...');
- foo(1, 2, '############', 4);
特性5,從數組中導出變量
把數組中的數據復制出變量,將鍵名當作變量名,值作為變量的值,代碼如下:
- // 例1
- $a = array('x' => 100, 'y'=> 200, 'z' => 300);
- // 從數組中將變量導入到當前的符號表
- extract($a); // 和extract相反的函數是compact()
- print "$x $y $z";
- //開源軟件:Vevb.com
- // 例2
- $a = array(100, 200, 300);
- list($x, , $z) = $a;
- print "$x $z";
特性6,用一個數組的值作為其鍵名,另一個數組的值作為其值,創建一個數組,代碼如下:
- $a = array('green', 'red', 'yellow');
- $b = array('avocado', 'apple', 'banana');
- $c = array_combine($a, $b);
- print_r($c);
特性7,動態創建函數,代碼如下:
- // lambda函數
- $newfunc = create_function('$a,$b', 'return "$a + $b = " . $a + $b;'); // 創建了一個匿名函數
- print "nNew anonymous function: $newfuncn";
- print $newfunc(2, 4);
- print "n";
- // 效果類似于
- function test($a,$b){
- return "$a + $b = " . $a + $b;
- }
- print test(2, 4);
特性8、自動加載對象
可以定義一個 __autoload 函數,它會在試圖使用尚未被定義的類時自動調用,代碼如下:
- // ClassA.php, 這段代碼寫在ClassA.php
- class A {
- function __construct() {
- print 'yeah!';
- }
- }
- 5
- function __autoload($className) {
- require_once $className . '.php';
- }
- // 這段代碼寫在b.php
- new A(); // 程序運行到這里的時候,A類未定義,將自動調用__autoload()函數
特性9、__get和__set代替所有對屬性變量數組的訪問:
- class Setter{
- public $n;
- private $x = array("a" => 1, "b" => 2, "c" => 3);
- private function __get($nm) {
- echo "Getting [$nm]n";
- if (isset($this->x[$nm])) {
- $r = $this->x[$nm];
- print "Returning: $rn";
- return $r;
- } else {
- echo "Nothing!n";
- }
- }
- private function __set($nm, $val) {
- echo "Setting [$nm] to $valn";
- if (isset($this->x[$nm])) {
- $this->x[$nm] = $val;
- echo "OK!n";
- } else {
- echo "Not OK!n";
- }
- }
- private function __isset($nm) {
- echo "Checking if $nm is setn";
- return isset($this->x[$nm]);
- }
- private function __unset($nm) {
- echo "Unsetting $nmn";
- unset($this->x[$nm]);
- }
- }
- $foo = new Setter();
- $foo->n = 1;
- $foo->a = 100;
- $foo->a++;
- $foo->z++;
- var_dump(isset($foo->a)); //true
- unset($foo->a);
- var_dump(isset($foo->a)); //false
- // this doesn't pass through the __isset() method
- // because 'n' is a public property
- var_dump(isset($foo->n));
- var_dump($foo);
特性10、自定義未定義的方法
你調用未定義方法時,方法名和方法接收的參數將會傳給__call方法,代碼如下:
- class Caller {
- private $x = array(1, 2, 3);
- private function __call($m, $a) {
- print "Method $m called:n";
- print_r($a);
- return $this->x;
- }
- }
- $foo = new Caller();
- $a = $foo->test(1, "2", 3.4, true);
- print_r($a);
特性11、自定義錯誤、異常處理
設置使用自定義錯誤或異常處理函數后,當發生錯誤或異常時將調用自定義的處理函數代替系統錯誤處理函數,代碼如下:
- set_error_handler('error_handler'); // 設置錯誤時調用的自定義處理錯誤函數,設置自定義異常處理函數為set_exception_handler()
- print $a/0; // 這里邏輯錯了,調用error_handler()報錯
- function error_handler($errno, $message, $filename, $line) {
- if ($errno & (E_ALL ^ E_NOTICE)) {
- $types = array(
- 1 => 'error',
- 2 => 'warning',
- 4 => 'parse error',
- 8 => 'notice',
- 16 => 'core error',
- 32 => 'core warning',
- 64 => 'compile error',
- 128 => 'compile warning',
- 256 => 'user error',
- 512 => 'user warning',
- 1024 => 'user notice',
- 2048 => 'strict warning'
- );
- print "n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~n";
- print $types[$errno] .': '. $message .' in '. $filename .' on line '. $line .'.';
- print "n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~n";
- exit;
- }
- }
特性12、高可配置性,可修改范圍為:
PHP_INI_USER 的 配置選項可在用戶的PHP腳本或Windows注冊表中設置
PHP_INI_PERDIR 的 配置選項可在 php.ini, .htaccess 或 httpd.conf 中設置
PHP_INI_SYSTEM 的 配置選項可在 php.ini or httpd.conf 中設置
PHP_INI_ALL 的 配置選項可在各處設置
我們要熟悉在php.ini中修改php的配置,還會經常在php腳本中修改腳本中可修改的配置項,可以使用 ini_set()函數或專門修改運行時配置的函數來改變可修改范圍為PHP_INI_ALL
- // 修改php的配置參數
- ini_set('session.save_path', 'D:/temp'); // 修改配置讓腳本把session文件保存到D:/temp目錄
特性13、代碼中執行php腳本
特性14、php的工作模型(這個特性詳細的在).
作為一種純解釋型語言,PHP腳本在每次被解釋時進行初始化,在解釋完畢后終止運行。這種運行是互相獨立的,每一次請求都會創建一個單獨的進程或線程,來解釋相應的頁面文件,頁面創建的變量和其他對象,都只在當前的頁面內部可見,無法跨越頁面訪問舊電腦回收.
在終止運行后,頁面中申請的、沒有被代碼顯式釋放的外部資源,包括內存、數據庫連接、文件句柄、Socket連接等,都會被強行釋放.
也就是說,PHP無法在語言級別直接訪問跨越頁面的變量,也無法創建駐留內存的對象。
PHP這種獨特的工作模型的優勢在于,基本上解決了令人頭疼的資源泄漏問題,Web應用的特點是大量的、短時間的并發處理,對各種資源的申請和釋放工作非常頻繁,很容易導致泄漏.
但是,這種機制的缺點也非常明顯,最直接的后果是,PHP在語言級別無法實現跨頁面的緩沖機制.
補充一點,對象克隆
PHP對象賦值到變量是傳引用的,需要復制對象需要用clone.
新聞熱點
疑難解答