視圖是任何 MVC 應用程式中的關鍵組成部分,CodeIgniter 應用程式也不例外。今天,我們將了解什麼是視圖,並了解如何使用它們為您的 CodeIgniter 專案建立模板解決方案。
本教學的第一部分將向 CodeIgniter 的初學者介紹什麼是視圖以及如何在典型應用程式中使用它們。後半部將討論尋找模板解決方案的動機,並引導讀者完成創建簡單而有效的模板庫的必要步驟。
如果您想使用 CodeIgniter 做更多事情,請查看 Envato Market 上的 CodeIgniter 外掛程式和程式碼腳本範圍。
視圖是 CodeIgniter 中用於儲存應用程式輸出的標記的特殊文件,通常由 HTML 和簡單的 PHP 標記組成。
「視圖只是一個網頁,或者一個頁面片段,例如頁眉、頁腳、側邊欄等。事實上,如果您需要的話,視圖可以靈活地嵌入到其他視圖中(在其他視圖中,等等)等級制度的類型。”
視圖從控制器方法內加載,視圖內的內容隨後顯示在瀏覽器中。
為了在 CodeIgniter 中載入(並顯示)視圖,我們使用內建的 Loader 庫。
$this->load->view('hello_world', $data, true/false);
這行程式碼將告訴 CodeIgniter 在 application/views
資料夾中尋找 hello_world.php
,並在瀏覽器中顯示該檔案的內容。
請注意,CodeIgniter 允許您排除 .php 後綴,從而在鍵入要載入的視圖檔案名稱時節省一些擊鍵次數。
第二個參數 $data
是可選,並採用關聯陣列或物件。此數組/物件用於將資料傳遞到視圖文件,因此可以在視圖中使用或引用它。
最後一個可選參數決定視圖的內容是顯示在瀏覽器視窗中,還是作為字串傳回。此參數預設為false,在瀏覽器中顯示內容。我們將在本教程後面看到如何在創建模板解決方案時使用此參數。
要設定我們的第一個視圖,請在 application/views
中建立一個名為 hello_world.php
的新文件,並在其中編寫以下簡單的 HTML:
<!DOCTYPE html> <html> <head> <title>Hello World!</title> </head> <body> <p> Hello world! </p> </body> </html>
現在要在瀏覽器中顯示此視圖,必須使用上述方法將其載入到控制器方法中。
因此,讓我們在 application/controllers
中建立一個名為 hello_world.php
的新控制器文件,並在其中放置以下程式碼。從這個控制器中,我們將載入新建立的視圖。
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Hello_world extends CI_Controller { public function index() { $this->load->view('hello_world'); } }
將瀏覽器指向http://your-ci-install.com/index.php/
現在將導致application/views/hello_world.php
中的HTML 在瀏覽器中輸出。您已成功載入視圖!
將視圖拆分為多個文件可以使您的網站更易於維護,並減少重複程式碼的可能性。
顯示單一視圖固然很好,但您可能希望將輸出拆分為多個不同的文件,例如頁首、內容和頁尾視圖。
只需多次呼叫 $this->load->view()
方法即可載入多個視圖。然後,CodeIgniter 將視圖的內容連接在一起,然後再顯示在瀏覽器中。
在 application/views
中建立一個名為 header.php
的新文件,並剪下並貼上原始 hello_world.php
文件中的前幾行。
<!DOCTYPE html> <html> <head> <title>Hello World!</title> </head> <body>
同樣,在 application/views
中創建另一個名為 footer.php
的文件,並將 hello_world.php
的最後兩行移入。
</body> </html>
這使得 hello_world.php
視圖檔案僅包含我們的頁面內容。
<p> Hello world! </p>
現在要再次顯示頁面,我們必須在控制器中按順序載入所有三個視圖(header.php、hello_world.php、footer.php)。
重新開啟 application/controllers/hello_world.php
並在現有呼叫的上方和下方新增新的 $this->load->view()
呼叫。
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Hello_world extends CI_Controller { public function index() { $this->load->view('header'); $this->load->view('hello_world'); $this->load->view('footer'); } }
由於頁首和頁尾視圖現在與 hello_world
視圖分開,這意味著它們可以與網站中的任何其他視圖結合使用。這意味著頁首和頁尾文件中的程式碼不需要複製到專案中需要此程式碼的任何其他視圖中。
顯然,這是一個巨大的好處,因為對視圖中的 HTML 或內容的任何更改(例如,向標題添加新的樣式表)只能對一個文件進行,而不是對每個文件進行!
现在,我们将研究从控制器传递数据,以便可以在视图内使用或输出它们。
为此,我们将传递一个关联数组 $data
作为 $this->load->view()
调用中的第二个参数。
该数组的值将在加载的视图中作为变量进行访问,由各自的键命名。
$data = array( 'title' => 'Hello World!', 'content' => 'This is the content', 'posts' => array('Post 1', 'Post 2', 'Post 3') ); $this->load->view('hello_world', $data);
上面的代码将为变量 $title 赋予值“Hello World!”在 hello_world
视图内。
一旦我们将数据传递到视图文件,就可以按照通常的方式使用变量。
通常,视图文件将使用传递的数据来:
我将通过快速示例来说明如何执行每个操作。
要显示变量的内容,请使用简单且熟悉的 echo 语句:
<h1><?php echo $title; ?></h1>
循环遍历数组或对象是视图文件中的常见任务,可以使用 foreach 循环来实现:
<ul> <?php foreach($posts as $post) { ?> <li><?php echo $post; ?></li> <?php } ?> </ul>
可以在视图文件中使用简单的条件语句来稍微改变输出,具体取决于传递的数据。
一般来说,您希望尽量减少视图中条件语句的使用,因为过度使用可能会导致包含“业务逻辑”的复杂视图文件。将视图拆分为不同的文件,并决定在控制器中显示哪个文件是更可取的。
<?php if ( $logged_in ) { ?> <p><?php echo 'Welcome '.$user_name; ?></p> <?php } else { ?> <p>Please login</p> <?php } ?>
上面的示例将显示“欢迎”消息,或要求用户登录的请求,具体取决于 $logged_in
的值(true/false)。
我们已经了解了如何将视图拆分为单独的较小文件可以帮助组织和减少 CodeIgniter 项目中的文件数量,但现在每个显示页面的实例都需要进行多个加载视图调用。
假设您有单独的页眉和页脚视图,它们用于形成模板。项目中您希望使用此模板加载和显示页面的每个实例,都必须调用三个视图加载。这不仅会使您的控制器变得混乱,还会导致大量重复代码 - 这正是我们希望通过拆分文件来摆脱的事情。
如果您现在想向此模板添加额外的标记,例如侧边栏菜单。它可以放在标题视图中,但更适合放在自己的单独视图中。将这个新视图添加到现有模板意味着要遍历视图加载的每个实例,然后添加另一个实例。这可能会很快变得混乱。
我们需要一种方法,能够将显示单个页面内容的视图文件嵌入模板内,而无需重复代码,并且允许轻松高效地对模板进行修改。
以下步骤将指导您创建一个简单的 CodeIgniter 库来满足这些需求,以及:
一旦库被编写并放入我们的 CodeIgniter 工具带中,我们将能够显示一个模板化页面,如下所示:
$this->template->load('template_name', 'body_view');
好多了!
我们的模板解决方案将使用包含模板完整标记的视图文件,以及要嵌入其中的另一个视图文件(包含页面内容)的占位符。
占位符实际上只是一个名为 $body
的变量。当使用我们的库加载模板化视图时,相应的正文视图文件的内容将被分配给此 $body
,将视图嵌入到模板中。
我们希望为要存放的视图文件强制执行一个合理且可预测的目录系统,以便我们的视图:
我们的目录系统还允许库巧妙地确定在哪里查找视图文件,从而减少加载模板化视图所需的代码量。
在 application/views
目录中创建一个新文件夹,并将其命名为 templates
。该文件夹将保存不同的模板视图。
CodeIgniter 中的库只是 PHP 类,并且像视图一样加载到控制器中。
$this->load->library('class_name');
您在 CodeIgniter 项目中使用的自定义库存储在 application/libraries
文件夹中。要开始编写我们的模板库,请在此文件夹中创建一个名为 Template.php
的新文件,并将以下代码放入:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Template { var $ci; function __construct() { $this->ci =& get_instance(); } }
上面的代码定义了一个名为 Template 的新类或库,以及其中的 __construct()
方法。
此方法将 CodeIgniter 超级对象分配给 $ci
类变量,从而通过在通常的方法调用中将 $this
替换为 $this->ci
来允许使用 CodeIgniter 的所有资源。
当CodeIgniter框架加载该库时,会自动调用__construct()
方法。
现在我们将编写实际加载模板视图的方法。我们希望向此函数传递最多三个参数:
调用此方法的结果将是在浏览器中显示模板视图,并嵌入其中的正文视图(如果提供了)。
在 __construct()
方法下面,放置以下代码:
function load($tpl_view, $body_view = null, $data = null) { if ( ! is_null( $body_view ) ) { if ( file_exists( APPPATH.'views/'.$tpl_view.'/'.$body_view ) ) { $body_view_path = $tpl_view.'/'.$body_view; } else if ( file_exists( APPPATH.'views/'.$tpl_view.'/'.$body_view.'.php' ) ) { $body_view_path = $tpl_view.'/'.$body_view.'.php'; } else if ( file_exists( APPPATH.'views/'.$body_view ) ) { $body_view_path = $body_view; } else if ( file_exists( APPPATH.'views/'.$body_view.'.php' ) ) { $body_view_path = $body_view.'.php'; } else { show_error('Unable to load the requested file: ' . $tpl_name.'/'.$view_name.'.php'); } $body = $this->ci->load->view($body_view_path, $data, TRUE); if ( is_null($data) ) { $data = array('body' => $body); } else if ( is_array($data) ) { $data['body'] = $body; } else if ( is_object($data) ) { $data->body = $body; } } $this->ci->load->view('templates/'.$tpl_view, $data); }
上面的代码首先检查 $body_view
参数是否已提供给该方法。该变量将保存要用作模板视图中的正文的视图的名称。
if ( ! is_null( $body_view ) )
如果提供了该参数,则会进行一系列 file_exists 检查,以尝试在目录系统中找到视图文件。
if ( file_exists( APPPATH.'views/'.$tpl_view.'/'.$body_view ) ) { $body_view_path = $tpl_view.'/'.$body_view; } else if ( file_exists( APPPATH.'views/'.$tpl_view.'/'.$body_view.'.php' ) ) { $body_view_path = $tpl_view.'/'.$body_view.'.php'; }
该代码首先尝试在 application/views
文件夹中与模板同名的文件夹内找到视图文件。
如果项目的各个部分与其他部分截然不同并且使用不同的模板,这非常有用。在这些情况下,将这些视图文件分组在一起是有意义的。
例如,许多网站为不同的部分(例如博客)显示不同的模板。在我们的系统中,博客视图文件可以放置在 application/views/blog
文件夹中,将它们与主站点视图分开。
如果无法在此文件夹中找到视图文件,则将 .php
附加到文件名末尾,并再次进行检查。这只是为了像本地 $this->load->view()
调用一样排除 .php
。
如果仍然找不到该文件,则会进一步检查其位置。
else if ( file_exists( APPPATH.'views/'.$body_view ) ) { $body_view_path = $body_view; } else if ( file_exists( APPPATH.'views/'.$body_view.'.php' ) ) { $body_view_path = $body_view.'.php'; } else { show_error('Unable to load the requested file: ' . $tpl_name.'/'.$view_name.'.php'); }
这次,代码检查视图文件是否位于 application/views
文件夹内,如果找不到,则追加 .php
并再次检查。
如果文件位于这些位置之一,则将路径分配给 $body_view_path
,否则使用 CodeIgniter 内置的 show_error()
函数会抛出错误消息,并终止脚本。
如果成功找到正文视图文件,则内容将分配给 $body
变量。
$body = $this->ci->load->view($body_view_path, $data, TRUE);
我们将 $data
参数(如果未提供则为 null)传递给视图加载调用,并将第三个参数设置为 true 以将视图的输出作为字符串返回。
我们现在将这个 $body
变量添加到 $data
中的数据列表中,以便在加载时可以将其嵌入到模板视图中。
if ( is_null($data) ) { $data = array('body' => $body); } else if ( is_array($data) ) { $data['body'] = $body; } else if ( is_object($data) ) { $data->body = $body; }
如果 $data
未提供给 load()
调用,则 $data
会被分配到键 body 下包含 $body
的数组。如果提供了参数,则将 $body
添加到列表中,方法是将其分配给数组键或对象属性,两者也都命名为 body。
$body
变量现在可以在模板视图文件中用作嵌入视图的占位符。
我们方法的最后一行从 application/views/templates
文件夹加载模板视图文件,并在第二个参数中传递 $data
变量。
$this->ci->load->view('templates/'.$tpl_name, $data);
就是这样!该库现在可以投入使用了。
要开始使用我们的库,让我们在 application/views/templates
中创建一个名为 default.php
的模板视图,并将以下 HTML/PHP 放入其中:
<!DOCTYPE html> <html> <head> <title><?php echo $title; ?></title> </head> <body> <h1>Default template</h1> <div class="wrapper"> <?php echo $body; ?> </div> </body> </html>
在此模板中,我们引用两个变量,$title
和 $body
。
回想一下,在我们的模板文件中,$body
用作嵌入视图的占位符。
我们现在将制作另一个视图嵌入到该模板中。在 application/views/
中创建一个名为 content.php
的新文件,并将以下简单的 HTML 放入其中:
<p> Hello world! </p>
我们现在准备从控制器内加载模板化页面视图。
在任何控制器方法内,放置以下代码以在 default
模板内显示 content
视图。
$data = array( 'title' => 'Title goes here', ); $this->load->library('template'); $this->template->load('default', 'content', $data);
注意:必须先加载该库,然后才能调用 load
方法。为了避免每次需要显示模板视图时加载库,
通过将类添加到 application/config/autoload.php
中的库数组来自动加载该类。
如果您希望在模板中嵌入字符串而不是视图文件,只需使用键 body
将字符串分配给 $data
数组,并传递 null
作为加载调用中的第二个参数。
$data = array( 'title' => 'Title goes here', 'body' => 'The string to be embedded here!' ); $this->template->load('default', null, $data);
我发现按控制器甚至它们所属的方法将视图文件分组到文件夹中确实有助于使我的视图井然有序且易于查找。
以这种方式组织视图会导致目录结构紧密遵循 controller/method
的 URL 架构。
例如,假设您的项目有一个名为 Members
的控制器,包含方法 list
。
list
视图文件的适当位置应位于 application/views/members
或 application/views/members/list
(如果此方法加载多个视图)。
然后可以使用我们的库通过以下代码将该视图嵌入到模板中:
$this->template->load('template_name', 'members/list');
本教程中讨论的模板解决方案只是在 CodeIgniter 中实现模板的众多不同方法之一。
希望您现在应该知道什么是视图,以及如何在您的 CodeIgniter 项目中有效且高效地使用它们。
本教程中讨论的模板解决方案只是在 CodeIgniter 中实现模板的众多不同方法之一。有多种不同的方法,我鼓励读者研究其他方法并确定哪种方法最适合您的项目。
如果您对本教程有任何意见或疑问,或者对不同模板解决方案有任何见解,请在下面发表评论!感谢您的阅读。
以上是CodeIgniter:探索視圖與模板的詳細內容。更多資訊請關注PHP中文網其他相關文章!