使用CodeIgniter模型的OOP抽象


OOP abstraction with CodeIgniter Models

我正在编写一个库搜索引擎,用户可以使用CodeIgniter根据各种标准(例如,作者、标题、出版商等)进行搜索。因此,我定义了接口BookSearch,所有负责搜索数据库的类都将实现

interface BookSearch{
/**
Returns all the books based on a given criteria as a query result.
*/
public function search($search_query);
}

如果我想实现基于作者的搜索,我可以将类AuthorSearch编写为

class AuthorSearch implements BookSearch extends CI_Model{
function __construct(){
    parent::__construct();
}
public function search($authorname){
    //Implement search function here...
    //Return query result which we can display via foreach
}
}

现在,我定义了一个控制器来利用这些类并显示我的结果,

class Search extends CI_Controller{
/**
These constants will contain the class names of the models
which will carry out the search. Pass as $search_method.
*/
const AUTHOR = "AuthorSearch";
const TITLE = "TitleSearch";
const PUBLISHER = "PublisherSearch";
public function display($search_method, $search_query){
    $this->load->model($search_method);
}
}

这就是我解决问题的地方。CodeIgniter手册说,要调用模型中的方法(即search),我需要编写$this->AuthorSearch->search($search_query)。但由于我把搜索类的类名作为字符串,所以我真的不能做$this->$search_method->search($search_query),对吧?

如果这是在Java中,我会将对象加载到常量中。我知道PHP5有类型提示,但这个项目的目标平台有PHP4。此外,我正在寻找一种更"CodeIgniter"的方式来实现这种抽象。有什么提示吗?

你真的可以做$this->$search_method->search($search_query)。此外,在CI中,您可以根据需要分配库名称。

public function display($search_method, $search_query){
    $this->load->model($search_method, 'currentSearchModel');
    $this->currentSearchModel->search($search_query);
}

您所说的是驱动程序模型。事实上,你可以做你建议不能做的事:

<?php
$this->{$search_method}->search($search_query);

CodeIgniter具有CI_Driver_Library&CI_Driver类执行此操作(请参见CodeIgniter驱动程序)。

然而,我发现,像现在这样实现接口/扩展抽象类通常更简单。继承比CI的驱动程序更有效。