CodeIgniter:特定功能应该放在哪里?

发布于 2024-08-29 07:05:57 字数 347 浏览 7 评论 0原文

以下是大多数应用程序中控制器功能的快速概述:

  • 控制器加载特定模型,从中获取数据,格式化数据并将格式化数据传递到视图。

现在有一个搜索页面,需要对整个数据库(所有型号)进行搜索查询。它需要以列表的形式在单个页面上以特定格式输出显示每种类型的数据。

问题:

搜索控制器可以进行搜索,为每个记录类型动态加载模型,并从模型中获取数据。当数据需要格式化时就会出现问题。我正在尝试从搜索控制器加载特定控制器,这导致了问题。

该怎么办?

PS:我尝试使用“Wick”库,但是当控制器的格式函数尝试使用自己的模型和会话对象时,它会失败,并给出有关调用非对象上的成员的错误。

Here is a quick overview of the controllers functionality in most of the application:

  • controller loads a specific model, gets data from it, formats the data and passes the formatted data to the view.

Now there is a search page, which needs to do a search query over entire database (all models). It needs to show each type of data in its particular formatted output on a single page as a list.

The problem:

The search controller can do the search, dynamically load model for each record type, and get the data from model. Problem comes when the data needs to be formatted. I am trying to load the specific controller from the search controller, which is causing problems.

What to do?

PS: I tried using the 'Wick' library, but it fails when the controller's format function tries to use its own model and session object, giving errors about call to a member on a non-object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

天气好吗我好吗 2024-09-05 07:05:57

经过多次重构和试验/错误,看来实现上述目标的最佳方法是这样的:

  1. 将格式函数保留在派生所有其他控制器的基本控制器中。格式选项与数据对象一起作为参数传递给函数。

  2. 在每个派生控制器中创建一个静态函数,该函数返回数据的格式化选项。

  3. 在搜索控制器(本身源自基本控制器)内,对于每个数据对象,调用其特定控制器的静态函数,该函数返回数据格式化选项,然后使用它来格式化视图的对象。< /p>

我想我可以说我将坚持仅使用模型与数据库交互,并让控制器完成其他所有事情。如果有人还有更好的解决方案,我会洗耳恭听。

After much refactoring and trial/error, It appears that the best way to achieve the above is this way:

  1. Keep the format function in the base controller from which all other controllers are derived. The format options are passed to the function along with the data object as arguments.

  2. Make a static function in each derived controller, which returns the formatting options of the data.

  3. Inside the search controller (which is itself derived from the base controller), for each data object, call the static function of its particular controller which returns the data formatting options, then use that to format the object for the view.

I guess I can say I will stick to using the model only for interaction with the database, and let everything else be done by controller. If anyone has a better solution still, I am all ears.

逐鹿 2024-09-05 07:05:57

听起来您想使用 工厂设计模式

使其成为一个库:

class MyModelFactory {
  static public function Factory($data) {
    $type = key($data);
    return new $type($data);
  }
}

现在,在你的控制器中,你可以这样做:

$model = MyModelFactory::Factory(array($_REQUEST['model'] => $_REQUEST));

现在你有了一个 $_REQUEST['model'] 中指定的任何模型的对象。请务必采取应用程序可能需要的任何安全预防措施,以确保用户有权使用他们请求的模型

现在,由于您希望使用通用方法和内容,因此您的模型可能应该基于抽象类/接口..所以

class MyModelOne extends Model {
  // stuff
}

你可能想要这样的东西,以确保你所需的方法始终可用:

abstract class MyAbstractModel extends Model {

  protected $search_params;

  public function __construct($data = array()) {
     $search_params = $data['search_params'];
  }

  protected function GetSearchParameters() {
    return $this->search_params;
  }
  abstract public function GetData();
  abstract public function GetColumns();
  abstract public function DefineViewOptions();
}

class MyModelOne extends MyAbstractModel {


  public function GetData() {
    $params = array();
    $params[] = $this->db->escape_str($this->GetSearchParameters());
    // return whatever data you want, given the search parameter(s)
  }
  public function GetColumns() {
    // return some columns
  }
  public function DefineViewOptions() {
    // return some configuration options
  }
}

It sounds like you want to use the Factory design pattern

Make this a library:

class MyModelFactory {
  static public function Factory($data) {
    $type = key($data);
    return new $type($data);
  }
}

now, in your controller, you can do something like this:

$model = MyModelFactory::Factory(array($_REQUEST['model'] => $_REQUEST));

and now you have an object of whatever model was specified in $_REQUEST['model']. Be sure to take any security precautions you may need for your application to assure the user has permissions to use the model that they request

Now, since you want to be using common methods and stuff, your models should probably be based off an abstract class / interface.. so instead of

class MyModelOne extends Model {
  // stuff
}

You probably want something like this, to ensure your required methods will always be available:

abstract class MyAbstractModel extends Model {

  protected $search_params;

  public function __construct($data = array()) {
     $search_params = $data['search_params'];
  }

  protected function GetSearchParameters() {
    return $this->search_params;
  }
  abstract public function GetData();
  abstract public function GetColumns();
  abstract public function DefineViewOptions();
}

class MyModelOne extends MyAbstractModel {


  public function GetData() {
    $params = array();
    $params[] = $this->db->escape_str($this->GetSearchParameters());
    // return whatever data you want, given the search parameter(s)
  }
  public function GetColumns() {
    // return some columns
  }
  public function DefineViewOptions() {
    // return some configuration options
  }
}
-柠檬树下少年和吉他 2024-09-05 07:05:57

一般来说,您无法从 CodeIgniter 的控制器中加载另一个控制器(尽管有一些 mods 允许您执行类似的操作)。

我会尝试创建一个类来格式化数据并将其添加到应用程序/库文件夹中。然后在您的各种控制器中加载、使用和重复使用此类。

以下是 CodeIgniter 文档 创建您自己的库 中的页面,其中解释了详细信息和约定。

另外,如果一个类太过分了,那么创建辅助函数是一种更轻松的方法。

CodeIgniter 中库和助手之间的区别在于,库是类,助手只是一组 php 函数。

一旦你格式化了你的数据,你就可以从任何控制器加载任何视图,所以你应该仍然拥有你需要的所有可重用性,这样你就可以干燥(不要重复自己)

In general you can't load another controller from within a controller in CodeIgniter (although there are mods that allow you to do something like this).

I would try creating a class for formatting your data and add it to the application/library folder. Then load, use and re-use this class throughout your various controllers.

Here is a page from the CodeIgniter documentation Creating Your Own Libraries that explains the details and conventions.

Also, if a class is overkill, creating helper functions is an even lighter approach.

The difference between libraries and helpers in CodeIgniter is that libraries are classes, helpers are just a group of php functions.

Once you have formatted your data, you can load any view from any controller, so you should still have all the re-usability you need so you DRY (don't repeat yourself)

网名女生简单气质 2024-09-05 07:05:57

有一些简单的方法基于“更简单”(相对于“完全 DRY”)的原则。这是我在 CodeIgniter 中使用的另一种方法:

  1. 不要尝试加载多个控制器,而是重用搜索控制器(或搜索路径,具体取决于您使用的控制器)中的视图片段。这需要对数据元素使用相同的命名约定,以便视图可以互换,但无论如何您都应该这样做。
  2. 不要使用多个模型进行搜索,而是添加一个了解可搜索内容的搜索模型。如果要防止重复的 SQL,请在模型之间重用 SQL(这可以使用常量或从磁盘加载 SQL 来完成)。

控制器不适合从您自己的 PHP 代码中重用:它们将操作和资源请求路由到事物本身。它们旨在使用您提出的 URI 接口通过 HTTP 进行调用。从代码中调用它们是您要避免的耦合。也就是说,从 JavaScript(或通过 cURL)重用控制器是在任何 Web 框架中重用事物的一种很好的解耦方式。

There are a few simple approaches based on the principle of what's simpler (versus what's perfectly DRY). Here's one alternative approach I use with CodeIgniter:

  1. Instead of trying to load multiple controllers, reuse the view fragments from your search controller (or search route, depending which you're using). This requires using the same naming conventions for your data elements so the views are interchangeable, but you should be doing this anyway.
  2. Instead of using multiple models for search, add a single Search model that knows about the things that can be searched on. If you want to prevent duplicate SQL, reuse the SQL between models (this can be done using constants, or loading SQL from disk).

Controllers are not great candidates for reuse from your own PHP code: they route actions and requests for resources to the things themselves. They are intended to be called via HTTP, using the URI interface you've come up with. Calling them from code is a coupling you want to avoid. That said, reusing controllers from JavaScript (or via cURL) is a great, decoupled way to reuse things in any web framework.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文