iT邦幫忙

0

ThinkPHP V5.1 新增控制器

還不會創建ThinkPHP V5.1專案的朋友們可以先去看看創建ThinkPHP V5.1專案

何謂MVC?

所謂的MVC指的是分離資料、介面和操作等業務,讓分工可以更加細化。
MVC展開來看就是Model-View-Controller。

  • Model,直譯過來就是模型。意思是將資訊的各種屬性按照特定標準組合在一起,形成的一個操作對象。也可以理解為根據與業務相關的特徵來描摩現實中的事物。
  • View,一般譯為視圖。顧名思義就是如何將業務對象的屬性展示出來。這個部分涉及到的邏輯操作一般比較少。
  • Controller,翻作控制器。用來調控程式的時序、處理交互事件等,通常組織協調模型和視圖之間的互動。

ThinkPHP V5.1 裡的MVC目錄結構

ThinkPHP V5.1裡的MVC相關文件一般都放在application目錄裡。
這裡分成兩種情況:

支持多模組(預設)

支持多模組的情況下,要新增控制器就必須要在application下面新增一個模組資料夾。這個資料夾下面再有model、view、controller三個資料夾,而我們的控制器文件就放在controller目錄下。

  • 比如添加一個含有Reader控制器的module模組:
    application/module/controller/Reader.php
    同理,也會有:
    application/module/view/
    application/module/model/
    這兩個部分以後會詳述,今天的關注重點放在控制器上。

單一模組

如果網頁程式特別單純,只需要一個控制器模組不需要多個模組,可以到config資料夾裡的app.php文件裡將'app_multi_module' => false,改成'app_multi_module' => true,。這樣一來,可以直接在application目錄下加上controller目錄,不需要再套一層模組資料夾(我們往後的說明都採用單模組,今天是為了演示模組跟控制器的關係,所以採用預設的多模組)。

  • 例如,新增一個Reader控制器:
    application/controller/Reader.php

控制器文件規範

控制器在設計方面有一些硬性規定:

  • 文件名稱必須大寫開頭,所以上面的Reader.php都是大寫開頭。
  • 必須聲明命名空間namespace。
    比如上述application/module/controller/Reader.php的Reader.php會有這麼一行:
    namespace app\module\controller;
    app對應的是application目錄,module對應模組名稱,controller對應controller目錄。
    那麼,在單一模組的情況下,application/controller/Reader.php的namespace會是這樣:
    namespace app\controller;
  • 一個控制器文件裡面只能有一個類別,且類別必須與文件同名。
  • 每個類別中都要有一個index函數,如果網址沒有輸入方法名,預設呼叫index方法。
    所以,Reader.php裡面只會有一個Reader類,最好也跟文件名一樣大寫開頭:
application/module/controller/Reader.php
<?php
namespace app\module\controller;

class Reader
{
    public function index()
    {
        ...
    }
}

控制器名稱與訪問方法

  • 駝峰命名法
    所謂駝峰命名法指的是,當把多個單詞連接起來時,每個詞的開頭用大寫表示分界,例如hello world是兩個詞彙,把它們組合起來就要變成helloWorld。假設我們在module模組下面增加一個HelloWorld控制器:
    application/module/controller/HelloWorld.php
application/module/controller/HelloWorld.php
<?php
namespace app\module\controller;

class HelloWorld
{
    public function index()
    {
        ...
    }
}

大概很多人會疑惑,這不是一種命名慣例而已嗎?為何要專門挑出來說?
這是因為當你要在網址中呼叫某個控制器時,預設是不能輸入大寫字母的。

比如我要訪問Reader控制器的index方法,我在網址列中要輸入域名/public/module/reader/index,那麼要訪問HelloWorld控制器是不是直接改成域名/public/module/helloworld/index就行了?

答案是否定的,如果這麼寫會報錯,因為域名/public/module/helloworld/index對應的是Helloworld控制器,而非HelloWorld控制器。

那要怎麼正確訪問HelloWorld控制器呢?方法有兩個:

  • 把非開頭大寫字母改成_加對應小寫字母
    在這個例子中,把網址改成域名/public/module/hello_world/index/就可以訪問HelloWorld控制器了。
  • 修改配置文件
    配置文件指的是放在專案根目錄下的config目錄裡的app.php。
    在文件裡會有一個'url_convert' => true,把這一行改成'url_convert' => false,這樣網址就不會轉變大小寫了,可以直接輸入原定名稱來訪問。但一般不建議這麼做。

繼承控制器基類Controller

一般的MVC程式在實作控制器的時候都會繼承控制器基類,ThinkPHP也不例外。
要繼承控制器的方法是加上一行use think\Controller;,然後在類別名稱後面加上extends Controller。
use think\Controller;意思是引用thinkphp/library/think/Controller.php。這裡定義了Controller基類的內容,有興趣的讀者們可以自己去閱讀代碼。在引用了控制器基類後,使用extends關鍵字來繼承。
如果Reader控制器要繼承Controller,代碼就會如下:

application/module/controller/Reader.php
<?php
namespace app\module\controller;

use think\Controller;

class Reader extends Controller
{
    public function index()
    {
        ...
    }
}

事實上,在ThinkPHP裡面並沒有強制控制器一定要繼承基類。有很多靈活的方法可以在不繼承基類的情況下實現一樣的功能。

控制器命名空間配置

相信有些小夥伴會有一個疑惑:
模組明明是放在根目錄/application/下面,為何控制器裡的命名空間卻是寫成app
比如,application/module/controller/Reader.php的命名空間為何要寫成namespace app\module\controller;,而不是namespace application\module\controller;

app是預設的寫法。

如果不習慣,想改成其他寫法的話,可以在專案根目錄下新增一個.env文件。
內容是一個用等號隔開的鍵值對:配置選項=配置內容。控制器命名空間的鍵名是app_namespace,如果想要讓命名空間的app變成application(我知道你並不想),文件內容如下:

app_namespace=application

內容不需要用引號包裹,就是這麼單純。
這樣,以後命名空間都必須寫成namespace application\module\controller;了。

下一篇,我會來介紹控制器的使用方法。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言