1. 程式人生 > >PHP魔術函式原理介紹和簡單使用

PHP魔術函式原理介紹和簡單使用

魔術函式

魔術函式是PHP中內建的語言特性,當程式執行到某種情況時,如果定義了這些魔術函式 (php手冊中稱之為“Overloading”),則PHP會呼叫他們,同時也會傳入相應的引數,可以認為是PHP執行過程中的鉤子函式。常見的魔術函式有__construct, __destruct , __call, __get, __set, __isset, __unset __sleep, __wakeup, __toString, __clone 以及__autoload 。它們可以用來自動載入包含檔案,實現延遲執行(類似於.Net中的屬性訪問器)、垃圾回收、物件clone 等操作,舉個__autoload的例子,其他魔術函式參見 Magic Method。

__autoload($class_name):用來自動載入包含檔案,省得include,require,對效能有一定影響,但一般情況下可忽略。

下面是一個簡單的例子

function __autoload($class_name){
require_once $class_name . '.class.php';
}

把它放入common.php等全域性包含檔案中,當新建一個物件時,比如 $obj=new Class_A,如果php無法找到Class_A,則會把"Class_A" 作為引數$class_name,執行 __autoload函式。這樣就可以達到自動包含標頭檔案的目的了。

另外附贈幾個常量和函式:

__FILE__ :魔術常量,獲取當前原始碼檔案的路徑(含檔名)

__CLASS__:魔術常量,獲取當前類的類名(區分大小寫的)。

array get_included_files ( void ):內建函式,返回通過include(), include_once(), require() 或require_once()包含的檔案列表,但不包括通過php.ini配置檔案中所設定的auto_prepend_file 項。另外get_required_files()只是get_included_files ( void )的別名。

string dirname ( string path ):返回路徑中的目錄部分。

匿名函式

在PHP5.3以前使用匿名函式,可以通過create_function()來建立匿名函式,

$func=create_function('$a,$b', '
  if ($a == $b){
   return 0;
  }
  return ($a< $b) ? -1 : 1;
');

在PHP5.3中,可以直接使用lamda表示式

$func=function($a,$b){
if ($a == $b){
return 0;
}
return ($a< $b) ? -1 : 1;
}

然後可以作為引數傳入其他函式,如:usort($arr,$func); 也可以直接呼叫,$func(3,4);

在PHP5.3中使用閉包

function foo($arg1){
$var=3;
$inner=function($innerArg) use($arg1,$var){
return $innerArg+$arg1/$var;
};
echo $inner(5);
}

閉包被當成一個內建類,但是沒有javascript那麼靈活,這個類不能有屬性。$inner->a=5;是非法的。

巢狀函式

巢狀函式可以在父函式體裡面定義函式,如:

function outer(){
   $out_var=1;
   function inner(){
   var_dump($out_var);//輸出NULL,無法訪問到$out_var,宣告global也不行,$out_var不是全域性變數
   echo "call inner\n";
  }
  //echo "call outer\n";
  inner();//如果不呼叫inner(),則在訪問outer()時也不會被呼叫
}
outer();
inner();//雖然,函式是全域性的,必須先呼叫outer(),否則inner()呼叫會報錯(函式未定義)
條件函式
$debug=false;
if($debug===true){
  function foo(){
  echo "foo";
 }
}
foo();

相當於條件編譯了,從這裡我們可以猜測到,為什麼上文中outer()呼叫之前,inner()是無法呼叫的。因為inner在outer()呼叫之前還未被“編譯”(只是猜測,未深入研究)。

函式動態呼叫

函式名可以是變數名。

function foo(){
  echo "call foo";
}
$func='foo';
$func();

此方式比較危險,建議使用白名單方式將可用的函式名寫在配置檔案中,或者函式名都有統一字首,比如$func="act_".$funcName;。另外在呼叫之前可用function_exists ($funcName)來檢查函式是否存在。

通過內建函式呼叫函式,call_user_func(callback function ,[, mixed parameter [, mixed ...]] ),對於不確定的函式名,確定的引數可以使用此函式呼叫,如果引數也不確定可以通過call_user_func_array( callback function, array param_arr )

另外,可以通過get_defined_functions()來獲取所有已定義的函式(注意是所有,包括內建函式)

呼叫類的方法則傳入一個數組作為引數,此陣列第一個元素是例項或類名,第二個元素是方法名:

class myclass{
  public $age=21;
  function echo_age(){
  echo $this->age;
  }
  static function s_echo_age(){
  echo 22;
  }
  function i_echo_age(){
  echo 23;
  }
}
$c=new myclass;
$classname = "myclass";
//呼叫例項方法,如果call_user_func(array($classname , 'echo_age'));則會報錯,$this未指向任何例項
call_user_func(array($c, 'echo_age'));
echo "\n";
//呼叫例項方法,如果沒有引用$this變數,則不會有問題
call_user_func(array($classname, 'i_echo_age'));
echo "\n";
//呼叫靜態方法,傳入類名或例項均可
call_user_func(array($classname, 's_echo_age'));
echo "\n";
call_user_func(array($c, 's_echo_age'));

獲取函式引數

通過此方式可以實現非常靈活的過載,但容易使邏輯變得負責,適度使用。

func_get_arg ( int arg_num )獲取第arg_num個引數(從0開始計數)

func_num_args()獲取引數總個數

func_get_args()獲取所有引數。

用三行程式碼實現Gof中的一個設計模式:

function call_it($func){
  $args=func_get_args();
  array_shift($args);//去掉第一個引數,那是函式名
  call_user_func_array($func,$args);
}
function add($a,$b){
  echo $a+$b;
}
function sqr($a){
  echo $a*$a;
}
call_it('add',1,2);
echo "\n";
call_it('sqr',2);

相關推薦

PHP魔術函式原理介紹簡單使用

魔術函式 魔術函式是PHP中內建的語言特性,當程式執行到某種情況時,如果定義了這些魔術函式 (php手冊中稱之為“Overloading”),則PHP會呼叫他們,同時也會傳入相應的引數,可以認為是PHP執行過程中的鉤子函式。常見的魔術函式有__construct, __de

PHP魔術函式__autoload機制介紹

在使用PHP的OO模式開發系統時,通常大家習慣上將每個類的實現都存放在一個單獨的檔案裡,這樣會很容易實現對類進行復用,同時將來維護時也很便利。這也是OO設計的基本思想之一。在PHP5之前,如果需要使用一個類,只需要直接使用include/require將其包含進來即可。下面是一個實際的例子: 01 /* P

linux Mysql 主從復制 原理介紹步驟詳解

linux Mysql 主從復制 大家好,我是霸王卸甲,今天我給大家帶來的是linux數據庫中的主從復制的簡單介紹和步驟詳解。 主從復制 mysql主從復制 靈活 一主一從 主主復制 一主多從---擴展系統讀取的性能,因為讀是在從庫讀取的; 多主一從---5.7開始支持 聯級

Polly的多種彈性策略介紹簡單使用

故障 廣泛 forever 影響 結合 ssim 封裝 n) csharp 什麽是Polly? Polly是一個.NET彈性和瞬態故障處理庫.允許我們以非常順暢和線程安全的方式來執行諸如行重試,斷路,超時,故障恢復等策略。 Polly項目地址:https://github.

[iOS高階]Xcode中的Target介紹簡單使用

        本文地址:http://blog.csdn.net/zhaoyabei/article/details/45396913   轉載註明出處

Dubbox介紹簡單使用

Dubbox介紹和簡單使用 Dubbox定義: 1、dubbox是dubbo的一個版本,它是針對於SOA架構的系統,實現系統表現層和服務層之間的關係調用。 2、dubbox使用rpc協議進行遠端呼叫,直接使用socket通訊,傳輸效率高。 而且它可以計算出系統之間的呼叫關係,可以

servlet 介紹簡單使用

1,servle介紹: html+css+js Servlet:用來開發動態web的技術 屬於javaee規範 【1】,javaEE Servers建立專案      a,new Dynamic Web Project  &nbs

Mongodb的介紹簡單使用

Mongodb的介紹和簡單使用 ①Mongodb的介紹 MongoDB (名稱來自「humongous (巨大無比的)」), 是一個可擴充套件的高效能,開源,模式自由,面向文件的NoSQL,基於 分散式 檔案儲存,由 C++ 語言編寫,設計之初旨在為 WEB 應用提供可擴充套件的高效

twemproxy0.4原理分析-基本原理介紹優缺點分析

引言 接下來將會寫一個分析twemproxy的系列。該系列會對twemproxy最新版v0.4的原始碼進行分析,對設計原理進行剖析,力求用通俗的語言和圖來表達設計思想,並結合實際的使用達到深入淺出的效果。 概述 twemproxy是一個redis和memcached的輕量級分

【轉】理解JMX之介紹簡單使用

原文連結:https://blog.csdn.net/lmy86263/article/details/71037316  近期在專案上需要新增一些功能,想把一個開源工程整合進來,雖說是整合,但是覺得跟開發有查不了多少,要讓這個開源工程的編碼風格和設計方式與我們的工程保持一

Flume的介紹簡單操作

Flume是什麼 Flume是Cloudera提供的一個高可用的,高可靠的,分散式的海量日誌採集、聚合和傳輸的系統,Flume支援在日誌系統中定製各類資料傳送方,用於收集資料;同時,Flume提供對資料進行簡單處理,並寫到各種資料接受方(可定製)的能力。 F

mysql-cluster叢集原理介紹搭建步驟(四個data/sql節點)

MySQL簇概述 MySQL簇是一種技術,該技術允許在無共享的系統中部署“記憶體中”資料庫的簇。通過無共享體系結構,系統能夠使用廉價的硬體,而且對軟硬體無特殊要求。此外,由於每個元件有自己的記憶體和磁碟,不存在單點故障。 MySQL簇將標準的MySQL伺服器與名為NDB的“

PHP curl拓展的介紹使用

curl_setopt($ch, CURLOPT_URL, 'http://www.baidu.com/');//請求url地址curl_setopt($ch, CURLOPT_HEADER, 0);//不輸出頭部資訊curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//

flume的介紹簡單安裝

nbsp 壓縮 容錯能力 故障轉移 apach 有效 color 相關 .html 一:介紹 (1)日誌采集系統 (2)是一種分布式,可靠且可用的服務,用於有效地收集,聚合和移動大量日誌數據。 (3)具有基於流數據流的簡單靈活的架構。 (4)具有可靠的可靠性機制和許多故障轉

(十)lseek函式介紹使用

  每個開啟的檔案都記錄著當前讀寫位置,開啟檔案時讀寫位置是0,表示檔案開頭,通常讀寫多少個位元組就會將讀寫位置往後移多少個位元組。但是有一個例外,如果以O_APPEND方式開啟,每次寫操作都會在檔案末尾追加資料,然後將讀寫位置移到新的檔案末尾。lseek和

Netty專欄 (一)——— Netty初步介紹簡單Demo

Netty初步介紹和簡單Demo @author 魯偉林 記錄《Netty 實戰》中各章節學習過程,寫下一些自己的思考和總結,幫助使用Netty框架的開發技術人員們,能夠有所得,避免踩坑。 本部落格目錄結構將嚴格按照書本《Netty 實戰》,省略與Netty無關的內容,可能

JDBCTemplate---方法介紹簡單示例

當sql等查詢方式不能滿足效能或靈活性的要求,必須使用SQL時,大家有三種選擇: 第一、使用Hibernate 的sql 查詢函式,將查詢結果物件轉為Entity物件。 第二、使用Hibernate Session的getConnection 獲得JDBC

SpringMVC學習(一)———— springmvc框架原理分析簡單入門程式

一、什麼是springmvc?       我們知道三層架構的思想,並且如果你知道ssh的話,就會更加透徹的理解這個思想,struts2在web層,spring在中間控制,hibernate在dao層與資料庫打交道,而前面剛寫的mybatis跟hibernate一樣,與資料庫打交道在dao層的另一個框架,而

爬蟲基本原理介紹初步實現(以抓取噹噹網圖書資訊為例)

本文程式碼等僅作學習記錄使用 一、爬蟲原理 網路爬蟲指按照一定的規則(模擬人工登入網頁的方式),自動抓取網路上的程式。簡單的說,就是講你上網所看到頁面上的內容獲取下來,並進行儲存。網路爬蟲的爬行策略分為深度優先和廣度優先。 (1)、深度優先 深度

Yii2.0框架的介紹簡單部署

Yii是什麼?         高效能,基於元件 Yii適合做什麼?         大型應用,門戶,社群,OMS,電子商務等 Yii與其他框架相比         1:和其他PHP框架相比,Yii實現了MVC(Model-View-Controller)設計模式並基於該