在程式中如果加一大堆判斷的確是一個很大的麻煩!例如這樣:
代碼如下 |
複製代碼 |
if($fun=’a’){echo ”哎呀!”;} elesif(){} …… else{echo “嗯!”;};
|
真的很麻煩並且造成程式後期閱讀和修改時候的巨大麻煩!
這時候我們可以把每一個要執行的程式碼片段,用函數來實現。
然後可以用一個更加NB的方法來實現這些功能。
並且因為每一個函數實現一個功能,我們維護起來就簡單多了。
進入正題,看看PHP動態調用函數到底有什麼作用:
在PHP中是可以動態調用函數的,像這樣$fun(),PHP解析器可以根據變數$fun的值來調用對用的函數,例如$fun=’a’,解析器看到的將是a();這樣的形式,從而調用函數a。具體代碼如下:
代碼如下 |
複製代碼 |
<?php //程式來源:PHP iask http://www.111cn.net //controller.php (isset($_GET['fun'])&&$_GET['fun']!='')?$fun=$_GET['fun']:$fun='def'; controller($fun); function controller($fun){ if(function_exists($fun)) $fun(); else echo "函數{$fun}未定義"; } function def(){ echo "由於使用者沒有傳遞參數,調用了預設的函數def()"; } function a(){ echo "函數a被調用!"; } function b(){ echo "函數b被調用!"; } ?> |
執行個體
代碼如下 |
複製代碼 |
<?php require_once showErrMsg.php; $_action = (isset($_REQUEST[action])?$_REQUEST[action]:""); if($_action!=null&&$_action!=){ if(function_exists($_action)){ eval("$_action();"); }else{ die(showErrMsg ( "<br>當前php檔案中不存在方法[<b>".$_action."()</b>]。")); } } ?> <?php function showErrMsg($strMsg){ return "<font color=red>".$strMsg."</font>"; } ?> |
在前台頁面我們可以用不同的連結來實現不同的功能,例如我們有這樣一個連結
http://localhost/controller.php?fun=a
當請求到達controller.php的時候,PHP程式將會自動的執行函數a()。
問題的重點:
在於我們在這個程式的頁面首先調用了controller()函數。這個函數首先判斷參數中定義的函數名稱($fun的值)是否被定義,如果定義了就調用這個函數。
如果在$_GET參數中fun沒有定義:http://localhost/controller.php
就調用一個預設的函數def();
這樣的代碼是不是簡潔很對呢?你可以把這些代碼拷貝回去,自己看看效果——我肯定的告訴你,這些代碼運行時正常的!
然而我也很不幸的告訴你:其實這段看起來整齊的代碼有一個巨大的安全隱患在裡面,很大,很大的安全隱患!具體是啥,留到明天10點鐘準時上線的《關於PHP動態調用函數的安全問題》再說吧,你肯定不會把這一段代碼立馬用到伺服器上吧?
另外經過測試證實,這個方法不但可以動態調用函數,並且也可以動態執行個體化對象,像這樣:$obj = new $obj();
代碼如下 |
複製代碼 |
<?php class A { function foo() { if (isset($this)) { echo '$this is defined ('; echo get_class($this); echo ")n"; } else { echo "$this is not defined.n"; } } } class B { function bar() { A::foo(); //parent::foo(); } } $a = new A(); $a->foo();//動態調用,因為new了對象 A::foo();//靜態調用,直接用類名去調用,沒有new對象 $b = new B(); $b->bar();//在對象$b中,A::foo();進行靜態調用 B::bar(); ?> |
總結:靜態、動態調用都指類、對象對其方法的調用,動態指的是建立(new)了對象,然後用物件變數去調用方法;靜態則是沒有建立對象,直接用類名去調用。至於另一個對象那就很簡單了,不同的類建立不同的對象,比如class A;class B ,$a = new A();$b = new B();$a and $b 相對之間就是另一個對象了。