PHP 魔術函數 __call()用法

來源:互聯網
上載者:User

在 PHP 中的方法調用是這樣工作的。首先,PHP 解譯器在類上尋找方法。如果方法存在,PHP 就調用它。如果沒有,那麼就調用類上的魔術函數 __call(如果這個方法存在的話)。如果 __call 失敗,就調用父類方法,依此類推。

這樣紅口白牙的說似乎有點太變態了,我們還是舉個例子吧,看如下代碼:

 代碼如下 複製代碼

 class test{
public function __construct(){
echo "this is construct!n";
}
}
……

在這個測試類別test中,只有個建構函式輸出一些可有可無的垃圾字元,別的什麼都沒有;

這時候我們,把它執行個體化,並且調用一個原子彈的方法,你猜他會怎麼樣呢?我們立馬就這樣做,看著:

 代碼如下 複製代碼

$send = new test();
$send-> atomBomb();

結果是可想而知的,他一定會告訴你沒有這個方法的——咱們的確沒有這個原子彈的方法!錯誤資訊如下:
Debug Error: test.php line 9 – Call to undefined method test::atomBomb()

那麼我們把這個類修改一下,加上一個__call方法,看看怎麼樣呢:

 代碼如下 複製代碼

……
class test{
public function __construct(){
echo "this is construct!n";
}

public function __call($name,$arg){
echo “function name:”,$name,”n arg:”.$arg;
}
}
……

重複上邊的調用方式:
$send = new test();
$send-> atomBomb(‘ab’,9);

這次看到的結果肯定是和上次不一樣的。結果如下:

this is construct! //這個是建構函式自己輸出的

//下邊這些是__call函數輸出的

 代碼如下 複製代碼
function name:atomBomb
arg:Array

並且我們也很容易的看出,__call兩個參數,第一個參數:調用的方法名,第二個參數:調用方法時候輸入的參數(這個地方是個數組)。

說這麼多不知道你明白沒有,我想你要是明白的話,你一定會問這個東西有個什麼鳥用呢?就是我們能夠用來幹什麼呢?

那我給你一個用它的思路吧——學以致用嘛!試想,你如果把一個資料庫中的所有表都作為一個個對象,並且對其進行CURD操作,你需要寫多少個類呢?當然要是你的數組庫只有兩個表,你完全可以告訴我,只有兩個類!但是要是有108個表呢(你例如dede就是108個表),手工輸入108個類?顯然不科學,21世紀什麼最貴?——時間!

我們完全可以寫一個類,其餘的然他自動建立,我在IBM找了段代碼,並且精簡了一下,大家可以看看,這個可是進階工程師寫的東西啊。

 

 代碼如下 複製代碼
class DBObject{
private $id = 0;
private $table;
private $fields = array();
function __construct( $table, $fields ) {
$this->table = $table;
foreach( $fields as $key )
$this->fields[ $key ] = null;
}
function __call( $method, $args ) {
if ( preg_match( "/set_(.*)/", $method, $found ) ) {
if ( array_key_exists( $found[1], $this->fields ) ) {
$this->fields[ $found[1] ] = $args[0];
return true;
}
}
else if ( preg_match( "/get_(.*)/", $method, $found ) ) {
if ( array_key_exists( $found[1], $this->fields ) ) {
return $this->fields[ $found[1] ];
}
}
return false;
}
function insert() {
global $db;
$fields = $this->table."_id, ";
$fields .= join( ", ", array_keys( $this->fields ) );
$inspoints = array( "0" );
foreach( array_keys( $this->fields ) as $field )
$inspoints []= "?";
$inspt = join( ", ", $inspoints );
$sql = "INSERT INTO ".$this->table." ( $fields ) VALUES ( $inspt )";
$values = array();
foreach( array_keys( $this->fields ) as $field )
$values []= $this->fields[ $field ];
$sth = $db->prepare( $sql );
$db->execute( $sth, $values );
$res = $db->query( "SELECT last_insert_id()" );
$res->fetchInto( $row );
$this->id = $row[0];
return $row[0];
}</code>
 
//下邊刪除了3個方法分別是更新update,刪除一個,刪除全部(戰地注)
}
$book = new DBObject( 'book', array( 'author',
'title', 'publisher' ) );
$book->delete_all();
$book->set_title( "PHP Hacks" );
$book->set_author( "Jack Herrington" );
$book->set_publisher( "O'Reilly" );
$id = $book->insert();
echo ( "New book id = $idn" );
$book->set_title( "Podcasting Hacks" );
$book->update();
$book2 = new DBObject( 'book', array( 'author',
'title', 'publisher' ) );
$book2->load( $id );
echo( "Title = ".$book2->get_title()."n" );
$book2->delete( );……

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.