在线文档教程
Codeigniter 3

控制器 | Controllers

Controllers

控制器是应用程序的核心,因为它们决定了如何处理HTTP请求。

页面内容

  • 控制器

什么是控制器?

Controller是一个简单的类文件,它以一种可以与URI关联的方式命名。

考虑这个URI:

example.com/index.php/blog/

在上面的例子中,CodeIgniter会尝试找到一个名为Blog.php的控制器并加载它。

当控制器的名称与URI的第一个段相匹配时,它将被加载。

让我们试试看:Hello World!

我们来创建一个简单的控制器,这样你就可以看到它在运行。使用你的文本编辑器,创建一个名为Blog.php的文件,并在其中放入下面的代码:

<?php class Blog extends CI_Controller { public function index() { echo 'Hello World!'; } }

然后将该文件保存到您的应用程序/控制器/目录。

重要

该文件必须被称为'Blog.php',大写字母'B'。

现在使用类似下面的网址访问您的网站:

example.com/index.php/blog/

如果你做得对,你应该看到:

你好,世界!

重要

类名必须以大写字母开头。

这是有效的:

<?php class Blog extends CI_Controller { }

这是正确的:

<?php class blog extends CI_Controller { }

另外,请务必确保您的控制器扩展父控制器类,以便它可以继承其所有方法。

方法

在上面的例子中,方法名称是index()。如果URI的第二段为空,则“索引”方法始终默认加载。显示“Hello World”消息的另一种方法是:

example.com/index.php/blog/index/

URI的第二部分确定控制器中的哪个方法被调用。

我们来试试吧。为您的控制器添加一个新方法:

<?php class Blog extends CI_Controller { public function index() { echo 'Hello World!'; } public function comments() { echo 'Look at this!'; } }

现在加载以下URL以查看评论方法:

example.com/index.php/blog/comments/

你应该看到你的新消息。

将URI段传递给您的方法

如果你的URI包含两个以上的段,它们将作为参数传递给你的方法。

例如,假设你有一个这样的URI:

example.com/index.php/products/shoes/sandals/123

您的方法将通过URI段3和4(“凉鞋”和“123”):

<?php class Products extends CI_Controller { public function shoes($sandals, $id) { echo $sandals; echo $id; } }

重要

如果您使用的是URI路由功能,传递给您的方法的段将是重新路由的段。

定义一个默认的控制器

当URI不存在时,可以告诉CodeIgniter加载默认控制器,就像只有您的站点根URL被请求时一样。要指定一个默认的控制器,打开你的application / config / routes.php文件并设置这个变量:

$route['default_controller'] = 'blog';

其中'blog'是您想要使用的控制器类的名称。如果你现在加载你的主要index.php文件而不指定任何URI段,默认情况下你会看到你的“Hello World”消息。

有关更多信息,请参阅URI路由文档的“保留路由”部分。

重新映射方法调用

如上所述,URI的第二部分通常确定控制器中的哪个方法被调用。CodeIgniter允许您通过使用该_remap()方法来覆盖此行为:

public function _remap() { // Some code here... }

重要

如果您的控制器包含名为_remap()的方法,则无论您的URI包含什么,它都会始终被调用。它覆盖了URI确定调用哪个方法的正常行为,允许您定义自己的方法路由规则。

重写的方法调用(通常是URI的第二部分)将作为参数传递给_remap()方法:

public function _remap($method) { if ($method === 'some_method') { $this->$method( } else { $this->default_method( } }

方法名称之后的任何额外的段将_remap()作为可选的第二个参数传入。该数组可以与PHP的call_user_func_array()结合使用来模拟CodeIgniter的默认行为。

例:

public function _remap($method, $params = array()) { $method = 'process_'.$method; if (method_exists($this, $method)) { return call_user_func_array(array($this, $method), $params } show_404( }

处理输出

CodeIgniter有一个输出类,负责自动将最终呈现的数据发送到Web浏览器。关于这方面的更多信息可以在Views和Output Class页面找到。但是,在某些情况下,您可能需要以某种方式后处理最终数据,并将其自行发送到浏览器。CodeIgniter允许你添加一个名为_output()你的控制器的方法,它将接收最终的输出数据。

重要

如果您的控制器包含一个名为的方法_output(),它将始终由输出类调用,而不是直接回显最终数据。该方法的第一个参数将包含最终输出。

这里是一个例子:

public function _output($output) { echo $output; }

注意

请注意,您的_output()方法将收到处于最终状态的数据。基准和内存使用数据将被渲染,缓存文件被写入(如果您启用了缓存),并且标头将在它被切换到_output()方法之前被发送(如果您使用该功能)。要使控制器的输出正确缓存,其_output()方法可以使用:

if ($this->output->cache_expiration > 0) { $this->output->_write_cache($output }

如果您使用此功能,页面执行计时器和内存使用率统计可能不完全准确,因为它们不会考虑您所做的任何进一步处理。在完成任何最终处理之前,有关控制输出的另一种方法,请参阅输出库中的可用方法。

私人方法

在某些情况下,您可能希望某些方法隐藏公开访问。为了实现这一点,只需将该方法声明为私有或受保护,并且不会通过URL请求提供。例如,如果你有一个像这样的方法:

private function _utility() { // some code }

试图通过URL访问它,像这样,将无法正常工作:

example.com/index.php/blog/_utility/

注意

使用下划线前缀方法名称也会阻止它们被调用。这是为了向后兼容而留下的遗留功能。

将您的控制器组织到子目录中

如果你正在构建一个大型的应用程序,你可能想分层组织或者将你的控制器构造成子目录。CodeIgniter允许你这样做。

只需在主应用程序/控制器/子目录下创建子目录,然后将控制器类放在其中。

注意

使用此功能时,URI的第一部分必须指定文件夹。例如,假设您的控制器位于此处:

application/controllers/products/Shoes.php

要调用上面的控制器,你的URI将如下所示:

example.com/index.php/products/shoes/show/123

每个子目录都可能包含一个默认控制器,如果该URL 包含子目录,则该控制器将被调用。需在其中添加一个控制器,该控制器与application / config / routes.php文件中指定的'default_controller'的名称相匹配。

CodeIgniter还允许您使用URI路由功能重新映射您的URI。

类构造函数

如果您打算在任何控制器中使用构造函数,则必须在其中放置以下代码行:

parent::__construct(

这一行是必要的原因是因为你的本地构造函数将覆盖父控制器类中的构造函数,所以我们需要手动调用它。

例:

<?php class Blog extends CI_Controller { public function __construct() { parent::__construct( // Your own constructor code } }

如果您需要设置某些默认值,或者在实例化类时运行默认流程,则构造函数非常有用。构造函数不能返回值,但他们可以做一些默认的工作。

保留的方法名称

由于您的控制器类将扩展主应用程序控制器,因此您必须小心,不要将您的方法命名为该类使用的方法,否则您的本地函数将覆盖它们。请参阅保留名称以获取完整列表。

重要

你也不应该有一个与其类名相同的方法。如果你这样做了,并且__construct()在同一个类中没有方法,那么你的eg Index::index()方法将作为一个类的构造函数来执行!这是一个PHP4向后兼容性功能。

而已!

简而言之,就是要了解控制器。