技術交流

Dynamic Function Calling in PHP5

更新於

在程式設計中,特別是在框架 (Framework) 的設計中,因為框架的設計者預先並不知道框架的使用者 (Programmer) 在程序撰寫時所命名的 Function 名稱,框架的設計者可以用動態Function 的調用方式解決這個問題。簡單的說,function 的名稱是一個變數。

在本文中我們將會討論三種不同的動態調用的方式:

  • 直接調用變數名稱,變數的值是一個 Function 名稱
  • 使用 built-in Function call_user_func()
  • 用 built-in Function eval()

Variable Function

在 MVC 模式中的 Model 中,假設是跟 Database 交互的,其中有 add/delete/update/query function,在實際調用時,因為不知道當前使用者(End-user) 要做的動作,這時就可以利用變量 Function 的方式來處理這樣的情景。當然也可以用 switch 的方式來處理。


  Class User{
    function __constuct()
    {
      // some code here
    }
      public function add()
{
      // some code here
}// end add()
public function update()
{
// some code here
}// end update()

public function delete()
{
  // some code here
}// end delete()
public function query()
{
  // some code here
}// end query()
}// end class User

以下採用 switch 和動態 Function 調用代碼有何不同?


include_once('User.php');
  $user = new User();
  $action = isset($_GET['action']) && !empty($_GET['action']) ?
        $_GET['action'] :
        'query';
switch ($action)
{
  case 'save':
    $user->save();
    break;
  case 'update':
    $user->update();
    break;
  case 'delete':
    $user->delete();
    break;
  case 'query':
    $user->query();
    break;
   default:break;
  }

Dynamic Function Call


include_once('User.php');
$user = new User();
$action = isset($_GET['action']) && !empty($_GET['action']) ?
      $_GET['action'] :
      'query';
$user->$action();

可以看出使用動態 Function 調用非常簡潔。

call_user_func()


//Call a user defined function given by the function parameter.
// Take the following:
function hello($name)
{
  echo 'Hello '.$name;
}
call_user_func('hello', 'dennis'); //output 'Hello dennis'

// Object methods may also be invoked statically using this function // by passing array($objectname, $methodname)
// to the function parameter.
class Hello {
  function say_hello()
  {
   echo 'Hello!\n';
}
}
$classname = 'Hello';
call_user_func(array($classname, 'say_hello'));

// 多個 Parameter 時
 class Hello{
  function talk($who,$p)
  {
    echo $who .' talk with '.$p;
  }// end talk()
 }// end Hello()

$User = new Hello();
$func = 'talk';
call_user_func(array($User,$func),'dennis','allan');

eval()

eval 是把 string 轉變成 PHP 代碼來執行。這裡提到 eval 只是實現了動態調用的功能。使用 eval 會大大降低程式的執行效能,在實際產品環境中,盡量少用或不用 eval。


include_once 'User.php';
$User = new User();
$action = isset($_GET['action']) && !empty($_GET['action']) ?
        $_GET['action'] :
         'query';
eval("\$User->".$action."();");
閱讀更多