萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP 魔術函數 __call()用法

PHP 魔術函數 __call()用法

所謂PHP的魔術函數,簡單的說就是在PHP中具有特定名稱——都是用兩個下劃線開頭的,並且PHP解釋器會在運行到某一個時機的時候自動查找並運行的方法。最常見的魔術函數當然是構造函數方法:__construct了。

在 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( );……
copyright © 萬盛學電腦網 all rights reserved