- FuelPHP 教程
- FuelPHP - 首頁
- FuelPHP - 簡介
- FuelPHP - 安裝
- FuelPHP - 架構概述
- FuelPHP - 簡單 Web 應用
- FuelPHP - 配置
- FuelPHP - 控制器
- FuelPHP - 路由
- FuelPHP - 請求 & 響應
- FuelPHP - 檢視
- FuelPHP - 展示器
- FuelPHP - 模型 & 資料庫
- FuelPHP - 表單程式設計
- FuelPHP - 驗證
- 高階表單程式設計
- FuelPHP - 檔案上傳
- FuelPHP - Ajax
- FuelPHP - HMVC 請求
- FuelPHP - 主題
- FuelPHP - 模組
- FuelPHP - 包
- Cookie & Session 管理
- FuelPHP - 事件
- FuelPHP - 郵件管理
- FuelPHP - 效能分析器
- 錯誤處理 & 除錯
- FuelPHP - 單元測試
- 完整的執行示例
- FuelPHP 有用資源
- FuelPHP 快速指南
- FuelPHP - 有用資源
- FuelPHP - 討論
FuelPHP 快速指南
FuelPHP - 簡介
FuelPHP是一個開源的Web應用程式框架。它是用PHP 5.3編寫的,並實現了HMVC模式。HMVC是分層模型-檢視-控制器框架,它允許子請求控制器,返回部分頁面,例如評論、選單等,而不是像普通MVC那樣返回完整的頁面。
FuelPHP的建立是為了結合CodeIgniter和Kohana等框架的最佳實踐,並加入自身改進和理念。FuelPHP的資料庫遷移工具和腳手架功能受到流行的Ruby on Rails框架的啟發。
FuelPHP透過一個名為“Oil”的實用程式充分利用了命令列的強大功能。該實用程式旨在幫助加快開發速度,提高效率,進行測試、除錯和HTML支援。
FuelPHP純粹是一種面向物件的方法。其架構基於模組化的思想。應用程式可以分為模組,每個元件都可以擴充套件或替換,而無需重寫一行程式碼。Fuel支援任何模板解析器,例如Smarty、Twig、PHPTal等,用於解析檢視。
FuelPHP社群龐大且活躍,擁有超過300名貢獻者。其龐大的社群定期建立和改進包和擴充套件。FuelPHP框架的主要目標是提供靈活性和相容性。它快速、易於學習,並且是開發Web應用程式的完整解決方案。
使FuelPHP成為PHP開發人員使用的頂級框架之一的原因是——由於其穩定的API,FuelPHP的新版本與舊版本向後相容。它非常靈活。
包和模組使以系統化的方式輕鬆簡單地重用現有程式碼成為可能。FuelPHP透過小型庫提供最大效能。其互動式除錯允許輕鬆消除開發中的錯誤。此外,其簡潔穩定的程式碼使程式設計更容易。
FuelPHP - 特性
FuelPHP提供了許多特性來建立一個功能齊全的Web應用程式。它提供靈活的元件、簡單的配置、易於使用的ORM、基於REST的應用程式開發模式等。以下是一些主要特性:
- 靈活且社群驅動的Web框架
- 易於配置和使用
- FuelPHP極其便攜,幾乎可以在任何伺服器上執行
- 靈活的URI路由系統
- FuelPHP提供RESTful API開發支援
- 輕量級ORM模型
- 輸入過濾並防止SQL注入
- 安全的身份驗證和授權框架
- 程式碼可重用且易於維護
- 自動載入類、會話管理和異常處理。
FuelPHP - 優勢
FuelPHP是一個優雅的HMVC PHP 5.3框架,提供了一套用於構建Web應用程式的元件,具有以下優勢:
模組化結構 - Fuel不會強制你使用模組或HMVC檔案結構。如果你想使用,整合過程非常容易。FuelPHP應用程式以模組化結構建立,使開發人員更容易獲得明確的好處。
HMVC模式 - 此框架最重要的特性是HMVC(分層模型檢視控制器),它使訪問或使用更高級別的任何屬性、類方法、函式、檔案變得容易。
安全的雜湊函式 - FuelPHP支援強大的密碼工具和密碼雜湊技術。它使用強大的PHPSecLib處理加密、解密和雜湊。
腳手架功能 - 腳手架是一種用於構建資料庫操作的超程式設計方法。Fuel的腳手架非常簡單。它允許你透過非常簡單的步驟獲得基本的CRUD應用程式。
以下流行產品使用FuelPHP框架:
Matic Technology - 全球離岸定製軟體開發解決方案提供商。在Matic Technologies,他們根據客戶的要求,透過FuelPHP提供所有可能的最佳解決方案。
Kroobe - Kroobe是一家社交網路分類資訊公司。Fuel為Kroobe團隊提供了極低的開發成本和服務,以實現高效的解決方案。
FuelPHP - 安裝
本章解釋如何在你的機器上安裝FuelPHP框架。FuelPHP的安裝非常簡單易行。你有兩種方法可以建立FuelPHP應用程式:
第一種方法是使用名為Oil的FuelPHP工具進行命令列安裝。
第二種方法是基於Composer的安裝。FuelPHP使用Composer進行安裝和包依賴管理,因此請確保在繼續操作之前已在本地安裝了composer。
讓我們在後續章節中詳細逐一介紹每種方法。
系統要求
在進行安裝之前,必須滿足以下系統要求。
Web伺服器(以下任一)
- WAMP(Windows)
- Microsoft IIS(Windows)
- LAMP(Linux)
- MAMP(Macintosh)
- XAMP(多平臺)
- Nginx(多平臺)
- PHP內建開發Web伺服器(多平臺)
瀏覽器支援(以下任一)
- IE(Internet Explorer 8+)
- Firefox
- Google Chrome
- Safari
PHP相容性 - PHP 5.3或更高版本。為了獲得最大的好處,請使用最新版本。
在本教程中,讓我們使用PHP的內建開發Web伺服器。內建開發Web伺服器易於啟動,並且足以理解FuelPHP Web應用程式的基礎知識,而無需深入瞭解Web伺服器和配置的世界。
命令列安裝
FuelPHP的命令列安裝非常簡單,最多需要五分鐘。
安裝Oil包
Oil是FuelPHP框架提供的一個特殊包/命令,用於執行FuelPHP應用程式開發中所需的許多工,包括安裝、開發和測試應用程式。
要安裝Oil包,請開啟shell並執行以下命令:
sudo curl https://get.fuelphp.com/oil | sh
該命令使用curl下載並安裝oil包。該命令將顯示類似於以下資訊的輸出,並最終安裝oil包。
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 479 100 479 0 0 353 0 0:00:01 0:00:01 --:--:-- 353
建立新專案
要使用Oil建立新專案,請使用以下命令:
oil create <project_name>
讓我們使用以下命令建立一個名為“HelloWorld”的新專案。
oil create HelloWorld
現在,你將看到類似於以下的響應,並最終建立一個簡單的FuelPHP應用程式框架。
composer create-project fuel/fuel HelloWorld
Installing fuel/fuel (1.8.0.1)
- Installing fuel/fuel (1.8.0.1)
Loading from cache
Created project in HelloWorld
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing composer/installers (v1.3.0)
Loading from cache
- Installing fuelphp/upload (2.0.6)
Loading from cache
- Installing michelf/php-markdown (1.4.0)
Loading from cache
- Installing psr/log (1.0.2)
Loading from cache
- Installing monolog/monolog (1.18.2)
Loading from cache
- Installing phpseclib/phpseclib (2.0.0)
Loading from cache
- Installing fuel/core (1.8.0.4)
Loading from cache
- Installing fuel/auth (1.8.0.4)
Loading from cache
- Installing fuel/email (1.8.0.4)
Loading from cache
- Installing fuel/oil (1.8.0.4)
Loading from cache
- Installing fuel/orm (1.8.0.1)
Loading from cache
- Installing fuel/parser (1.8.0.4)
Loading from cache
- Installing fuel/docs (1.8.0.4)
Loading from cache
…………….
…………….
Writing lock file
Generating autoload files
Oil版本
要測試Oil是否可用以及檢查版本,請使用以下命令:
$ cd HelloWorld $ php oil -v
以上命令產生以下結果:
Fuel: 1.8 running in "development" mode
Oil幫助命令
要獲取Oil的基本幫助文件,請使用以下命令:
$ php oil help
以上命令將顯示類似於以下結果的幫助文件:
Usage: php oil [cell|console|generate|package|refine|help|server|test] Runtime options: -f, [--force] # Overwrite files that already exist -s, [--skip] # Skip files that already exist -q, [--quiet] # Supress status output -t, [--speak] # Speak errors in a robot voice Description: The 'oil' command can be used in several ways to facilitate quick development, help with testing your application and for running Tasks. Environment: If you want to specify a specific environment oil has to run in, overload the environment variable on the commandline: FUEL_ENV=staging php oil <commands> More information: You can pass the parameter "help" to each of the defined command to get information about that specific command: php oil package help Documentation: http://docs.fuelphp.com/packages/oil/intro.html
目前,你已經瞭解瞭如何使用Oil安裝Fuel。讓我們在下一節中瞭解基於composer的安裝。
基於Composer的安裝
以下命令用於使用Composer安裝FuelPHP。
$ composer create-project fuel/fuel --prefer-dist.
Git倉庫克隆
要安裝最新的開發版本作為本地git倉庫克隆,請使用以下命令。
$ composer create-project fuel/fuel:dev-1.9/develop --prefer-source.
執行應用程式
移動到專案目錄的public資料夾,使用以下命令使用生產伺服器執行應用程式。
$ cd path/to/HelloWorld/public $ php -S localhost:8080 index.php
它會產生以下響應。
PHP 5.5.31 Development Server started at Sun May 21 12:26:10 2017 Listening on https://:8080 Document root is /Users/workspace/php-fuel/HelloWorld/public Press Ctrl-C to quit.
現在,請求URL,https://:8080,它將產生以下結果。
結果
這是在開發環境中執行FuelPHP應用程式的最簡單方法。如果你在生產環境中以這種方式建立應用程式,將會面臨安全問題。推薦的方法是設定虛擬主機配置。下一節將針對apache web伺服器進行解釋。
設定虛擬主機
這是訪問FuelPHP應用程式更安全的方法。要設定虛擬主機,你需要將apache虛擬主機檔案連結到你的應用程式。對於內網應用程式,將系統主機檔案URL重定向到虛擬主機。
虛擬主機檔案
開啟虛擬主機並新增以下更改。
<VirtualHost *:80>
ServerName hello.app
DocumentRoot /path/to/public
SetEnv FUEL_ENV “development”
<Directory /path/to/public>
DirectoryIndex index.php
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
系統主機檔案
現在,使用以下命令向你的機器新增主機條目。
sudo vi /etc/hosts
然後,將以下行新增到檔案的末尾。
127.0.0.1 hello.app
為了使所有更改生效,請重新啟動你的Apache伺服器並請求url,http://hello.app。它將顯示FuelPHP主頁。
FuelPHP - 架構概述
FuelPHP基於經過實戰檢驗的模型-檢視-控制器架構以及HMVC(分層MVC)支援。MVC提供了靈活的分層應用程式開發,而HMVC則更進一步,能夠將Web應用程式部件化。
FuelPHP的優勢在於它不強制使用特定的應用程式開發方式。它只提供一個簡單易用的標準結構。開發人員可以自由使用FuelPHP提供的預定義功能集,或者根據需要修改它。FuelPHP提供的所有功能,包括核心功能,都可以根據應用程式的要求進行更改。
模型
模型是應用程式的業務實體。控制器和檢視以模型的形式交換資料。模型使我們的業務資料能夠統一表示。它使資料庫層能夠以標準方式與Web應用程式層互動,並提供選擇、儲存、編輯和刪除資料庫實體的選項。
控制器
一個典型的MVC應用程式從控制器開始。一旦使用者向FuelPHP Web應用程式傳送請求,應用程式就會收集有關該請求的所有資訊並將其傳送到控制器。控制器執行請求頁面的必要業務邏輯,然後呼叫相關的檢視以及以模型形式處理後的資料。
檢視
檢視是MVC應用程式的表示層。檢視決定如何向用戶顯示模型。它支援從簡單資料渲染到高階佈局,這使得網站能夠在所有頁面上規範設計。檢視還提供主題支援,這使得能夠快速更改應用程式中的設計。
展示器
Presenter是FuelPHP提供的一個特殊功能。它是控制器(Controller)和檢視(View)之間的橋樑。控制器可以將一些底層職責,例如從資料庫檢索模型、為檢視生成資料等,委託給Presenter。控制器呼叫Presenter而不是直接呼叫檢視,而Presenter再呼叫檢視。Presenter實現了業務邏輯和表示層的純分離。
分層MVC
FuelPHP提供了一個選項,允許一個控制器呼叫另一個控制器,類似於來自客戶端(瀏覽器)的請求。如果一個控制器呼叫另一個控制器,被呼叫的控制器將把響應返回給呼叫控制器,而不是將其渲染到客戶端(瀏覽器)。這使得Web應用程式可以實現**部件化(widgetization)**。例如,評論區既可以作為一個獨立頁面顯示,也可以作為主頁面(部落格)的一個子部分顯示。
模組 (Module)
FuelPHP 的一個顯著特點是,可以將Web應用程式的一部分轉換為模組,這些模組可以在不同的應用程式之間共享。例如,為一個應用程式建立的部落格模組,只需將模組程式碼從源應用程式複製到目標應用程式,即可在另一個應用程式中重用。
需要注意的是,建立新模組與開發主應用程式一樣簡單。其結構與主應用程式類似,唯一的區別在於模組應該編碼在一個單獨的資料夾中。
包 (Package)
FuelPHP提供了一個選項,可以將程式碼組織成一個名為“包”的單元。一個包可以包含Web應用程式所需的一個或多個功能。例如,資料庫元件(如ORM、電子郵件等)可以組織成一個包,並在需要時使用。
包與模組的不同之處在於,包不包含任何網頁或網頁片段。包既可以在FuelPHP中使用,也可以在任何其他PHP框架中使用。
工作流程
FuelPHP的工作流程簡單易懂。下圖描述了該流程。
使用者嚮應用程式傳送請求。
控制器接收請求,並透過與模型互動來收集資訊,而模型又與資料庫互動。
控制器透過向其他控制器傳送子請求來收集資訊。
控制器將檢索到的模型傳送給檢視,檢視生成表示並將其作為響應傳送給客戶端。
在某些情況下,控制器可能會將控制權傳遞給Presenter。在這種情況下,Presenter從模型收集資訊並將其傳送給客戶端。在這裡,Presenter不執行任何業務邏輯,只從資料庫檢索模型。
FuelPHP - 簡單 Web 應用
本章將介紹如何在FuelPHP框架中建立一個簡單的應用程式。正如前面所討論的,您知道如何在Fuel中建立一個新專案。我們可以以員工詳細資訊為例。
讓我們首先使用以下命令建立一個名為Employee的專案。
oil create employee
執行命令後,將建立一個名為**employee**的專案,其**檔案結構**如下:
employee ├── CHANGELOG.md ├── composer.json ├── composer.lock ├── composer.phar ├── CONTRIBUTING.md ├── fuel │ ├── app │ │ ├── bootstrap.php │ │ ├── cache │ │ ├── classes │ │ ├── config │ │ ├── lang │ │ ├── logs │ │ ├── migrations │ │ ├── modules │ │ ├── tasks │ │ ├── tests │ │ ├── themes │ │ ├── tmp │ │ ├── vendor │ │ └── views │ ├── core │ │ ├── base56.php │ │ ├── base.php │ │ ├── bootstrap.php │ │ ├── bootstrap_phpunit.php │ │ ├── classes │ │ ├── composer.json │ │ ├── config │ │ ├── CONTRIBUTING.md │ │ ├── lang │ │ ├── phpunit.xml │ │ ├── tasks │ │ ├── tests │ │ ├── vendor │ │ └── views │ ├── packages │ │ ├── auth │ │ ├── email │ │ ├── oil │ │ ├── orm │ │ └── parser │ └── vendor │ ├── autoload.php │ ├── composer │ ├── fuelphp │ ├── michelf │ ├── monolog │ ├── phpseclib │ └── psr ├── LICENSE.md ├── oil ├── public │ ├── assets │ │ ├── css │ │ ├── fonts │ │ ├── img │ │ └── js │ ├── favicon.ico │ ├── index.php │ └── web.config ├── README.md └── TESTING.md 42 directories, 21 files
應用程式結構
FuelPHP框架提供了一個組織良好的應用程式結構。讓我們檢查一下應用程式中一些重要的檔案和資料夾。
**fuel** - 包含所有PHP檔案。
**public** - 包含所有可透過瀏覽器直接訪問的資源,例如JavaScript、CSS、影像等。
**oil** - 用於執行命令列任務的可執行檔案,例如生成程式碼或在應用程式中進行互動式除錯。這是可選的。
**fuel/app/** - 包含所有特定於應用程式的PHP檔案。它包含模型、檢視和控制器。
**fuel/core/** - Fuel框架本身位於此處。
**fuel/packages/** - 包含所有Fuel包。預設情況下,Fuel將包含三個包:oil、auth和orm。除非您需要它們,否則這些包不會被載入。
**fuel/app/config/** - 包含所有與應用程式相關的配置檔案。主要的應用程式配置檔案config.php位於此處。
**fuel/app/classes/** - 包含所有基於MVC的特定於應用程式的PHP檔案。它包含控制器、模型、輔助類、庫等。
**fuel/app/classes/controller/** - 控制器放置在此處。
**fuel/app/classes/model/** - 模型放置在此處。
**fuel/app/views/** - 包含檢視檔案。檢視沒有特定的命名約定。
新增控制器
如前所述,FuelPHP 基於模型-檢視-控制器 (MVC) 開發模式。MVC是一種軟體方法,它將應用程式邏輯與表示分離。在MVC模式中,控制器扮演著重要的角色,應用程式中的每個網頁都需要由控制器處理。預設情況下,控制器位於**fuel/app/classes/controller/**資料夾中。您可以在此處建立您自己的控制器類。
轉到fuel/app/classes/controller/位置並建立employee.php檔案。要建立一個新的控制器,只需擴充套件FuelPHP提供的Controller類,定義如下。
employee.php
<?php
class Controller_Employee extends Controller {
public function action_home() {
// functionality of the home page
echo "FuelPHP-Employee application!";
}
}
現在,我們建立了一個Employee控制器並添加了一個公共方法action_home,它列印一個簡單的文字。
路由
路由將網頁URI解析為特定的控制器和操作。FuelPHP應用程式中的每個網頁在控制器實際執行之前都應經過路由。預設情況下,每個控制器可以使用以下URI模式解析。
<controller>/<action>
其中:
**controller** 是控制器名稱,不包含名稱空間,例如employee
**action** 是方法名稱,不包含action_關鍵字,例如home
新建立的控制器可以透過**https://:8080/employee/home**訪問,並將產生以下結果。
結果
FuelPHP - 配置
在本章中,我們將瞭解如何配置FuelPHP應用程式。預設情況下,配置檔案儲存在**fuel/app/config**資料夾中。應用程式的主要配置是**fuel/app/config/config.php**。配置使用PHP的關聯陣列指定。
概述
預設情況下,所有預設配置檔案都在**fuel/core/config**資料夾中定義。要覆蓋預設配置,請在**fuel/app/config/config.php**檔案中新增相應的鍵並修改其值。我們可以使用“點表示法”來簡化多維陣列。例如,以下配置具有相同的用途(載入指定的包)。
array("always_load" => array("packages" => array( ... ) ) );
always_load.packages = array( ... );
配置可以按用途分組,並使用不同的檔案指定,例如db.php用於資料庫配置,package.php用於包管理等。
配置格式型別
FuelPHP非常靈活,並提供不同的格式來指定配置。預設配置格式是使用php陣列的PHP。其他選項包括:
**INI** - 許多軟體(包括PHP語言本身)都支援的簡單的基於文字的配置。
[group] key = value
**YAML** - 易於理解、基於縮排且易於閱讀的配置管理。
group: key: value
**JSON** - 易於理解,並且是開發人員最常用的檔案格式。
{
"group" :
{
"key": "value"
}
}
**Memcached** - 將配置儲存在Memcached伺服器中。Memcached伺服器詳細資訊可以在主配置檔案**fuel/app/config/config.php**中使用**config.memcached**條目指定。
**DB** - 將配置儲存在RDBMS系統中。配置表的表結構如下。
CREATE TABLE IF NOT EXISTS `config` ( `identifier` char(100) NOT NULL, `config` longtext NOT NULL, `hash` char(13) NOT NULL, PRIMARY KEY (`identifier`) )
可以使用config.database和config.table_name條目在配置檔案中指定資料庫和表詳細資訊。
環境
環境使FuelPHP能夠透過載入不同的配置以不同的模式工作。FuelPHP支援以下環境:
**開發 (Development)** - `\Fuel::DEVELOPMENT` 設定開發模式
**生產 (Production)** - `\Fuel::PRODUCTION` 設定生產模式
**測試 (Test)** - `\Fuel::TEST` 設定測試模式
**預釋出 (Staging)** - `\Fuel::STAGING` 設定預釋出模式
FuelPHP還支援建立新的環境。這將使每個開發人員擁有自己的配置設定,他們可以在編碼和測試應用程式時啟用它。特定環境的配置可以透過簡單地建立一個帶有環境名稱的資料夾(例如:test)並將配置檔案放在新建立的資料夾中來新增,如下所示。
. ├── config.php
├── db.php
├── development
│ └── db.php
├── production
│ └── db.php
├── routes.php
├── staging
│ └── db.php
└── test
└── db.php
4 directories, 7 files
設定您的環境
有三種方法可以設定您的環境。
**選項1** - 使用Web伺服器的環境變數設定環境。在Apache Web伺服器的**httpd.conf**檔案的虛擬主機部分新增以下程式碼。它也可以新增到**.htaccess**檔案中。
SetEnv FUEL_ENV production
**選項2** - 使用FuelPHP引導檔案**fuel/app/bootstrap.php**設定環境
Fuel::$env = (isset($_SERVER['FUEL_ENV']
**選項3** - 使用Oil設定環境
$ env FUEL_ENV = production php oil -v
它會產生以下結果。
Fuel: 1.8 running in "production" mode
FuelPHP - 控制器
**控制器**負責處理進入FuelPHP應用程式的每個請求。根據FuelPHP,控制器位於**fuel/app/classes/controller/**。讓我們首先建立一個Employee控制器。
employee.php
<?php
class Controller_Employee extends Controller {
public function action_home() {
echo "FuelPHP-Employee application!";
}
public function action_index() {
echo "This is the index method of employee controller";
}
}
控制器方法
控制器使用其一個**action_**方法來處理Web請求。我們可以根據應用程式的要求建立任意數量的action_方法。預設的action_方法是action_index。可以使用以下任何一個URL呼叫action_index方法。
https://:8080/employee/index https://:8080/employee/
結果
讓我們在我們的**employee**應用程式中建立一個新的**action**方法,action_show。
<?php
class Controller_Employee extends Controller {
public function action_home() {
echo "FuelPHP-Employee application!";
}
public function action_index() {
echo "This is the index method of employee controller";
}
public function action_show() {
echo "This is the show method of employee controller";
}
}
可以使用以下URL呼叫action_show方法。
https://:8080/home/show
結果
before() 方法
我們可以在控制器中建立一個方法before。此方法將在每次呼叫action_方法之前執行。如果該方法不存在,則不會呼叫此方法。此方法幫助我們編寫常見的操作,例如登入檢查、預設資料獲取等。
讓我們建立一個before方法並列印一條簡單的文字訊息。
public function before() {
echo "This message comes from <em>before()</em> method</br>";
}
帶有before操作的索引頁面
帶有before操作的顯示頁面
after() 方法
after()方法類似於before()方法,但在呼叫action_方法之後執行。after()方法以response作為輸入並返回response物件。
public function after($response) {
if ( ! $response instanceof Response) {
$response = \Response::forge($response, $this->response_status);
}
return $response;
}
如果輸入為NULL或不是response物件,則使用Response的forge方法建立一個新的Response物件並返回它。我們將在後續章節中詳細學習Response類。
擴充套件控制器
我們可以從另一個控制器擴充套件一個控制器。以下是基本語法。
class Controller_Employee extends Controller_Welcome {
// controller methods
}
這將有助於共享方法。
生成控制器
Fuel可以選擇使用Oil命令生成控制器。以下是語法。
語法
oil g controller <controller-name>
示例
oil g controller sample
執行上述命令後,您將看到以下響應。
結果
Creating view: /path/to/project/fuel/app/views/template.php Creating view: /path/to/project/fuel/app/views/sample/index.php Creating controller: /path/to/project/fuel/app/classes/controller/sample.php
控制器型別
FuelPHP為各種目的提供了不同型別的控制器。它們如下:
- 基礎控制器 (Base controller)
- 模板控制器 (Template controller)
- REST控制器 (Rest controller)
- 混合控制器 (Hybrid controller)
基礎控制器 (Base Controller)
控制器是FuelPHP中所有不同型別控制器的基控制器。它提供處理Web請求所需的所有基本功能。它支援請求、響應、會話等。除非另有說明,否則我們將在所有示例中使用它。
模板控制器
模板控制器是基控制器的擴充套件。它具有模板支援,預定義的before()和after()方法。基本上,它可以用於將您的檢視包裝在具有頁首、頁尾、側邊欄等的佈局中。要建立模板控制器,我們需要擴充套件Controller_Template類。預設情況下,擴充套件Controller_Template類的所有方法都需要使用模板。
其定義如下。
class Controller_Employee extends Controller_Template {
public function action_index() {
// add methods
}
}
我們將在檢視章節中更詳細地討論模板控制器。
REST控制器
REST控制器是基控制器的擴充套件。它預先支援REST API程式設計。這將使您可以輕鬆構建API。
要建立REST控制器,您需要擴充套件Controller_Rest類。其定義如下。
class Controller_Employee extends Controller_Rest {
public function action_index() {
// add methods
}
}
我們將在Ajax章節中更詳細地討論REST控制器。
混合控制器
混合控制器在一個基控制器中執行REST控制器和模板控制器的功能。
FuelPHP - 路由
路由將請求URI對映到特定控制器的method。在本節中,我們將詳細討論FuelPHP中路由的概念。
配置
路由配置檔案位於fuel/app/config/routes.php。預設的routes.php檔案定義如下:
<?php
return array (
'_root_' => 'welcome/index', // The default route
'_404_' => 'welcome/404', // The main 404 route
'hello(/:name)?' => array('welcome/hello', 'name' => 'hello'),
);
這裡,_root_是預定義的預設路由,當應用程式使用根路徑/(例如https://:8080/)請求時,將匹配它。_root_的值是在匹配時要解析的控制器和操作。welcome/index解析為Controller_Welcome控制器和action_index操作方法。同樣,我們還有以下保留路由。
root - 當沒有指定URI時的預設路由。
403 - 當發現HttpNoAccessException時丟擲。
404 - 當頁面未找到時返回。
500 - 當發現HttpServerErrorException時丟擲。
簡單路由
路由與請求URI進行比較。如果找到匹配項,則請求將路由到URI。簡單路由描述如下:
return array ( 'about' => 'site/about', 'login' => 'employee/login', );
這裡,about匹配https://:8080/about並解析控制器Controller_Site和操作方法action_about
login匹配https://:8080/login並解析控制器Controller_Login和操作方法action_login
高階路由
您可以將任何正則表示式包含到您的路由中。Fuel支援以下高階路由功能:
:any - 匹配從該點開始的任何內容,但不匹配“nothing”
:everything - 與:any類似,但也匹配“nothing”
:segment - 只匹配URI中的一個片段,但該片段可以是任何內容
:num - 匹配任何數字
:alpha - 匹配任何字母字元,包括UTF-8
:alnum - 匹配任何字母數字字元,包括UTF-8
例如,以下路由匹配URI https://:8080/hello/FuelPHP並解析控制器Controller_Welcome和操作action_hello
'hello(/:name)?' => array('welcome/hello', 'name' => 'hello'),
Controller_Welcome中相應的操作方法如下:
public function action_hello() {
$this->name = Request::active()->param('name', 'World');
$message = "Hello, " . $this->name;
echo $message;
}
這裡,我們使用了Request類從URL獲取name引數。如果找不到name,則使用World作為預設值。我們將在請求和響應章節學習Request類。
結果
HTTP方法操作
FuelPHP支援匹配HTTP方法字首操作的路由。以下是基本語法。
class Controller_Employee extends Controller {
public function get_index() {
// called when the HTTP method is GET.
}
public function post_index(){
// called when the HTTP method is POST.
}
}
我們可以在配置檔案中根據HTTP動詞將您的URL路由到控制器和操作。
return array (
// Routes GET /employee to /employee/all and POST /employee to /employee/create
‘employee’ => array(array('GET', new Route(‘employee/all')), array('POST',
new Route(‘employee/create'))),
);
FuelPHP - 請求 & 響應
HTTP請求和HTTP響應在任何Web應用程式中都扮演著重要的角色。我們需要獲取HTTP請求的完整詳細資訊才能正確處理它。處理完成後,我們需要透過HTTP響應將處理後的資料傳送到客戶端。
FuelPHP提供出色的Request和Response類分別讀取和寫入HTTP請求和HTTP響應。讓我們在本節中瞭解Request和Response類。
請求
在一個典型的Web應用程式中,應用程式需要解析當前請求的詳細資訊。Request類提供簡單的方法來解析應用程式要處理的當前請求。Request還提供了一個選項,可以透過充當http客戶端來建立一個新的請求。
建立新的請求使應用程式能夠請求應用程式的其他部分或完全不同的應用程式並顯示結果。讓我們在本節中學習如何解析傳入的請求,並在HMVC請求章節中學習如何建立一個新的請求。
解析請求
Request類提供三種方法來獲取HTTP請求的詳細資訊。它們如下:
active - 它是一個靜態方法,返回當前活動的HTTP請求。
$currentRequest = Request::active();
param – 它返回指定引數的值。它包含兩個引數。第一個引數是引數名稱,第二個引數是如果引數在當前HTTP請求中不可用,則返回的值。
$param = Request::active()->param('employee_name', 'none');
params – 與param相同,只是它返回所有引數作為一個數組。
$params = Request::active()->params();
示例
讓我們建立一個簡單的表單,並使用request類處理表單。
步驟1 - 在employee控制器中建立一個新的操作,action_request。
public function action_request() {
}
步驟2 - 呼叫request方法以獲取當前請求的所有引數。
public function action_request() {
$params = Request::active()->params();
}
步驟3 - 轉儲獲取的引數陣列。
public function action_request() {
$params = Request::active()->params();
echo dump($params);
}
步驟4 - 更改路由以在路由配置檔案fuel/app/config/routes.php中包含引數
'employee/request(/:name)?' => array('employee/request', 'name' => 'name'),
現在,請求新的操作https://:8080/employee/request/Jon,它將顯示以下響應。
響應
Response類提供建立HTTP響應的選項。在大多數情況下,我們不需要直接使用response類。相反,我們使用View(我們將在下一節中學習)來建立HTTP響應。View向開發者隱藏HTTP響應,並使用底層的Response類將響應傳送給客戶端。在高階情況下,我們直接使用Response類並建立一個完整的HTTP響應。
建立響應
響應由標頭和正文組成。主標頭是HTTP狀態程式碼。HTTP狀態程式碼是HTTP協議中定義的標準程式碼,用於描述響應。例如,狀態程式碼200表示請求成功。
Response類提供三個引數來建立HTTP響應:
$body - HTTP響應的正文
$status_code - HTTP響應的狀態程式碼
$headers - 可選標頭作為陣列
$body = "Hi, FuelPHP"; $headers = array ( 'Content-Type' => 'text/html', ); $response = new Response($body, 200, $headers);
讓我們在employee控制器中建立一個新的操作action_response,如下所示。
public function action_response() {
$body = "Hi, FuelPHP";
$headers = array ('Content-Type' => 'text/html',);
$response = new Response($body, 200, $headers);
return $response;
}
結果
方法
Response類提供許多方法來操作HTTP響應。它們如下:
forge - 與上面看到的response類建構函式相同。
return Response::forge("Hi, FuelPHP", 404);
redirect - 它提供了一個選項,可以重定向到一個URL,而不是傳送響應。它包含以下引數:
a.url - 目標url b. method - 重定向方法。location(預設)和refresh c. redirect_code - HTTP狀態程式碼。預設值為302。
// use a URL
Response::redirect('http://some-domain/index', 'refresh');
// or use a relative URI
Response::redirect('employee/list');
redirect_back - 與redirect方法類似,只是它重定向到上一頁。如果找不到上一頁,我們可以指定重定向頁面。
// If there is no back page, go to the employee list page
Response::redirect_back('/employee/list', 'refresh');
set_status - 它提供了一個選項來設定HTTP狀態程式碼。
$response = new Response(); $response->set_status(404);
set_header - 它提供了一個選項來設定HTTP標頭。
$response = new Response();
$response->set_header('Content-Type', 'application/pdf');
// replace previous value using third arguments
$response->set_header('Content-Type', 'application/pdf', 'text/plain');
set_headers - 與set_header相同,只是它提供了一個選項,可以使用陣列設定多個標頭。
$response = new Response(); $response->set_headers (array 'Content-Type' => 'application/pdf', 'Pragma' => 'no-cache', ));
get_header - 它可以獲取之前設定的標頭詳細資訊。
$response = new Response();
$response->set_header('Pragma', 'no-cache');
// returns 'no-cache'
$header = $response->get_header('Pragma');
// returns array('Pragma' => 'no-cache')
$header = $response->get_header();
body - 它提供了一個選項來設定HTTP響應的正文。
$response = new Response();
$response->body('Hi, FuelPHP');
// returns 'Hi, FuelPHP'
$body = $response->body();
send_headers - 它將標頭髮送到請求的客戶端。FuelPHP使用此方法將響應傳送到客戶端。通常,我們不需要使用此方法。
$response->send_headers();
send - 與send_headers相同,只是HTTP響應中的標頭可能會受到限制。
// send the headers as well $response->send(true); // only send the body $response->send(false); $response->send();
FuelPHP - 檢視
View是MVC應用程式的表示層。它將應用程式邏輯與表示邏輯分開。當控制器需要生成HTML、CSS或任何其他內容時,它會將任務轉發給檢視引擎。
FuelPHP提供了一個簡單靈活的類View,它具有檢視引擎的所有必要功能。View類支援渲染檢視檔案。檢視檔案是一個HTML頁面,其中嵌入了PHP指令。檢視檔案的變數可以使用View類作為PHP陣列來設定,並使用陣列的鍵在檢視檔案中引用。讓我們檢查View類的一些重要方法。
forge
用途 - 建立一個新的View物件
引數 - 以下是引數
$file - 檢視檔案的路徑,相對於views資料夾,fuel/app/views
$data - 值的陣列
$filter - 設定自動編碼,預設為主配置檔案中的設定
返回 - 檢視的例項
例如:
$view = View::forge ('path/to/view', array(
'title' => "Show employee,
'employees' => $employees,
));
auto_filter
用途 - 設定是否編碼資料
引數 - 以下是引數
$filter - true / false
返回 - 當前檢視物件
例如:
$view->auto_filter(); $view = $view->auto_filter(false);
set_filename
用途 - 允許設定或更改檢視檔案。
引數 - 以下是引數 -
$file - 檢視檔案的路徑,相對於views資料夾,fuel/app/views
返回 - 當前View物件
例如:
$view = new View();
$view>set_filename('path/to/view');
set
用途 - 設定一個或多個變數的值
引數 - 以下是引數
$key - 變數名或值的陣列
$value - 值 / null
$filter - 編碼設定,true / false
返回 - 當前檢視物件
例如:
$view = new View();
$view->set(array('name' => 'Jon'));
set_global
set_global類似於set,只是它適用於所有檢視,並且所有檢視都可以訪問這些變數。這是一個靜態方法。
View::set_global('name', 'Jon', false);
set_safe
用途 - 設定一個或多個變數的值,並啟用安全編碼。
引數 - 以下是引數 -
$key - 變數名或值的陣列
$value - 值 / null
返回 - 當前檢視物件
例如:
$view = new View();
$view->set_safe(array('name' => 'Jon'), null);
get
用途 - 獲取一個或多個變數的值
引數 - 以下是引數
$key - 變數名
$default - 如果找不到鍵,則返回的預設值
返回 - 輸入鍵的值
例如:
$view = new View();
$name = $view>get('name'); // name = 'Jon'
render
用途 - 透過將其與區域性和全域性變數合併,將檢視檔案渲染成字串
引數 - 以下是引數 -
$file − 檢視檔名
返回 − 渲染後的檢視檔案字串
例如:
$html = View::forge()->render('/path/to/view');
建立檢視
為了理解檢視,讓我們修改控制器 `Controller_Employee` 的操作方法 `action_show`。
employee.php
<?php
class Controller_Employee extends Controller {
public function action_show() {
return View::forge('employee/show');
}
}
現在在 `views` 目錄(位於 `fuel/app/views`)下建立一個名為 `employee` 的資料夾。然後,在 `employee` 資料夾內建立一個名為 `show.php` 的檔案,並新增以下程式碼。
show.php
<h3> My first view </h3>
現在,請求 URL `https://:8080/employee/show`,它將產生以下結果。
向檢視傳遞資料
我們可以使用前面討論過的檢視方法向檢視傳遞資料。下面是一個簡單的例子。
employee.php
class Controller_Employee extends Controller {
public function action_show() {
$data = array(); //stores variables going to views
$data['name'] = ‘Jon’;
$data[‘job’] = ‘Designer’;
//assign the view to browser output
return View::forge('employee/show', $data);
}
}
現在,在檢視檔案中新增更改。
show.php
<html>
<body>
Hello, <?php echo $name; ?>.
Your job is, <?php echo $job; ?>.
</body>
</html>
請求 URL 後,它將顯示姓名和職位,如下所示:
檢視過濾器
檢視使用輸出編碼來傳遞任何你想要的內容。如果你想傳遞未過濾的資料,可以使用 `set` 方法。
employee.php
class Controller_Employee extends Controller {
public function action_show() {
$view = \View::forge('employee/show');
$view->set('name', 'Jon', true);
$view->set('job', '<em>Designer</em>', false);
return $view;
}
}
請求 URL 後,它將以強調樣式顯示職位詳情,如下所示。
巢狀檢視
FuelPHP 支援巢狀檢視。在巢狀檢視中,一個檢視可以包含一個或多個檢視。要在一個檢視中設定另一個檢視,可以使用 `render` 方法,如下所示。
employee.php
class Controller_Employee extends Controller {
public function action_nestedview() {
//assign variables
$data = array();
$data['title'] = 'Home';
$data['name'] = 'Jon';
$data['job'] = 'Designer';
$views = array();
$views['head'] = View::forge('head', $data)->render();
$views['content'] = View::forge('employee/show', $data)->render();
return View::forge('layout', $views, false)->render();
}
}
fuel/app/views/layout.php
<html>
<head>
<?php echo $head; ?>
</head>
<body>
<?php echo $content; ?>
</body>
</html>
fuel/app/views/head.php
<title> <?php echo $title; ?> </title>
fuel/app/views/employee/show.php
Hello, <?php echo $name; ?>. Your job is, <?php echo $job; ?>.
請求 URL `https://:8080/employee/nestedview` 並檢查源檢視後,將得到以下程式碼。
<html>
<head>
<title>Home</title>
</head>
<body>
Hello, Jon.
Your job is, Designer.
</body>
</html>
模板控制器
FuelPHP 提供了一個控制器 `Controller_Template`,它具有內建的佈局概念。佈局概念是使用控制器的 `before()` 和 `after()` 方法完成的。要使用模板控制器,需要使用 `Controller_Template` 而不是 `Controller` 來擴充套件控制器。使用 `after()`/`before()` 方法時,需要呼叫 `parent::before` 和 `parent::after`,否則模板會中斷。
<?php
class Controller_Test extends Controller_Template {
public function before() {
parent::before();
// do stuff
}
public function after($response) {
$response = parent::after($response);
// do stuff
return $response;
}
}
template.php
這是 Fuel 中的預設模板檔案。模板檔案用於呼叫 JS、CSS、HTML 和呼叫檢視區域性檔案。它位於 `fuel/app/views/`。模板用於將你的檢視包裝在一個帶有頁首、頁尾、側邊欄等的佈局中。我們可以使用操作方法中的 `$template` 變數來更改預設模板,如下所示。
fuel/app/classes/controller/test.php
<?php
class Controller_Test extends Controller_Template {
public $template = 'template_test';
public function action_index() {
$this->template->title = 'Example Page';
$this->template->content = View::forge('test/index');
}
}
fuel/app/views/template_test.php
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<title><?php echo $title; ?></title>
<?php echo Asset::css('bootstrap.css'); ?>
</head>
<body>
<div>
<?php echo $content; ?>
</div>
</body>
</html>
fuel/app/views/test/index.php
<h3>My Test page</h3>
現在,請求 URL `https://:8080/test`,它將產生以下結果。
結果
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<title>Example Page</title>
<link type = "text/css" rel = "stylesheet"
href = "https://:8080/assets/css/bootstrap.css?1464964766" />
</head>
<body>
<div>
<h3>My Test page</h3>
</div>
</body>
</html>
生成檢視頁面
你可以使用 Fuel 的 Oil 控制檯生成檢視頁面。以下是基本語法。
oil g controller <controller-name> <page1> <page2> ..
要生成一個帶有主頁和登入頁面的管理員控制器,請使用以下命令。
oil g controller admin home login
結果
Creating view: /path/to/app/fuel/app/views/admin/home.php Creating view: /path/to/app/fuel/app/views/admin/login.php Creating controller: /path/to/app/fuel/app/classes/controller/admin.php
FuelPHP - 展示器
FuelPHP 在控制器之後提供了一個額外的層來生成檢視。一旦控制器處理完輸入並完成業務邏輯,它就會將控制權傳送給 **Presenter**,Presenter負責處理額外的邏輯,例如從資料庫獲取資料、設定檢視資料等,然後呼叫 View 物件。
我們可以使用 Presenter 類渲染檢視,如下所示:
fuel/app/classes/controller/employee.php
public Controller_Employee extends Controller {
public function action_welcome() {
return Presenter::forge('employee/hello');
}
}
Presenter 類的預設位置是 `fuel/app/classes/presenter/`。下面是一個簡單的例子。
fuel/app/classes/presenter/employee/hello.php
<?php
class Presenter_Employee_Hello extends Presenter {
public function view() {
$this->name = Request::active()->param('name', 'World');
}
}
上述 Presenter 類的檢視檔案解析為相對於 `views` 資料夾的 `employee/hello.php`,如指定的那樣。
fuel/app/views/employee/hello.php
<h3>Hi, <?php echo $name; ?></h3>
最後,更改路由以匹配員工的歡迎操作,如下所示:
fuel/app/config/routes.php
'employee/hello(/:name)?' => array('employee/welcome', 'name' => 'hello'),
現在,請求 URL `https://:8080/employee/hello/Jon` 將渲染以下結果。
結果
FuelPHP - 模型 & 資料庫
模型在 FuelPHP Web 框架中扮演著重要的角色。它代表應用程式的業務實體。它們要麼由客戶提供,要麼從後端資料庫獲取,根據業務規則進行操作,然後持久化回資料庫。讓我們在本節學習模型以及它們如何與後端系統互動。
建立模型
在 FuelPHP 中,模型只是一個簡單的 PHP 類,它擴充套件了內建的 Model 類。預設情況下,模型可能以 `Model_` 為字首,類似於控制器,並且應該放在 `fuel/app/classes/model/` 資料夾中。讓我們建立一個基本的員工模型,並在我們繼續的過程中對其進行擴充套件。
fuel/app/classes/model/employee.php
<?php
namespace Model;
class Model_Employee extends \Model {
public static function fetchAll() {
// Code to fetch employee from database
}
}
定義模型後,只需在控制器中包含它,就可以在任何控制器中自由使用它,如下所示:
訪問模型
use \Model\Employee;
class Controller_Employee extends Controller {
public function action_index() {
$employees = Employee::fetchAll();
}
}
資料庫概述
FuelPHP 提供了自己的資料庫抽象層來從資料庫中獲取資料。它提供基本的和高階的基於 ORM 的工具。基本工具包包括基於 DB、DBUtil 和 Query_Builer 的類。高階工具包是 Orm。Orm 工具包派生自基本工具包,並作為單獨的包捆綁在一起。
資料庫配置
FuelPHP 將資料庫設定與主配置檔案分開,該檔案為 `fuel/app/config/db.php`。它支援每個環境的單獨設定。目前,FuelPHP 支援 MySQL、MySQLi 和 PDO 驅動程式。示例設定如下:
<?php
return array (
'development' => array (
'type' => 'mysqli',
'connection' => array (
'hostname' => 'localhost',
'port' => '3306',
'database' => 'tutorialspoint_fueldb',
'username' => 'root',
'password' => 'password',
'persistent' => false,
'compress' => false,
),
'identifier' => '`',
'table_prefix' => '',
'charset' => 'utf8',
'enable_cache' => true,
'profiling' => false,
'readonly' => false,
),
)
基於 DB 的工具包
DB 類是從應用程式訪問資料庫的最簡單選項。它提供構建資料庫查詢、針對目標資料庫執行查詢以及最終獲取結果的選項。`DB` 類與以下類互動並提供全面的資料庫 API。
Database_Connection − 單例和與資料庫互動的主要類
Database_Query − 執行 SQL 查詢並獲取結果的基本具體類
Database_Query_Builder − 構建 SQL 查詢的基本抽象類
Database_Query_Builder_Join − 構建 SQL 連線的類
Database_Query_Builder_Where − 構建 SQL 查詢條件的抽象類
Database_Query_Builder_Select − 構建 SQL 選擇查詢的具體類
Database_Query_Builder_Insert − 構建 SQL 插入查詢的抽象類
Database_Query_Builder_Update − 構建 SQL 更新查詢的抽象類
Database_Query_Builder_Delete − 構建 SQL 刪除查詢的抽象類
下圖描述了類之間的關係以及類提供的方法。
DB API
讓我們在本節學習 DB 類中最重要的方法。
instance
用途 − 建立並返回新的 `Database_Connection` 例項。
引數 −
$db − 配置檔案中定義的資料庫連線名稱,可選。
返回 − 返回 `Database_Connection` 物件
例如:
$db = DB::instance();
$db = DB::instance('test');
query
用途 − 準備提供的 SQL 語句並返回 `Database_Query` 物件,該物件可用於插入、更新、刪除或從資料庫中獲取資料。
引數 −
$query − SQL 語句,可能包含佔位符;
$type − SQL 型別,可選 (DB::SELECT, DB::INSERT, DB::UPDATE 和 DB::DELETE)
返回 − 返回 `Database_Query` 物件
例如:
$query = DB::query('SELECT * FROM 'employees'');
last_query
用途 − 獲取最後執行的查詢
引數 − 無
返回 − 返回最後執行的查詢
例如:
$employees = DB::Select('Select * from 'employee'');
$sql = DB::last_query();
select
用途 − 生成查詢的選擇部分
引數 −
$columns − 資料庫列名稱列表
返回 − 返回 `Database_Query_Builder_Select` 物件
例如:
$query = DB::select(); // Select *
$query = DB::select('id', 'name'); // Select id, name
select_array (DB)
它類似於 `select`,只是我們可以將列作為陣列傳送。
$query = DB::select_array(array('id', 'name')); // Select id, name
insert
用途 − 生成查詢的插入部分
引數 −
$table_name − 資料庫表名稱;
$columns − 表列陣列
返回 − 返回 `Database_Query_Builder_Insert` 物件
例如:
$query = DB::insert('employee'); // Insert into employee
$query = DB::insert('employee', array('id', 'name')); // Insert into employee (id, name)
update
用途 − 生成查詢的更新部分
引數 −
$table_name − 資料庫表名稱
返回 − 返回 `Database_Query_Builder_Update` 物件
例如:
$query = DB::update('employee'); // update `employee`
delete
用途 − 生成查詢的刪除部分
引數 −
$table_name − 資料庫表名稱
返回 − 返回 `Database_Query_Builder_Delete` 物件
例如
$query = DB::delete('employee'); // delete from 'employee'
Query API
Database_Query 提供了一個選項來設定資料庫連線、執行查詢並將結果作為關聯陣列或物件獲取。讓我們看看 `Database_Query` 類提供的方法。
set_connection
用途 − 設定要針對其執行查詢的資料庫(資料庫連線詳細資訊)
引數 − `$db` - 資料庫連線名稱
返回 − 返回 `Database_Query` 物件
例如:
$query = DB::query('DELETE * FROM employee', DB::DELETE);
$query->set_connection('2nd-db');
param
用途 − 將值設定為在 Query 物件中定義的引數
引數 −
$param − 引數名稱;
$value − 引數的值
返回 − 返回 `Database_Query` 物件
例如:
// set some variables
$table = 'employee';
$id = 1;
$name = 'Jon';
// don't use
$query = DB::query('SELECT * FROM '.$table.'. WHERE id = '.$id.' AND name = "'.$name.'"');
// but use
$query = DB::query('SELECT * FROM :tablename WHERE id = :id AND name = :name');
$query->param('tablename', 'employee');
$query->param('id', $id);
$query->param('name', $name);
類似的方法
parameters 是一個類似的物件,除了它提供一次給多個值的選項。
$query->parameters (array( 'tablename' => $table, 'id' => $id, 'name' => $name });
bind
用途 − 將變數設定為在 Query 物件中定義的引數
引數 −
$param − 引數名稱
$var − 要將引數繫結到的變數
返回 − 返回 `Database_Query` 物件
例如:
// bind a query parameter
$table = 'employee';
$query = DB::query('DELETE * FROM :tablename', DB::DELETE);
$query->bind('tablename', $table);
// update the variable
$table = 'employee_salary';
// DELETE * FROM `employee_salary`;
$sql = $query->compile();
compile
用途 − 將定義的 Query 物件編譯成 SQL 查詢
引數 −
$db − 連線字串,可選
返回 −
例如:
// assign a value to a query parameter
$table = 'employee';
$query = DB::query('DELETE * FROM :tablename', DB::DELETE);
$query->param('tablename', $table);
// compile the query, returns: DELETE * FROM employee
$sql = $query->compile();
execute
用途 − 執行在 Query 物件中定義的查詢並返回結果
引數 −
$db − 資料庫連線名稱
返回 − 返回結果
例如:
// assign a value to a query parameter
$table = 'employee';
$query = DB::query('DELETE * FROM :tablename', DB::DELETE);
$query->param('tablename', $table);
// execute the query
$query->execute();
as_assoc
用途 − 將返回型別設定為關聯陣列而不是物件
引數 − 無
返回 − 返回當前物件
例如:
$query = DB::query('SELECT * FROM employee', DB::SELECT);
$result = $query->as_assoc()->execute();
foreach ($result as $row) {
echo $row['id'];
}
as_object
用途 − 將返回型別設定為物件而不是關聯陣列
引數 − 無
返回 − 返回當前物件
例如:
$query = DB::query('SELECT * FROM employee', DB::SELECT);
$result = $query->as_object()->execute();
foreach ($result as $row) {
echo $row->id;
}
// have ORM model objects return instead
$result = $query->as_object('Model_Employee')->execute();
Query Builder API
基於 Query builder(`Query_Builder`)的類提供動態構建 SQL 查詢的選項。它有四個類,每個類用於選擇(`Query_Builder_Select`)、插入(`Query_Builder_Insert`)、更新(`Query_Builder_Update`)和刪除(`Query_Builder_Delete`)查詢。這些類派生自 `Query_Builder_Where` 類(生成條件的選項),而 `Query_Builder_Where` 類本身又派生自 `Query_Builder`,它是所有類的基礎。
讓我們看看 `Query_Builder` 類提供的方法。
select
用途 − 生成選擇查詢的列。
引數 −
$columns − 列列表,可選
返回 − 返回當前例項
例如:
$query = DB::select('name') // select `name`
$query = DB::select(array('first_name', 'name')) // select `first_name` as `name`
from
用途 − 生成選擇查詢的表詳細資訊
引數 −
$tables − 表列表
返回 − 返回當前例項
例如:
$query = DB::select('name')->from('employee') // select `name` from `employee`
where
用途 − 生成選擇、插入和更新查詢的條件
引數 −
$column − 列名或陣列(`$column`, `$alias`);
$op − 邏輯運算子,=,!=,IN,BETWEEN 和 LIKE,可選;
$value − 列值
返回 − 返回當前例項
例如:
$query = DB::select('name')->from('employee')
$query = $query->where('name', '=', 'Jon');
// select `name` from `employee` where `name` = `Jon`;
類似的方法
類似的方法有 `where_open()`、`and_where_open()`、`or_where_open()`、`where_close()`、`and_where_close()`、`or_where_close()`。它們類似於 `where()` 方法,只是它們在條件周圍添加了額外的關鍵字和括號。以下是一個示例程式碼。
$query = DB::select('*')->from('employee');
$query->where('email', 'like', '%@gmail.com');
$query->or_where_open();
$query->where('name', 'Jon');
$query->and_where('surname', 'Peter');
$query->or_where_close();
// SELECT * FROM `employee` WHERE `email` LIKE "%gmail.com" OR
(`name` = "Jon" AND `surname` = "Peter")
join
目的 − 生成 select 查詢的表連線
引數 −
$table − 表名或陣列 ($table, $alias);
$type − 連線型別 (LEFT, RIGHT, INNER 等)
返回 − 返回當前例項
示例
$query = DB::select('name')->from('employee')->join('employee_salary')
// select `name` from `employee` JOIN `employee_salary`
on
目的 − 生成 select 查詢中連線的條件
引數 −
$c1 − 表名或帶有別名的表名陣列;
$op − 邏輯運算子;
$c2 − 表名或帶有別名的表名陣列
返回 − 返回當前例項
例如:
$query = DB::select('name')->from('employee')->join('employee_salary')
$query = $query->on('employee.employee_id', '=', 'employee_salary.employee_id')
// select `name` from `employee` JOIN `employee_salary` on
// `employee.employee_id` = `employee_salary.employee_id`
類似的方法
相關方法為 and_on() 和 or_on()。它們與 on() 類似,只是在連線周圍添加了額外的關鍵字和括號。
group_by
目的 − 生成 group by 查詢
引數 − $columns − 用於分組結果的列名
返回 − 返回當前例項
例如:
$query = DB::select('name')->from('employee')
$query = $query->group_by('name');
// select `name` from `employee` group by `name`
having
目的 − 生成 SQL 查詢的 group by 條件
引數 − $column − 列名或陣列 ($column, $alias); $op − 邏輯運算子,=, !=, IN, BETWEEN 和 LIKE,可選; $value − 列值
返回 − 返回當前例項
示例
$query = DB::select('name')->from('employee')
$query = $query->group_by('name');
$query = $query->having('name', '!=', 'Jon');
// select `name` from `employee` group by `name` having `name` != `Jon`
類似的方法
類似的方法有 having_open(),and_having_open(),or_having_open(),having_close(),and_having_close(),or_having_close()。它們與 having() 方法類似,只是在條件周圍添加了額外的關鍵字和括號。
reset
目的 − 重置查詢
引數 − 無
返回 − 返回當前例項
例如:
$query = DB::select('name')->from('employee')
$query->reset()
$query = DB::select('name')->from('employee_salary')
// select `name` from `employee_salary`
DBUtil 類
DBUtil 類提供了一個管理和執行常規資料庫操作的選項。一些重要的方法如下:
- set_connection - 設定預設連線
DBUtil::set_connection('new_database');
- create_database - 建立資料庫。
DBUtil::create_database('my_database');
- drop_database - 刪除資料庫。
DBUtil::drop_database('my_database');
- table_exists - 檢查給定的表是否存在。
if(DBUtil::table_exists('my_table')) {
// Table exists
} else {
// Table does NOT exist, create it!
}
- drop_table - 刪除表。
DBUtil::drop_table('my_table');
- create_table - 建立表。
\DBUtil::create_table (
'users',
array (
'id' => array('type' => 'int', 'auto_increment' => true),
'name' => array('type' => 'text'),
),
);
ORM 工具包
FuelPHP 使用基於流行的活動記錄模式的 ORM 概念提供高階資料庫層。該工具包包含在應用程式中,但預設情況下未配置。它作為一個包捆綁在一起,包名為 orm。我們可以在主配置檔案fuel/app/config/config.php中新增以下配置來載入 orm 工具包。
'always_load' => array (
'packages' => array (
'orm',
),
),
建立模型
ORM 提供了基本的模型類 Orm\Model。我們需要用 orm 模型擴充套件我們的模型才能使用 ORM 功能。以下是一個示例程式碼。
class Model_Employee extends Orm\Model {}
配置
ORM 提供了一組設定來配置模型以使用 ORM 功能。它們如下:
連線 − 在模型中設定靜態_connection屬性以指定連線名稱。
class Model_Employee extends Orm\Model {
protected static $_connection = "production";
}
表名 − 在模型中設定靜態_table_name屬性以指定後端表的表名。
class Model_Employee extends Orm\Model {
protected static $_table_name = 'employee';
}
主鍵 − 在模型中設定靜態_primary_key屬性以指定後端表的主鍵。
class Model_Employee extends Orm\Model {
protected static $_primary_key = array('id');
}
列 − 在模型中設定靜態 _properties 屬性以指定後端表的列。它支援資料型別、標籤、驗證、表單元素等。
class Model_Employee extends Orm\Model {
protected static $_properties = array (
'id',
'name' => array (
'data_type' => 'varchar',
'label' => 'Employee Name',
'validation' => array (
'required',
'min_length' => array(3),
'max_length' > array(80)
),
'form' => array (
'type' => 'text'
),
),
'age' => array (
'data_type' => 'int',
'label' => 'Employee Age',
'validation' => array (
'required',
),
'form' => array (
'type' => 'text'
),
),
);
}
條件 − 設定靜態_conditions屬性以設定條件和排序選項。
class Model_Employee extends Orm\Model {
protected static $_conditions = array (
'order_by' => array('id' => 'desc'),
'where' => array (
array('is_active', > true),
),
);
}
觀察者 − Orm 提供基於觀察者的事件系統,以便為特定事件新增行為。要新增行為,首先在模型中設定_observers屬性。然後,將行為定義為一個類,並將其與事件一起設定在_observers屬性中。如果沒有指定事件,則該行為將針對所有事件呼叫。我們也可以指定多個行為。
class Model_Employee {
protected static $_observers = array (
'example', // will call Observer_Example class for all events
'Orm\\Observer_CreatedOn' => array (
'events' => array('before_insert'),
// will only call Orm\Observer_CreatedOn at before_insert event
)
);
}
建立
配置好模型後,我們可以直接開始使用這些方法。Orm 提供了一個save方法來將物件儲存到資料庫中。我們可以使用配置的屬性設定資料,如下所示:
// option 1
$new = new Model_Employee();
$new->name = 'Jon';
$new->save();
// option 2, use forge instead of new
$new = Model_Employee::forge();
$new->name = 'Jon';
$new->save();
// option 3, use array for properties
$props = array('name' => 'Jon');
$new = Model_Employee::forge($props);
$new>save();
讀取
ORM 提供了一個 find 方法來從資料庫中獲取資料並繫結到物件中。find 方法的工作方式取決於輸入引數。讓我們看看不同的選項:
按主鍵 − 指定主鍵將根據配置表的匹配主鍵返回記錄。
$employee = Model_Employee::find(1);
第一/最後一條記錄 − 指定“first”或“last”將分別獲取第一條記錄或最後一條記錄。我們也可以傳遞排序選項。
$entry = Model_Employee::find('first');
$entry = Model_Article::find('last', array('order_by' => 'id'));
全部 − 指定“all”將從配置表中獲取所有記錄。我們也可以指定排序選項和條件。
$entry = Model_Employee::find('all');
$entry = Model_Article::find ('all', array (
'where' => array (
array ('name', 'Jon'),
),
'order_by' => array ('id' => 'desc'),
));
我們可以將基本資料庫工具包的 Query API 與模型一起使用,以實現高階搜尋選項,如下所示。
$query = Model_Employee::query()->where('category_id', 1)->order_by('date', 'desc');
$number_of_employees = $query->count();
$latest_employee = $query->max('id');
$young_employee = $query->min('age');
$newest_employee = $query->get_one();
$employees = $query->limit(15)->get();
更新
更新模型與建立模型相同,只是不需要建立新模型,只需使用 find 方法獲取要更新的模型,更新屬性,然後呼叫 save 方法,如下所示。
$entry = Model_Employee:find(4); $entry->name = 'Peter'; $entry->save();
刪除
ORM 提供了一個 delete 方法來刪除模型。只需獲取物件並呼叫 delete 方法即可。
$entry = Model_Employee:find(4); $entry->delete();
工作示例
讓我們在本章中建立一個工作示例來理解模型和資料庫。
建立資料庫
使用以下命令在 MySQL 伺服器中建立一個新資料庫。
create database tutorialspoint_fueldb
然後,使用以下命令在資料庫中建立一個表。
create table employee(id int primary key, name varchar(20), age int not null);
配置資料庫
讓我們使用資料庫配置檔案 *fuel/app/config/db.php* 來配置資料庫。新增以下更改以連線 MySQL 伺服器。
<?php
return array (
'development' => array (
'type' => 'mysqli',
'connection' => array (
'hostname' => 'localhost',
'port' => '3306',
'database' => 'tutorialspoint_fueldb',
'username' => 'root',
'password' => 'pass',
'persistent' => false,
'compress' => false,
),
'identifier' => '`',
'table_prefix' => '',
'charset' => 'utf8',
'enable_cache' => true,
'profiling' => false,
'readonly' => false,
),
'production' => array (
'type' => 'mysqli',
'connection' => array (
'hostname' => 'localhost',
'port' => '3306',
'database' => 'tutorialspoint_fueldb',
'username' => 'root',
'password' => 'pass',
'persistent' => false,
'compress' => false,
),
'identifier' => '`',
'table_prefix' => '',
'charset' => 'utf8',
'enable_cache' => true,
'profiling' => false,
'readonly' => false,
),
);
包含 ORM 包
更新主配置檔案fuel/app/config/config.php,透過新增以下配置來包含 ORM 包。
'always_load' => array (
'packages' => array (
'orm'
),
),
現在,ORM 已在您的應用程式中啟用
建立員工模型
在模型資料夾“fuel/app/classes/model”下建立一個新的模型 Employee。它定義如下。
Employee.php
<?php
class Model_Employee extends Orm\Model {
protected static $_connection = 'production';
protected static $_table_name = 'employee';
protected static $_primary_key = array('id');
protected static $_properties = array (
'id',
'name' => array (
'data_type' => 'varchar',
'label' => 'Employee Name',
'form' => array (
'type' => 'text'
),
),
'age' => array (
'data_type' => 'int',
'label' => 'Employee Age',
'form' => array (
'type' => 'text'
),
),
);
}
建立操作
在位於fuel/app/classes/controller/employee.php的 Employee 控制器中建立一個新的操作action_model,如下所示。
class Controller_Employee extends Controller {
public function action_model() {
// db based sql command to delete all employees
$query = db::query('delete from `employee`');
$query->execute('production');
// orm based query to add new employees
$model = new model_employee();
$model->name = "john";
$model->age = 25;
$model->save();
$model = new model_employee();
$model->name = "peter";
$model->age = 20;
$model->save();
// orm based query to fetch all employee data
$data = array();
$data['emps'] = model_employee::find('all');
return response::forge(view::forge('employee/model', $data));
}
}
建立檢視
現在,建立一個位於“fuel/app/views/employee”的檢視檔案model.php。在檔案中新增以下更改。
<ul>
<?php
foreach($emps as $emp) {
?>
<li><?php echo $emp['name']; ?></li>
<?php
}
?>
</ul>
現在,請求 URL,https://:8080/employee/model,它將產生以下結果。
結果
FuelPHP - 表單程式設計
FuelPHP 提供了三個類,Form、Fieldset 和Input,來執行表單程式設計。
Form 類提供了一個建立所有 HTML 表單元素的選項。
Fieldset 類提供了一個透過更高級別的方法建立 html 元素的選項,集成了模型和驗證。
Input 類提供了一個解析透過 html 表單以及 http 引數、伺服器變數和使用者代理提交的資料的選項。
在本章中,讓我們學習 FuelPHP 中的表單程式設計。
表單
如前所述,Form 類提供了建立 html 表單元素的方法,重要的方法如下:
open()
open() 用於建立一個新表單。它提供以下兩個引數:
$attributes − 表單標籤的屬性,可以是陣列或只是一個 action URL 字串。
$hidden − 隱藏欄位名稱及其值的陣列。
echo Form::open('/employee/add');
echo Form::open(array('action' => '/employee/add', 'method' => 'post'));
close()
close() 只需關閉表單。
echo Form::close();
input()
input() 建立 html 輸入元素。它有以下三個引數:
$field − 輸入元素的名稱
$value − 輸入元素的值
$attributes − 輸入元素的屬性陣列
echo Form::input('name', 'jon', array('style' => 'border: 20px;'));
label 元素
label 建立 html label 元素。它有以下三個引數:
$label − 要顯示的標籤
$id − 關聯的表單元素 ID
$attributes − label 元素的屬性陣列
echo Form::label('Employee Name', 'employee_name');
hidden
hidden 與 input 方法類似,只是它將輸入元素的型別設定為隱藏。
password
password 與 input 方法類似,只是它將輸入元素的型別設定為密碼。
radio
radio 與 input 方法類似,只是它將輸入元素的型別設定為單選按鈕。它有以下四個引數:
$field − 輸入元素的名稱
$value − 輸入元素的值
$checked − 專案是否被選中 (true / false)
$attributes − 輸入元素的屬性陣列
echo Form::label('Male', 'gender');
echo Form::radio('gender', 'Male', true);
echo Form::label('Female', 'gender');
echo Form::radio('gender', 'Female');
checkbox
checkbox 與 input 方法類似,只是它將輸入元素的型別設定為複選框。它有以下四個引數:
$field − 輸入元素的名稱
$value − 輸入元素的值
$checked − 專案是否被選中 (true / false)
$attributes − 輸入元素的屬性陣列
echo Form::label('Male', 'gender');
echo Form::checkbox('gender', 'Male', true);
echo Form::label('Female', 'gender');
echo Form::checkbox('gender', 'Female');
file
file 與 input 方法類似,只是它將輸入元素的型別設定為檔案。
textarea
textarea 建立 html textarea 元素。它有以下三個引數:
$field − textarea 元素的名稱
$value − textarea 元素的值
$attributes − textarea 元素的屬性陣列
echo Form::textarea ('description', 'original data (value)', array ('rows' => 6,
'cols' => 8));
select
select 建立一個 HTML select 元素。它有以下四個引數:
$field − select 元素的名稱
$values − 初始選擇值
$options − 選項陣列。選項可以使用巢狀陣列進行分組
$attributes − 輸入元素的屬性陣列
echo Form::select (
'country',
'none',
array (
'none' => 'None',
'asia' => array (
'in' > 'India',
'cn' => 'China'
),
'us' => 'United States'
)
);
submit
submit 與 input 方法類似,只是它將輸入元素的型別設定為提交。
button
button 建立 html button 元素。它有以下三個引數:
$field − button 元素的名稱
$value − button 元素的值
$attributes − button 元素的屬性陣列
echo Form::button('emp_submit', 'Submit');
reset
reset 與 input 方法類似,只是它將輸入元素的型別設定為重置。
fieldset_open
fieldset_open 建立 html fieldset 和 legend 元素。它有以下兩個引數:
attributes − fieldset 元素的屬性陣列
legend − 要建立的圖例名稱
// returns <fieldset class = "example-class" id = "example-id"> <legend> Custom Legend </legend> echo Form::fieldset_open (array ( 'class' => 'example-class', 'id' => 'exampleid', 'legend' => 'Custom Legend' ));
fieldset_close
fieldset_close 建立 HTML fieldset 關閉標籤。
// returns </fieldset> echo Form::fieldset_close();
Input 類
Input 類提供方法來讀取所有請求資料以及表單詳細資訊。一些重要的方法如下:
uri
uri 返回請求的當前 URI
// request: https://:8080/employee/welcome echo Input::uri(); // return /employee/welcome
method
method 返回請求中使用的 HTTP 方法
echo Input::method() // "POST"
get
get 可用於讀取 $_GET 變數。它有以下兩個引數:
$index − $_GET 陣列的索引
$default − 如果找不到索引,則為預設值。
echo Input::get('age', '20'); // returns $_GET['age']
post
post 可用於讀取 $_POST 變數。它有以下兩個引數:
$index − $_POST 陣列的索引
$default − 如果找不到索引,則為預設值
echo Input::get('age', '20'); // returns $_POST['age']
param
param 可用於從 $_GET、$_POST、$_PUT 或 $_DELETE 變數中獲取專案。它有以下兩個引數:
$index − 陣列的索引
$default − 如果找不到索引,則為預設值
如果沒有指定引數,它將返回所有專案。
echo Input::param('age', '20'); // returns $_POST['age']
file
file 可用於讀取 $_FILE 變數。它有以下兩個引數:
$index − $_POST 陣列的索引
$default − 如果找不到索引,則為預設值
echo Input::file();
is_ajax
is_ajax 如果請求是透過 AJAX 發出的,則返回 true。
echo Input::is_ajax() // return false
protocol
protocol 返回請求中使用的 HTTP 協議。
echo Input::protocol() // returns "HTTP"
ip
ip 返回發出請求的 IP 地址。
echo Input::ip() // returns "84.45.34.24" (Public IP Address)
real_ip
real_ip 嘗試返回發出請求的真實 IP 地址(如果客戶端位於代理後面)。
echo Input::real_ip() // returns "10.76.12.1" (local private IP Address)
server
伺服器端 可讀取 $_SERVER 變數。它具有以下兩個引數:
$index − $_POST 陣列的索引
$default − 如果找不到索引,則為預設值。
echo Input::server('HTTP_HOST'); // returns localhost:8080
referrer
referrer 返回 $_SERVER 變數中的 referrer。這是一個獲取當前請求的 HTTP referrer 的快捷方法。
user_agent
user_agent 返回 $_SERVER 變數中的 user agent。這是一個獲取當前請求的 HTTP user agent 的快捷方法。
query_string
query_string 返回 $_SERVER 變數中的 query string。這是一個獲取當前請求的 query string 的快捷方法。
headers
headers 返回特定或所有 HTTP 頭資訊。它具有以下兩個引數:
$index − HTTP 頭的名稱
$default − 如果找不到索引,則為預設值。
echo Input::headers('Content-Type'); // returns "text/html"
extension
extension 返回當前請求的 URI 副檔名。
// Example URL: https:///test/ echo Input::extension(); // NULL // Example URL: https:///test.html echo Input::extension(); // 'html'
工作示例
讓我們建立一個簡單的表單,使用 Form 和 Input 類來新增新員工。
建立表單
在 employee 控制器中建立一個新的 action,get_add,如下所示。
public function get_add() {
return Response::forge(View::forge('employee/add'));
}
現在,為該 action 新增檢視,fuel/app/views/employee/add.php,如下所示。
<!DOCTYPE html>
<html lang = "en">
<head>
<title>Employee :: add page</title>
<meta charset = "utf-8">
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<?php echo Asset::css('bootstrap.css'); ?>
</head>
<body>
<div class = "container">
<?php
echo Form::open(array('action' => 'employee/add', 'method' => 'post'));
?>
<div class = "form-group">
<?php
echo Form::label('Employee name:', 'name');
echo Form::input('name', '', array('class' => 'form-control'));
?>
</div>
<div class = "form-group">
<?php
echo Form::label('Employee age:', 'age');
echo Form::input('age', '', array('class' => 'form-control'));
?>
</div>
<?php echo Form::button('frmbutton', 'Submit', array(
'class' => 'btn btn-default'));
?>
<?php
echo Form::close();
?>
</div>
</body>
</html>
這裡,我們使用了bootstrap來設計表單。FuelPHP 完全支援 bootstrap 元件。現在,請求頁面 https://:8080/employee/add 將顯示以下表單。
處理表單
建立一個新的 action,post_add,用於處理表單並將使用者輸入的員工資料新增到 employee 控制器中的資料庫中,如下所示。
public function post_add() {
$name = Input::post('name');
$age = Input::post('age');
$model = new model_employee();
$model->name = $name;
$model->age = $age;
$model->save();
Response::redirect('employee/list');
}
在這裡,一旦使用者輸入的資料儲存到資料庫中,我們將被重定向到員工列表頁面。接下來,我們將建立員工列表頁面。
員工列表
建立一個新的 action,action_list,用於列出資料庫中的員工,如下所示。
public function action_list() {
$data = array();
$data['emps'] = model_employee::find('all');
return Response::forge(view::forge('employee/list', $data));
}
為上述 action 建立一個新的檢視,fuel/app/views/employee/list,如下所示。
<ul>
<?php
foreach($emps as $emp) {
?>
<li><?php echo $emp['name']; ?></li>
<?php
}
?>
</ul>
檢查表單
現在,請求 URL,https://:8080/employee/add,輸入一些員工資料(如下面的截圖所示)並提交表單。
然後,它將顯示資料庫中所有員工(包括新新增的員工),如下所示:
FuelPHP - 驗證
驗證是 Web 應用程式中頻繁且最重複的任務之一。使用者在表單中輸入所需資料並提交。然後,Web 應用程式需要在處理資料之前驗證資料。例如,使用者輸入員工資料,post_action 需要在儲存到資料庫之前進行驗證。FuelPHP 為此目的提供了一個非常簡單的類,Validation。
在 FuelPHP 中,驗證的概念非常簡單,它透過 Validation 類提供各種方法來正確驗證表單。以下是驗證的工作流程:
步驟 1 − 使用forge方法建立一個新的 Validation 物件。
$val = Validation::forge();
步驟 2 − 使用 add 方法新增需要驗證的欄位。
$val->add('name', 'Employee name');
步驟 3 − 使用add_rule方法為新增的欄位設定驗證規則。
$val->add('name', 'Employee name')->add_rule('required');
$val->add('age', 'Employee age')->add_rule('required')
->add_rule('numeric_min', 20)
->add_rule('numeric_max', 30);
步驟 4 − 呼叫 run 方法來驗證資料。
// run validation on just post
if ($val->run()) {
// success
} else {
// falier
}
步驟 5 − 使用 validated 和 error 分別獲取有效和無效的欄位。
$vars = $val->validated(); $vars = $val->error();
規則
FuelPHP 包含許多驗證規則,並且還提供建立新規則的選項。Validation 類支援的規則如下:
required − 必須輸入的值
required_with − 設定另一個欄位作為伴隨欄位。如果設定了該欄位,則也需要設定伴隨欄位。
match_value − 設定要與欄位值匹配的值。
match_pattern − 設定要與欄位值匹配的正則表示式。
match_field − 設定另一個欄位的值作為要與欄位值匹配的值。
match_collection − 設定要與欄位值匹配的集合。
min_length − 設定欄位值的最小長度。
max_length − 設定欄位值的最大長度。
exact_length − 設定欄位值的精確長度。
valid_date − 將欄位值設定為有效的日期。
valid_email − 將欄位值設定為有效的電子郵件地址。
valid_emails − 將欄位值設定為有效的電子郵件地址,用逗號分隔。
valid_url − 將欄位值設定為有效的 URL。
valid_ip − 將欄位值設定為有效的 IP 地址。
numeric_min − 設定欄位值的最小值。
numeric_max − 設定欄位值的最大值。
numeric_between − 設定欄位值的最小值和最大值。
valid_string − 與正則表示式類似,但更簡單。
$val->add('username', 'User name')->add_rule('valid_string', array('alpha, dots');
這裡,alpha 指的是字母字元,點指的是 (.)。有效的字串僅包含字母字元和 (.) 的字串。其他選項包括大寫字母、小寫字母、特殊字元、數字、空格等。
工作示例
我們可以更新新增員工功能以包含驗證。只需更新 employee 控制器的post_add方法,如下所示。
public function post_add() {
$val = Validation::forge();
$val->add('name', 'Employee name')->add_rule('required');
$val->add('age', 'Employee age')->add_rule('required')
->add_rule('numeric_min', 20)
->add_rule('numeric_max', 30);
if ($val->run()) {
$name = Input::post('name');
$age = Input::post('age');
$model = new model_employee();
$model->name = $name;
$model->age = $age;
$model->save();
Response::redirect('employee/list');
} else {
Response::redirect('employee/add');
}
}
在這裡,我們指定了name和 age 為必填欄位。age需要在 20 到 30 之間。如果兩個規則都有效,則將儲存員工資料並重定向到員工列表頁面。否則,將拒絕員工資料並重定向到新增員工頁面。
FuelPHP - 高階表單程式設計
FuelPHP 透過 Fieldset 和 Fieldset_Field 類提供高階表單程式設計。Fieldset提供了一種面向物件的方式來建立表單。它完全支援模型。它還內建支援客戶端和伺服器端驗證。要建立一個完整的表單,建立具有適當表單和驗證設定的模型就足夠了。讓我們在本節中學習關於 Fieldset 類的知識以及如何使用它來建立表單。
Fieldset
Fieldset 是Fieldset_Field物件的集合。Fieldset_Field 定義表單的單個條目,例如 firstname、lastname 等,以及驗證。Fieldset 類具有新增/編輯/刪除欄位的方法。它可以選擇識別模型中定義的欄位並從給定的模型建立欄位。Fieldset在後臺使用 Form 和 Validation 類來完成實際工作。讓我們看看 Fieldset 類的一些重要方法。
forge
forge 建立一個新的 Fieldset 例項。它具有以下兩個引數:
$name − fieldset 的識別符號
$config − 配置陣列。可能的選項是validation_instance和form_instance。validation_instance可以具有Validation物件,form_instance可以具有 Form 物件。
$employee_form = Fieldset::forge('employee');
instance
instance 透過識別符號返回先前建立的 Fieldset 例項。
$employee_form = Fieldset::instance('employee');
get_name
獲取 fieldset 例項的識別符號。
$employee_form = Fieldset::forge('employee');
$name = $employee_form->get_name();
add
add 建立一個新的 Fieldset_Field 例項並將其新增到當前 fieldset。它包含以下四個引數:
$name − 欄位的名稱
$label − 欄位的標籤
$attributes − HTML 標籤屬性
$rules − 驗證規則
$employee_field = $employee_form-> add (
'employee_lastname',
'Lastname',
array ('class' => 'pretty_input')
);
// with validation rules
$employee_form->add (
'email', 'E-mail',
array('type' => 'email', 'class' => 'pretty_input'),
array('required', 'valid_email')
);
add_before
add_before 與 add 類似,只是它還有一個額外的引數來指定將在其之前新增新建立欄位的欄位。
$employee_form->add_before (
'employee_firstname',
'Firstname',
array ('class' => 'pretty_input'),
array(),
'employee_lastname'
);
delete
delete 從 fieldset 中刪除指定的欄位。
$employee_form->delete('employee_firstname');
field
field 獲取 fieldset 中的所有欄位或指定的欄位。
$fields = $employee_form->field();
$lastname_field = $employee_form->field('employee_lastname');
build
build 是$this->form()->build()的別名。生成表單的 HTML 標記。
$employee_form->build(Uri::create('employee/add'));
enable
enable 重新啟用先前停用的欄位。
$employee_form->enable('employee_firstname');
disable
disable 允許停用 fieldset 中的欄位不被構建。
$employee_form->disable('employee_firstname');
form
form 返回當前 fieldset 的 Form 例項。
$form = employee_form->form();
add_model
add_model 將模型的欄位新增到 fieldset。它具有以下三個引數:
$class − 類名
$instance − 類的例項,用於填充欄位的值
$method − 類中的方法名稱。此方法用於將欄位新增到 fieldset。Orm\Model 具有所需的方法。預設方法名稱設定為 set_form_fields。
$employee_form = Fieldset::forge('employee');
$employee_form->add_model('Model_Employee');
populate
populate 使用模型例項設定 fieldset 中欄位的初始值。
$emp = new Model_Employee(); $emp->name = "Jon"; $employee_form->populate($emp);
repopulate
repopulate 與 populate 相同,只是它重新填充 fieldset 中的欄位。
validation
validation 獲取當前 fieldset 的驗證例項。
$validation = $employee_form->validation();
validated
$this->validation()->validated() 的別名。
input
$this->validation()->input() 的別名。
error
$this->validation()->error() 的別名。
show_errors
$this->validation()->show_errors() 的別名。
工作示例
讓我們使用 Fieldset 類建立一個高階表單來在我們的示例員工應用程式中新增新員工。
更新模型
使用必要的驗證規則更新員工模型,並新增驗證觀察者,如下所示。
<?php
class Model_Employee extends Orm\Model {
protected static $_connection = 'production';
protected static $_table_name = 'employee';
protected static $_primary_key = array('id');
protected static $_properties = array (
'id',
'name' => array (
'data_type' => 'varchar',
'label' => 'Employee Name',
'validation' => array (
'required',
'min_length' => array(3),
'max_length' => array(80)
),
'form' => array (
'type' => 'text'
),
),
'age' => array (
'data_type' => 'int',
'label' => 'Employee Age',
'validation' => array (
'required',
),
'form' => array ('type' => 'text' ),
),
);
// Just add the Observer, and define the required event
protected static $_observers = array('Orm\\Observer_Validation' => array (
'events' => array('before_save')));
}
在這裡,我們為 name 和 age 欄位定義了驗證規則,並添加了一個新的觀察者,用於在將模型儲存到資料庫之前執行伺服器端驗證。相同的驗證規則還將在表單中建立必要的輸入驗證屬性。
建立表單
在 employee 控制器中建立一個新的 action,action_advancedform,如下所示。
public function action_advancedform() {
// create a new fieldset and add employee model
$fieldset = Fieldset::forge('employee')->add_model('Model_Employee');
// get form from fieldset
$form = $fieldset->form();
// add submit button to the form
$form->add('Submit', '', array('type' => 'submit', 'value' => 'Submit'));
// build the form and set the current page as action
$formHtml = $fieldset->build(Uri::create('employee/advancedform'));
// set form in data
$data = array();
$data['form'] = $formHtml;
return Response::forge(View::forge('employee/advancedform', $data, false));
}
在這裡,我們使用 fieldset 建立了表單,並將表單傳送到檢視。接下來,為 action 新增檢視,fuel/app/views/employee/advancedform.php,如下所示。
<!DOCTYPE html>
<html lang = "en">
<head>
<title>Employee :: add page</title>
<meta charset = "utf-8">
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<?php echo Asset::css('bootstrap.css'); ?>
<style>
table {
width: 90%;
}
table tr {
width: 90%
}
table tr td {
width: 50%
}
input[type = text], select {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
input[type = submit] {
width: 100%;
background-color: #3c3c3c;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
border-radius: 4px;
cursor: pointer;
}
div {
border-radius: 5px;
background-color: #f2f2f2;
padding: 20px;
}
</style>
</head>
<body>
<div class = "container">
<?php
if(isset($errors)) {
echo $errors;
}
echo $form;
?>
</div>
</body>
</html>
現在,請求頁面https://:8080/employee/add將顯示以下表單。
處理表單
更新 action 方法 action_advancedform 以處理表單並將使用者輸入的員工資料新增到 employee 控制器中的資料庫中,如下所示。
public function action_advancedform() {
// create a new fieldset and add employee model
$fieldset = Fieldset::forge('employee')->add_model('Model_Employee');
// get form from fieldset
$form = $fieldset->form();
// add submit button to the form
$form->add('Submit', '', array('type' => 'submit', 'value' => 'Submit'));
// build the form and set the current page as action
$formHtml = $fieldset->build(Uri::create('employee/advancedform'));
if (Input::param() != array()) {
try {
$article = Model_Employee::forge();
$article->name = Input::param('name');
$article->url = Input::param('age');
$article->save();
Response::redirect('employee/list');
}
catch (Orm\ValidationFailed $e) {
$view = View::forge('employee/advancedform');
$view->set('form', $formHtml, false);
$view->set('errors', $e->getMessage(), false);
}
}
return Response::forge($view);
}
在這裡,一旦使用者輸入的資料經過驗證並儲存到資料庫中,我們將被重定向到員工列表頁面。否則,我們將再次看到表單。
建立表單
現在,請求 URL,https://:8080/employee/add,輸入一些員工資料並提交表單。如果未提供資料,則表單將提示使用者輸入資料(如下面的截圖所示)。
如果使用者繞過客戶端驗證,則伺服器將驗證表單並顯示錯誤(如下面的截圖所示)。
如果資料通過了客戶端和伺服器端驗證,則員工資料將儲存到資料庫中,並且頁面將重定向到列表頁面。
FuelPHP - 檔案上傳
檔案上傳是表單程式設計中最常用的功能之一。FuelPHP 提供了一個特殊的類Upload來處理檔案上傳。讓我們在本節中學習如何使用 Upload 類上傳檔案。
配置
可以使用單獨的配置檔案fuel/app/config/upload.php配置 Upload 類。重要的配置項如下:
max_size − 設定要上傳檔案的最大大小。“0”表示無限制的上傳大小
ext_whitelist − 設定允許的副檔名
ext_blacklist − 設定不允許的副檔名
type_whitelist − 設定允許的檔案型別。例如,對於 mime 型別“text/plain”,使用“text”。
type_blacklist − 設定不允許的檔案型別
mime_whitelist − 設定允許的 MIME 檔案型別。例如,“text/plain”
mime_blacklist − 設定不允許的 MIME 檔案型別
prefix − 儲存上傳檔案到伺服器時,在檔名之前新增的字串
suffix − 儲存上傳檔案到伺服器時,在檔名之後新增的字串
extension − 要設定的上傳檔案的副檔名
create_path − 是否建立檔案路徑(如果不存在)
overwrite − 儲存上傳檔案時是否覆蓋現有檔案
auto_rename − 儲存上傳檔案時是否透過新增序列號來重新命名檔案
randomize − 是否建立一個 32 個字元的隨機名稱來儲存上傳檔案
上傳方法
Upload 類提供處理和儲存使用者上傳檔案的選項。每個處理後的檔案(儲存之前)都將在結果陣列中包含以下資訊。
field − 表單欄位的名稱
name − 上傳檔案的名稱
type − 瀏覽器定義的檔案型別
mimetype − Upload 類定義的檔案型別
file − 上傳檔案的臨時位置的完整限定名稱
filename − 上傳檔案的名稱
extension − 上傳檔案的副檔名
size − 上傳檔案的大小(以位元組為單位)
errors − 包含錯誤程式碼和訊息的錯誤陣列
error − 是否設定錯誤陣列以及上傳失敗的原因(如果上傳失敗)
檔案儲存到伺服器後,結果陣列也將包含以下資訊。
saved_to − 上傳檔案儲存的完整限定路徑
saved_as − 儲存的檔名
errors − 更新後的錯誤陣列
現在,讓我們看看 Upload 類的使用方法。
is_valid
如果使用者上傳了任何有效檔案,is_valid 將返回 true。
// do we have any uploaded files to save?
if (Upload::is_valid()) {
// process
}
get_files
get_files 返回所有上傳檔案作為多維陣列。如果指定了表單檔案輸入的索引/名稱,則它只返回與指定檔案輸入相關的上傳檔案。
foreach(Upload::get_files() as $file) {
// do something with the file info
}
if ( Upload::get_files(0)) {
// do something
}
get_errors
如果上傳一個或多個檔案失敗,get_errors 將返回一個錯誤陣列。如果指定了表單檔案輸入名稱的索引/名稱,則它只返回與指定檔案輸入相關的錯誤。
foreach(Upload::get_errors() as $file) {
// do something with the file info
}
if (Upload::get_errors('myimage')) {
// do something
}
Process
process 指的是收集有關上傳檔案資訊的實際過程。我們可以使用陣列提供新的自定義配置。如果沒有指定配置,則它將使用 fuel/app/config/upload.php 中定義的配置。
Upload::process (array( 'auto_rename' => false, 'overwrite' => true ));
save
save 指的是將所有已驗證的檔案儲存到適當位置的實際過程。我們可以指定索引只儲存該特定條目。
Upload::save(); Upload::save(0); Upload::save(0, 3);
工作示例
讓我們在員工示例中建立一個新的控制器 Controller_Upload 來測試上傳功能。
步驟 1 − 建立一個檔案,fuel/app/classes/controller/upload.php。建立上傳控制器。
<?php
class Controller_Upload extends Controller {
}
步驟 2 − 建立一個新的 action get_upload。
<?php
class Controller_Upload extends Controller {
public function get_index() {
return \View::forge("upload/index");
}
}
步驟 3 − 為建立的 action 建立一個新的檢視。
<!DOCTYPE html>
<html>
<body>
<form action = "/upload/index" method = "post" enctype = "multipart/form-data">
Select image to upload:
<input type = "file" name = "fileToUpload" id = "fileToUpload">
<input type = "submit" value = "Upload Image" name = "submit">
</form>
</body>
</html>
步驟 4 − 建立一個新的 action post_action 來處理上傳的檔案。
<?php
class Controller_Upload extends Controller {
public function get_index() {
return \View::forge("upload/index");
}
public function post_index(){
$config = array(
'path' => DOCROOT.'files',
'randomize' => true,
'ext_whitelist' => array('img', 'jpg', 'jpeg', 'gif', 'png'),
);
Upload::process($config);
// if there are any valid files
if (Upload::is_valid()) {
Upload::save();
echo "success";
} else {
// and process any errors
foreach (Upload::get_errors() as $file) {
echo var_dump($file);
}
}
}
}
最後,透過請求 url https://:8080/upload/index 來執行應用程式,並嘗試上傳檔案。
結果
FuelPHP - Ajax
AJAX 是 web 程式設計中的一項現代技術。它提供在網頁中非同步傳送和接收資料的選項,無需重新整理頁面。本章讓我們學習 FuelPHP AJAX 程式設計。
FuelPHP 框架提供識別請求型別是否為 AJAX 的選項。Input 類為此目的提供了一個方法 is_ajax()。如果進行了 AJAX 請求,Input::is_ajax 方法返回 true,否則返回 false。
此方法用於在伺服器端正確處理 AJAX 請求。
if (Input::is_ajax()) {
// Ajax request
} else {
// Normal request
}
我們可以使用 json_encode 返回 JSON 響應。我們可以將這兩種方法結合起來建立一個簡單幹淨的基於 AJAX 的 web 應用程式。
工作示例
讓我們在員工應用程式中新增一個新頁面,ajax/index,並嘗試非同步獲取員工資訊。
步驟 1 − 在 fuel/app/classes/controller/ajax.php 中建立一個新的控制器 Controller_Ajax。
<?php
class Controller_Ajax extends Controller {
}
步驟 2 − 建立一個新的 action,action_index,如下所示。
<?php
class Controller_Ajax extends Controller {
public function action_index() {
$emps = model_employee::find('all');
$data = array();
$i = 0;
foreach($emps as $emp) {
$data[$i] = array();
$data[$i]['name'] = $emp['name'];
$data[$i]['age'] = $emp['age'];
$i = $i + 1;
}
if(\Input::is_ajax()) {
echo json_encode($data);
} else {
return \View::forge("ajax/index");
}
}
}
在這裡,如果請求是 AJAX,我們獲取學生資訊,將其編碼為 JSON 並返回。否則,我們只呈現相應的檢視。
步驟 3 − 建立相應的檢視檔案,fuel/app/views/ajax/index.php,如下所示。
<html>
<head>
<script language = "javascript" src = "/assets/js/jquery-3.2.1.min.js"></script>
<style>
.table { border-collapse: collapse; }
.table th, td {
border-bottom: 1px solid #ddd;
width: 250px;
text-align: left;
align: left;
}
</style>
</head>
<body>
<a id = "loademployee" href = "#">Load employee information</a>
</br>
</br>
<table class = "table">
<tbody id = "employee">
</tbody>
</table>
<script language = "javascript">
$(document).ready(function() {
$("#loademployee").on("click", function(event) {
$.ajax ({
url: '/ajax/index',
type: 'POST',
dataType: 'json',
async: true,
success: function(data, status) {
var e = $('<tr><th>Name</th><th>Age</th></tr>');
$('#employee').html('');
$('#employee').append(e);
for(i = 0; i < data.length; i++) {
employee = data[i];
var e = $('<tr><td id = "name"></td><td id = "age"></td></tr>');
$('#name', e).html(employee['name']);
$('#age', e).html(employee['age']);
$('#employee').append(e);
}
},
error : function(xhr, textStatus, errorThrown) {
alert('Ajax request failed.');
}
});
});
});
</script>
</body>
</html>
在這裡,我們建立了一個錨點標籤 (id: loademployee) 用於使用 AJAX 呼叫載入員工資訊。AJAX 呼叫是使用 JQuery 完成的。當用戶點選時,附加到 loademployee 標籤的事件被啟用。然後,它將使用 AJAX 呼叫獲取員工資訊並動態生成所需的 HTML 程式碼。
步驟 4 − 執行應用程式。
最後,執行應用程式,https://:8000/ajax/index 並點選“載入員工資訊”錨點標籤。
結果
FuelPHP - HMVC 請求
FuelPHP 提供了一個優秀的特性,可以使用 Request 類請求同一個應用程式中的 action。這稱為 HMVC 請求。它能夠重用控制器邏輯。
建立 HMVC 請求
建立 HMVC 請求就像使用所需的 URL 建立一個請求物件並呼叫 execute 方法一樣簡單,如下所示。
$list = Request::forge('employee/list/')->execute();
echo $list;
$employee = Request::forge('employee/show/1')->execute(array('id' => '1'));
echo $employee;
工作示例
讓我們建立一個新的控制器 Controller_HMVC 來測試 HMVC 功能。建立一個檔案,fuel/app/classes/controller/hmvc.php 並放置以下程式碼。
<?php
class Controller_HMVC extends Controller {
public function action_index() {
echo Request::forge('employee/list')->execute();
}
}
在這裡,我們只是透過 HMVC 請求呼叫了 employee/list 頁面並顯示了結果。
結果
FuelPHP - 主題
主題用於為應用程式啟用多種外觀。它為使用者/開發人員提供了更改應用程式外觀的選項,而不會影響應用程式的功能。一個應用程式可以有一個或多個主題。每個主題都位於它自己的資料夾中。本章讓我們學習如何建立主題。
主題配置
FuelPHP 為主題提供了一個單獨的配置檔案,fuel/app/config/themes.php。所有與主題相關的設定都在此檔案中配置。一些主要的主題設定如下:
active − 活動主題的名稱
fallback − 如果找不到活動主題,則為回退主題的名稱
paths − 搜尋和查詢主題的路徑陣列
assets_folder − 通常情況下,資源需要位於 DOCPATH 中,以便可以透過 web 訪問。它指的是 DOCPATH 內主題的資原始檔夾。
view_ext − 主題檢視檔案的副檔名
info_file_name − 包含有關主題的擴充套件資訊的的檔案
require_info_file − 是否需要主題資訊檔案,info_file_name
use_modules − 是否使用當前模組
主題檔案的簡單配置如下。
<?php
return array (
'active' => 'tpthemes',
'fallback' => 'tpthemes',
'paths' => array (
APPPATH.'themes',
),
'assets_folder' => 'assets',
'view_ext' => '.html',
'require_info_file' => false,
'info_file_name' => 'themeinfo.php',
'use_modules' => false,
);
在這裡我們設定了:
- 活動和回退主題的名稱為 tpthemes
- 主題資料夾的路徑為 fuel/app/themes/
- 資原始檔夾的路徑為 /public/assets/tpthemes/
主題類
完成配置後,我們可以使用 FuelPHP 提供的 Theme 類來執行主題的功能。讓我們瞭解本章中 Theme 類中可用的方法。
instance
instance 方法能夠建立一個新的主題。它有兩個引數:
$name − 主題的名稱(可選)
$config − 主題配置陣列(與配置部分中看到的一樣)
這兩個引數都是可選的。如果沒有指定引數,它將嘗試從配置檔案中獲取預設主題。如果指定了主題名稱,它將嘗試從配置檔案中獲取其他設定。如果也指定了配置,則它將使用使用者指定的設定而不是配置檔案中的設定。
$theme = \Theme::instance();
$theme = \Theme::instance('tpthemes');
$theme = \Theme::instance ('mytheme', array (
'active' => 'mytheme', 'view_ext' => '.php'));
forge
forge 與 instance 類似,只是它只有配置陣列。
$theme = \Theme::forge (array( 'active' => 'tpthemes', 'fallback' => 'tpthemes', 'view_ext' => '.php', ));
view
view 方法在後臺使用 View::forge()。這兩個 API 類似,除了 view 方法在 themes 資料夾 fuel/app/themes/tpthemes/ 中搜索檢視檔案,而不是 fuel/app/views/ 資料夾。
$theme = \Theme::instance();
$view = $theme->view('template/index');
// *fuel/app/themes/tpthemes/template/index.php
presenter
presenter 方法在後臺使用 Presenter::forge()。這兩個 API 類似,除了 presenter 方法在 themes 資料夾 fuel/app/themes/tpthemes/ 中搜索檢視檔案,而不是 fuel/app/views/ 資料夾。
$theme = \Theme::instance();
$presenter = $theme->presenter('template/index');
asset_path
asset_path 方法返回相對於當前選擇的主題請求的資源的路徑。
$theme = \Theme::instance();
// public/assets/tpthemes/css/style.css
$style = \Html::css($theme->asset_path('css/style.css'));
add_path
add_path 方法允許在執行時新增主題路徑。
$theme = \Theme::instance(); $theme->add_path(DOCROOT.'newthemes');
add_paths
add_paths 方法允許在執行時新增多個主題路徑。
$theme = \Theme::instance(); $theme->add_path(DOCROOT.'newthemes');
active
active 方法允許設定活動主題。
$theme = \Theme::instance();
$active = $theme->active('newtheme');
fallback
fallback 方法允許設定回退主題。
$theme = \Theme::instance();
$fallback = $theme->fallback('custom');
get_template
get_template 方法將返回當前載入的主題模板的 View 例項。
$theme = \Theme::instance();
$theme->get_template()->set('body', 'Theme can change the look and feel of your app');
set_template
set_template 方法允許設定頁面的主題模板。
$theme = \Theme::instance();
$theme->set_template('layouts/index')->set('body', 'set theme template');
find
如果找到主題的路徑,find 返回 true,否則返回 false。
$theme = \Theme::instance();
$path = $theme->find('newtheme')
all
all 方法返回所有主題路徑中所有主題的陣列。
$theme = \Theme::instance(); $themes = $theme->all();
get_info
get_info 方法返回主題資訊陣列中的特定變數。如果沒有指定主題,則使用活動主題的資訊陣列。
$theme = \Theme::instance();
$var = $theme->get_info('color', 'green', 'newtheme');
在這裡,該方法獲取在“newtheme”中定義的顏色。如果未定義,則將使用“green”作為預設顏色。
set_info
set_info 方法在活動或回退主題中設定變數。
$theme->set_info('color', 'green', 'fallback');
set_partial
set_partial 方法允許為頁面模板的命名部分設定檢視部分。通常,這是透過 HMVC 呼叫完成的。
$theme = \Theme::instance();
$theme->set_template('layouts/homepage');
$theme->set_partial('navbar', 'homepage/navbar');
get_partial
get_partial 方法允許獲取頁面模板命名部分中先前設定的部分的檢視例項。
$theme = \Theme::instance();
$theme->set_partial('sidebar', 'partials/menu');
$theme->get_partial('sidebar', 'partials/menu')->set('class', 'menu green');
工作示例
讓我們在員工應用程式中新增主題支援。
步驟 1 − 使用以下內容新增新的主題配置檔案 fuel/app/config/theme.php。
<?php
return array (
'active' => 'tpthemes',
'fallback' => 'tpthemes',
'paths' => array (APPPATH.'themes', ),
'assets_folder' => 'assets',
'view_ext' => '.html',
'require_info_file' => false,
'info_file_name' => 'themeinfo.php',
'use_modules' => false,
);
步驟 2 − 為主題 tpthemes 新增新的資原始檔夾 public/assets/tpthemes/css。
cd /go/to/app/root/path mkdir -p public/assets/tpthemes/css
步驟 3 − 下載最新的 bootstrap 並將 bootstrap.min.css 放置在 public/assets/tpthemes/css 下
步驟 4 − 在 fuel/app/themes 資料夾下新增新的資料夾 tpthemes。
cd /go/to/app/root/path mkdir -p fuel/app/themes/tpthemes
步驟 5 − 在 fuel/app/themes/tpthemes/layout/ 下新增新的佈局模板 bootstrap.html 並新增以下程式碼。
<!DOCTYPE html>
<html lang = "en">
<head>
<title>Theme example</title>
<meta charset = "utf-8">
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<!-- Bootstrap core CSS -->
<?php echo \Theme::instance()->asset->css('bootstrap.min.css'); ?>
</head>
<body>
<?php echo $header; ?>
<div class = "container">
<div class = "row">
<div class = "col-sm-12">
<?php echo $content; ?>
</div>
</div>
</div>
</body>
</html>
在這裡,我們使用了主題例項和 asset 方法來獲取 bootstrap 檔案的路徑。我們定義了兩個變數 header 和 content。header 用於動態設定標題詳細資訊。content 用於動態設定頁面的實際內容。
步驟 6 − 在 fuel/app/themes/tpthemes/partials 下新增新的標題模板 header.php,如下所示。
<div class = "jumbotron text-center"> <h1>Theme support in fuelphp</h1> <p>bootstrap based template</p> </div>
步驟 7 − 在 fuel/app/classes/controller/themesample.php 中建立一個新的控制器 ThemeSample 以及 action action_index,如下所示。
<?php
class Controller_ThemeSample extends \Controller {
public function before() {
$this->theme = \Theme::instance();
$this->theme->set_template('layouts/bootstrap');
$header = $this->theme->view('partials/header');
$this->theme->get_template()->set('header', $header);
}
public function action_index() {
$content = $this->theme
->view('themesample/index')
->set('message', 'This data comes from action page');
$this->theme
->get_template()
->set('content', $content);
}
public function after($response) {
if (empty($response) or ! $response instanceof Response) {
$response = \Response::forge(\Theme::instance()->render());
}
return parent::after($response);
}
}
在這裡,我們使用了 before 和 after 方法來使用 Theme 類的使用方法初始化主題。使用的一些方法是 instance、get_template、set_template 和 view。
步驟 8 − 最後,為 index action 新增檢視 index.php 在 fuel/app/themes/tpthemes/themesample 中,如下所示。
<p>The data comes from *fuel/app/themes/tpthemes/themesample/index.html* file.</p> <p> <?php echo $message; ?> </p>
在這裡,我們定義了一個變數 message,需要在控制器中動態設定。
我們建立了一個新的主題 tpthemes 並將其用於 ThemeSample 控制器。現在讓我們透過請求 URL https://:8080/themesample/index 來檢查結果。結果如下。
FuelPHP - 模組
模組是編寫可複用 web 功能(例如部落格、相簿、聊天等)的絕佳方式。模組不會干擾 web 應用中的其他程式碼。它位於自己的資料夾中,並默默地提供其功能。模組只是將控制器、模型和檢視分組、配置並放置在特殊資料夾中。通常,模組通常位於應用程式的子目錄中,該子目錄名為 modules,位於 fuel/app/modules。
模組配置
我們可以在主應用程式配置檔案 fuel/app/config/config.php 中定義模組路徑,如下所示。
'module_paths' => array ( path/to.’modules'.DS, // path to application modules path/to.’..’.DS.'globalmods'.DS // path to our global modules ),
模組名稱空間
在 FuelPHP 中,每個模組都有其自己的 PHP 名稱空間。設定單獨的名稱空間可以解決命名衝突。例如,員工模組可以設定在名稱空間 EmployeeModule 下,如下所示。
<?php
namespace Employeemodule;
class Controller_Employee {
//code here
}
模組名稱必須與其資料夾名稱相同。
模組結構
我們可以透過建立在配置中定義的資料夾名稱來建立模組。資料夾名稱決定模組的名稱以及模組中類的名稱空間名稱。
模組的結構如下:
- classes
- controller
- model
- view
- config
- lang
- tasks
- views
模組可以擁有自己的配置檔案。這在路由設定中非常有用,並且不會干擾應用程式的原始配置。另一個重要的概念是,可以透過在 always_load 配置部分載入模組來重用模組類,如下所示。
'always_load => array (
'modules' => array('employeemodule'),
),
此外,可以立即載入和使用模組,無需進行配置,如下所示。
Module::load('employeemodule');
\Employeemodule\Myclass::mymethod('params');
FuelPHP - 包
包在程式碼重用方面與模組類似,但在以下方面有所不同:
- 它不會對映到 web URL。
- 無法透過 HMVC 請求訪問。
簡而言之,包不是直接的 web 功能,例如部落格、相簿等。相反,它是一個函式庫的集合,例如電子郵件處理、文件建立、圖表建立、身份驗證等,有助於更快地開發 web 應用程式。
建立包
要建立包,首先我們需要按照如下所示的方式安排原始碼。
/fuel
/packages
/package (root directory of package)
/bootstrap.php
/classes
/our.php
/classes.php
/here.php
/config
/config.php
/and_so_on
包的結構包含兩個特定於包的檔案:config.php 和 bootstrap.php 檔案。配置檔案的目的是將包的配置分組到包資料夾本身,而不會干擾主應用程式。bootstrap 檔案的目的是設定名稱空間,以便自動載入程式正確載入它。
設定名稱空間的一些方法如下:
Autoloader::add_namespace('Mypackage', __DIR__.'/classes/');
Autoloader::add_core_namespace('Mypackage');
Autoloader::add_core_namespace('Mypackage', true);
Autoloader::add_classes (array(
'Mypackage\\Classname' => __DIR__.'/classes/classname.php',
'Mypackage\\Anotherclass' => __DIR__.'/classes/anotherclass.php',
));
一旦 bootstrap 檔案配置正確並將包載入到應用程式中,我們就可以按如下方式使用它:
$instance = new Myclass; $instance = new Mynamespace\Myclass;
安裝包
包通常放置在 fuel/packages 目錄下。預設情況下,安裝了以下包:
auth − 身份驗證包
email − 電子郵件包
oil − Fuel 的命令,oil 包
orm − ORM 包
parser − Markdown 解析器包
要安裝新包,有以下兩種選擇:
選項 1 − 手動安裝 - 下載並安裝
要手動安裝包,首先從作者的網站下載包。解壓它並將其放在 fuel/packages/ 資料夾下。
選項 2 − 使用 oil 命令的自動方法
FuelPHP 提供了一種自動安裝託管在 github 上的包的方法。使用以下命令安裝包 mytestpackage。
php oil package install mytestpackage
它使用 git 客戶端克隆包原始碼並將其移動到 fuel/packages 資料夾。如果 git 客戶端不可用,則可以使用 –direct 命令引數直接命令下載並安裝包,如下所示。
php oil package install mytestpackage --direct
使用包
一旦將包載入到應用程式中,就可以在應用程式中使用它。將包載入到應用程式中有兩種方法。
選項 1 − 透過 Package 類
FuelPHP 提供了一個類 Package 來載入、解除安裝和檢查包的可用性,分別透過 load、unload 和 loaded 方法。load 方法有兩個引數。第一個引數 $package 是包的名稱,第二個引數 path 是包的路徑。如果包安裝在 fuel/packages 資料夾中,則第二個引數是可選的。
// load the orm package
Package::load('orm');
// load the parser package from a specific directory
Package::load('parser', '/path/to/packages/dir/');
// load the non-existent package
Package::load('awesome'); // Throws a PackageNotFoundException
選項 2 − 透過配置檔案
要永久載入包,只需在主配置檔案 fuel/app/config/config.php 中的 always_load 配置項下新增包即可。要載入 email 包,請使用以下語法。
'always_load' => array (
'packages' => array (
'email',
),
),
一旦將包載入到應用程式中,我們就可以按如下方式使用它:
$instance = new Myclass; $instance = new Mynamespace\Myclass;
FuelPHP - Cookie 和會話管理
Cookie 提供客戶端資料儲存,並且僅支援少量資料。通常,每個域為 2KB,這取決於瀏覽器。Session 提供伺服器端資料儲存,並且支援大量資料。讓我們瞭解如何在 FuelPHP web 應用程式中建立 Cookie 和會話。
Cookie
FuelPHP 提供了一個 Cookie 類來建立 Cookie 專案。Cookie 類用於建立、分配和刪除 Cookie。
配置 Cookie
可以透過位於 fuel/app/config/config.php 的主應用程式配置檔案全域性配置 Cookie 類。定義如下。
'cookie' => array ( //Number of seconds before the cookie expires 'expiration' => 0, //Restrict the path that the cookie is available to 'path' => '/', //Restrict the domain that the cookie is available to 'domain' => null, // Only transmit cookies over secure connections 'secure' => false, // Only transmit cookies over HTTP, disabling Javascript access 'http_only' => false, ),
方法
Cookie 類提供建立、訪問和刪除 Cookie 專案的方法。它們如下:
set()
set 方法用於建立 Cookie 變數。它包含以下引數:
$name − $_COOKIE 陣列中的鍵。
$value − Cookie 的值。
$expiration − Cookie 應持續存在的秒數。
$path − 伺服器上 Cookie 可用的路徑。
$domain − Cookie 可用的域。
$secure − 如果只想透過安全連線傳輸 Cookie,則設定為 true。
$httponly − 僅允許透過 HTTP 傳輸 Cookie,停用 JavaScript 訪問。
Cookie::set('theme', 'green');
get()
get 方法用於讀取 Cookie 變數。它包含以下引數:
$name − $_COOKIE 陣列中的鍵。
$value − 如果鍵在 $_COOKIE 陣列中不可用,則返回的值。
Cookie::get('theme');
delete()
delete 方法用於刪除 Cookie 變數。它包含以下引數:
$name − $_COOKIE 陣列中的鍵。
$value − Cookie 的值。
$domain − Cookie 可用的域。
$secure − 如果只想透過安全連線傳輸 Cookie,則設定為 true。
$httponly − 僅允許透過 HTTP 傳輸 Cookie,停用 JavaScript 訪問。
Cookie::delete('theme');
會話
FuelPHP 提供類 Session 來維護應用程式的狀態。
配置會話
可以透過特殊的配置檔案 fuel/core/config/session.php 配置 Session 類。一些重要的配置項如下:
auto_initialize − 自動初始化會話。
driver − 會話驅動程式的名稱。會話是使用驅動程式實現的,可能的選項包括 cookie、db、memcached、redis 和 file。預設驅動程式是 cookie。
match_ip − 檢查客戶端 IP。
match_ua − 檢查客戶端使用者代理。
expiration_time − 會話超時值(以秒為單位)。
rotation_time − 續期會話的時間。
會話方法
Session 類提供操縱會話資料的方法。它們如下:
instance()
instance 方法返回預設例項或特定例項(由名稱標識)。
$session = Session::instance(); // default instance
$session = Session::instance('myseesion'); // specific instance
set()
set 方法用於分配會話變數。
Session::set('userid', $userid);
get()
get 方法允許您從會話中檢索儲存的變數。
$userid = Session::get('userid');
delete()
delete 方法允許您刪除儲存的會話變數。
Session::delete('userid');
create()
create 方法允許您建立新的會話。如果已經存在會話,則將其銷燬並建立一個新的會話。
Session::create();
destroy()
destroy 方法用於銷燬現有會話。
Session::destroy();
read()
read 方法允許您讀取會話。
Session::read();
write()
write 方法允許您寫入會話。
Session::write();
key()
key 方法允許您檢索會話鍵的元素。鍵的值是唯一的。
$session_id = Session::key('session_id');
FuelPHP - 事件
**事件**是程式識別的動作或事件,程式本身可以處理這些動作或事件。例如,我們可以定義一個名為 my_fuel_event 的動作或事件,然後在呼叫事件 my_fuel_event 時執行一些工作。FuelPHP 提供類 Event 來處理應用程式中的事件。
系統事件
FuelPHP 定義了一些事件,透過這些事件,我們可以隨時執行一些工作,只要應用程式呼叫或觸發定義的事件即可。這有助於更改 FuelPHP 的行為,而無需更改 FuelPHP 的核心程式碼檔案。預定義的事件如下:
app_created − 在 FuelPHP 框架初始化後將觸發此事件。
request_created − 建立新的 Request 物件後將觸發此事件。
request_started − 請求執行時將觸發此事件。
controller_started − 在呼叫控制器的 before() 方法之前將觸發此事件。
controller_finished − 在呼叫控制器的 after() 方法並收到響應後將觸發此事件。
response_created − 建立新的 Response 物件後將觸發此事件。
request_finished − 請求執行完成並收到響應時將觸發此事件。
shutdown − 處理主要請求併發送輸出後將觸發此事件。
我們可以在特殊的配置檔案 fuel/app/config/events.php 中處理事件,如下所示:
<?php
return array (
'fuelphp' => array (
'app_created' => function() {
// After FuelPHP initialised
},
'request_created' => function() {
// After Request forged
},
'request_started' => function() {
// Request is requested
},
'controller_started' => function() {
// Before controllers before() method called
},
'controller_finished' => function() {
// After controllers after() method called
},
'response_created' => function() {
// After Response forged
},
'request_finished' => function() {
// Request is complete and Response received
},
'shutdown' => function() {
// Output has been send out
},
),
);
事件方法
Event 類提供註冊、登出和觸發事件的方法。它們如下:
register()
register 方法允許檔案註冊一個物件,該物件將在呼叫 trigger 方法時執行。
$my_event_code = function() {
echo 'my event';
}
Event::register('my_event', $my_event_code);
unregister()
unregister 方法允許檔案登出在呼叫 trigger 方法時執行的物件。
Event::unregister('my_event', $my_event_code);
trigger()
trigger 方法用於觸發或啟用透過 register 方法關聯的回撥函式。
Event::trigger('my_event');
has_events()
has_events 方法允許您檢查特定註冊事件是否有觸發器。
Event::has_events('my_event');
forge()
forge 方法返回一個新的事件物件。
$event = Event::forge();
instance()
instance 方法返回一個新的事件物件單例。
$event = Event::instance('event_instance');
FuelPHP - 郵件管理
電子郵件功能是 Web 框架中最受需求的功能。FuelPHP 提供了一個優雅的電子郵件類,作為軟體包捆綁在一起。它用於傳送簡單的純文字電子郵件以及帶有多個附件的高階富文字電子郵件。它支援以下功能 - 純文字郵件、HTML 郵件、附件和內聯附件。
配置
要在應用程式中啟用電子郵件功能,我們只需要按照如下所示在主配置檔案 fuel/app/config/config.php 中載入電子郵件軟體包。
'always_load' => array (
'packages' => array (
'email',
),
),
另一種方法是在控制器本身中載入電子郵件軟體包,如下所示。
\Package::load('email');
電子郵件設定可以在主配置檔案中完成,一些重要的選項如下:
driver − 電子郵件驅動程式,例如 smtp
is_html − 是否以 HTML 內容傳送郵件
priority − 電子郵件的優先順序
smtp.host − SMTP 伺服器主機
smtp.port − SMTP 伺服器埠
smtp.username − SMTP 伺服器使用者名稱
smtp.password − SMTP 伺服器密碼
smtp.timeout − SMTP 超時時間
smtp.starttls − SMTP 伺服器是否需要 STARTTLS 命令
電子郵件 API
以下是電子郵件和電子郵件驅動程式類提供的 API。
forge
目的:建立電子郵件驅動程式的例項。它根據收到的配置或輸入建立驅動程式。電子郵件驅動程式提供建立和傳送郵件的功能。一些可能的電子郵件驅動程式是 smtp、sendmail、mailgun 和 mandrill。
引數 − 無或配置詳細資訊陣列
返回值 − 返回 Email_Driver 物件
例如:
$email = \Email::forge(); $email = \Email::forge (array( 'driver' => 'smtp', ));
body
目的 − 設定訊息正文
引數 − $body - 訊息正文
返回 − 返回當前例項
例如:
$email = \Email::forge();
$email->body('Body message');
//or pass it a View
$email->body(\View::forge('my/view', $data);
alt_body
目的 − 設定備用訊息正文
引數 − $alt_body - 備用訊息正文
返回 − 返回當前例項
例如:
$email = \Email::forge();
$email->alt_body('Body message');
//or pass it a View
$email->alt_body(\View::forge('my/view', $data);
priority
目的 − 設定郵件的優先順序
引數 −
$priority − 優先順序的數值。選項為:
a. \Email::P_LOWEST * \Email::P_LOW * \Email::P_NORMAL * \Email::P_HIGH * \Email::P_HIGHEST
返回 − 返回當前例項
例如:
$email = \Email::forge(); $email->priority(\Email::P_HIGHEST);
html_body
目的 − 以 HTML 格式設定訊息正文
引數 −
$html − HTML 格式的訊息正文;
generate_alt − 是否生成替代訊息;
auto_attach − 是否嵌入影像
返回 − 返回當前例項
例如:
$email = \Email::forge();
// Do generate the alt body, but don't auto attach images.
$email->html_body(\View::forge('welcome/email', $data), true, false);
from
目的 − 設定發件人地址
引數 −
$from − 發件人電子郵件地址;
$name − 發件人姓名
返回 − 返回當前例項
例如:
$email = \Email::forge();
$email->from('test@test.com', 'My Name');
subject
目的 − 設定訊息的主題
引數 − $subject - 電子郵件主題
返回 − 返回當前例項
例如:
$email = \Email::forge();
$email->subject('Suject of the mail message');
to
目的 − 設定收件人電子郵件地址
引數 −
$email − 電子郵件地址或電子郵件地址陣列;
$name − 收件人姓名
返回 − 返回當前例項
例如:
$email = \Email::forge();
$email->to('test@test.com', 'My Dear Name');
$email->to (array(
'test@test.com',
'test@test.com' => 'My Dear friend',
));
header
目的 − 為電子郵件訊息設定自定義標頭
引數 −
$header − 標頭型別或標頭陣列;
$value − 標頭的值
返回 − 返回當前例項
例如:
$email = \Email::forge();
$email->header('X-SMTPAP', 'XXXXXXXX');
$email>reply_to (array(
'X-SMTPAP' => 'XXXXXX',
'X-SMTPAP2' > 'XXXXXA',
));
attach
目的 − 將檔案附加到電子郵件訊息
引數−
$file − 檔案路徑;
$inline − 是否內聯附加檔案;
$cid − 內容識別符號;
$mime − 附件檔案的 MIME 型別;
$name − 附件檔名覆蓋
返回 − 返回當前例項
例如:
$email = \Email::forge(); $email>attach(DOCROOT.'attachments/sample_attachment.pdf');
send
目的 − 傳送郵件。
引數 −
$validate − 是否驗證電子郵件地址
返回值 − true 或 false
例如:
$email = \Email::forge();
try{
$email->send();
} catch(\EmailSendingFailedException $e) {
// The driver could not send the mail.
} catch(\EmailValidationFailedException $e) {
// One or more email addresses failed validation.
}
工作電子郵件示例
讓我們使用上一章中學習的 API,建立一個簡單的程式碼來發送訊息。以下是傳送訊息的最簡單程式碼。
$email = Email::forge();
$email->from('someone@gmail.com', 'person1');
$email->to('anotherone@gmail.com', 'person2');
$email->subject('Add something');
$email->body('contents of mail'); $email->send();
FuelPHP - 效能分析器
效能分析器是分析和改進應用程式效能的重要工具之一。FuelPHP 提供了一個優秀的效能分析器來分析應用程式。讓我們在本節中瞭解 FuelPHP 中的效能分析器。
啟用效能分析
預設情況下效能分析是停用的。要啟用效能分析,請在主配置檔案 fuel/app/config/config.php 中將屬性 profiling 設定為 true,如下所示。
'profiling' => true,
現在,應用程式中啟用了效能分析。啟用效能分析後,所有請求的頁面都將在頁面的底部顯示一個額外的選項卡,其中包含效能分析資訊,如下面的螢幕截圖所示。
效能分析器資訊
效能分析器具有選項卡式介面,它包含以下資料:
控制檯 − 提供有關錯誤、日誌條目、記憶體使用情況或執行時間的詳細資訊。
載入時間 − 顯示請求載入時間。
資料庫 − 執行的查詢數量和執行時間。
記憶體 − 請求使用的總記憶體。
檔案 − 顯示所有 PHP 檔案。
配置 − 請求結束時的配置內容。
會話 − 請求結束時的會話內容。
GET − $_GET 陣列的內容。
POST − $_POST 陣列的內容。
效能分析器類
效能分析器類用於新增效能分析資訊。它實現了一個 PHPQuickProfiler (PQP) 的自定義版本。效能分析器包含一系列 JavaScript 變數,用於控制性能分析器的初始狀態。
效能分析器類支援以下方法:
mark()
mark 方法將向性能分析器新增一個速度標記。它顯示載入時間。
Profiler::mark('my custom code');
mark_memory()
mark_memory 方法向性能分析器新增記憶體標記。如果沒有指定輸入,則記錄該時刻的記憶體使用情況。如果我們指定變數和變數的標籤,如下所示,那麼它將顯示變數的記憶體使用情況並使用指定的標籤進行標記。
mark_memory($this, 'My Employee Controller memory usage');
console()
console 方法只會向性能分析器新增日誌條目。
Profiler::console('log entry');
FuelPHP - 錯誤處理和除錯
FuelPHP 為處理錯誤和除錯應用程式提供了出色的支援。讓我們在本節中瞭解錯誤處理和除錯。
錯誤處理
FuelPHP 錯誤處理基於異常。FuelPHP 為所有舊的 php 錯誤提供 PhpErrorException 異常。每當遇到 PHP 程式碼中的錯誤時,FuelPHP 都會引發 PhpErrorException。FuelPHP 還簡化了為各種 HTTP 狀態程式碼顯示自定義錯誤頁面的過程。
檔案未找到錯誤
FuelPHP 提供了一個新的異常類 HttpNotFoundException 來處理未知請求。有時,我們可能會遇到未處理的請求。這時,我們可以直接丟擲 HttpNotFoundException。
預設情況下,在路由配置檔案 fuel/app/config/routes.php 中使用 400 條目為 HttpNotFoundException 配置了預設頁面。每當引發 HttpNotFoundException 時,請求將被重定向到 400 頁面。
'_404_' => 'welcome/404', // The main 404 route
內部錯誤
FuelPHP 提供了一個新的異常類 HttpServerErrorException 來處理所有伺服器錯誤。有時,由於內部錯誤,我們可能無法處理給定的請求。這時,我們可以直接丟擲 HttpServerErrorException。
預設情況下,在路由配置檔案 fuel/app/config/routes.php 中使用 500 條目為 HttpServerErrorException 配置了預設頁面。每當引發 HttpServerErrorException 時,請求將被重定向到 500 頁面。
'_500_' => 'welcome/500', // The main 500 route
此頁面將記錄錯誤,在頁面上顯示格式化的錯誤,並偶爾向系統管理員傳送通知。
訪問衝突錯誤
FuelPHP 提供了一個新的異常類 HttpNoAccessException 來處理訪問衝突。有時,由於訪問限制,我們可能無法處理請求。這時,我們可以直接丟擲 HttpNoAccessException。
預設情況下,在路由配置檔案 fuel/app/config/routes.php 中使用 403 條目為 HttpNoAccessException 配置了預設頁面。每當引發 HttpNoAccessException 時,請求將被重定向到 403 頁面。
'_403_' => 'welcome/403', // The main 403 route
此頁面將顯示訪問衝突資訊。
除錯
除錯是開發應用程式中最常見的活動之一。FuelPHP 提供了一個簡單的類 Debug 來處理應用程式的除錯活動。讓我們在本節中學習 Debug 類及其方法。
Debug 類
Debug 類提供實用程式方法來顯示變數、物件、陣列等的詳細資訊。Debug 類提供以下方法:
dump
dump 方法以格式化的結構化方式將多個混合值返回到瀏覽器。
Debug::dump($var1, $var2);
backtrace()
backtrace 顯示有關程式碼當前執行的詳細資訊。它顯示 PHP 檔案資訊、當前行及其所有之前的操作。
Debug::backtrace();
classes()
返回所有類的列表。
Debug::classes();
interfaces()
返回所有介面類的列表。
Debug::interfaces();
includes()
返回當前在執行時載入的所有包含檔案的列表。
Debug::includes();
functions()
返回所有函式的列表。
Debug::functions();
constants()
返回所有常量的列表。
Debug::constants();
extensions()
返回所有擴充套件的列表。
Debug::extensions();
headers()
返回所有 HTTP 標頭的列表。
Debug::headers();
phpini()
列印從 php.ini 檔案讀取的配置設定列表。
Debug::phpini();
FuelPHP - 單元測試
單元測試是在開發大型專案中必不可少的流程。單元測試有助於在開發的每個階段自動測試應用程式的元件。當應用程式的元件不符合專案的業務規範時,它會發出警報。單元測試可以手動完成,但通常是自動化的。
PHPUnit
FuelPHP 框架與 PHPUnit 測試框架整合。要為 FuelPHP 框架編寫單元測試,我們需要設定 PHPUnit。如果未安裝 PHPUnit,則下載並安裝它。我們可以使用以下命令確認 PHPUnit 在我們的系統中是否可用。
phpunit --version
如果 PHPUnit 可用,您將看到類似於以下的結果。
PHPUnit 5.1.3 by Sebastian Bergmann and contributors.
建立單元測試
FuelPHP 提供的編寫單元測試的標準位置是 fuel/app/tests。我們可以在單獨的資料夾中為控制器、模型、檢視和演示者編寫單元測試。讓我們編寫一個單元測試來驗證 Model_Employee 物件。
步驟 1 − 在 fuel/app/tests 資料夾下建立一個資料夾 model。
步驟 2 − 在 fuel/app/tests/model/ 資料夾下建立一個檔案 employee.php。
步驟 3 − 透過擴充套件 PHPUnit 提供的 TestCase 類,建立一個新的測試類 Test_Model_Employee。
步驟 4 − 編寫一個方法 testInstanceOfEmployee(),使用 PHPUnit 的 TestCase 類提供的 assertInstanceOf() 方法來斷言員工物件的建立。
以下是完整的程式碼:
<?php
class Test_Model_Employee extends TestCase {
public function testInstanceOfEmployee() {
$this->assertInstanceOf(Model_Employee::class, new Model_Employee());
}
}
建立測試組
FuelPHP 提供了建立測試用例組的選項。建立組就像新增文件塊屬性 `@group` 一樣簡單。讓我們將我們的測試用例包含在 MyTest 組中。
<?php
/**
* @group MyTest
*/
class Test_Model_Employee extends TestCase {
public function testInstanceOfEmployee() {
$this->assertInstanceOf(Model_Employee::class, new Model_Employee());
}
}
執行測試
要執行目錄中的所有測試,請使用以下命令。
$ php oil test
要執行特定組的測試,請使用以下命令。
$ php oil test --group = MyTest
執行命令後,您將收到以下響應。
Tests Running...This may take a few moments.
PHPUnit 5.1.3 by Sebastian Bergmann and contributors.
1 / 1 (100%).
Time: 123 ms, Memory: 8.00Mb
OK (1 test, 1 assertion)
FuelPHP - 完整的執行示例
在本節中,我們將學習如何在 FuelPHP 中建立一個完整的基於 MVC 的 BookStore 應用程式。
步驟 1:建立專案
使用以下命令在 FuelPHP 中建立一個名為“BookStore”的新專案。
oil create bookstore
步驟 2:建立佈局
為我們的應用程式建立一個新的佈局。在 fuel/app/views/ 目錄下建立一個檔案 layout.php。程式碼如下:
fuel/app/views/layout.php
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "utf-8">
<meta http-equiv = "X-UA-Compatible" content = "IE = edge">
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<title><?php echo $title; ?></title>
<!-- Bootstrap core CSS -->
<link href = "/assets/css/bootstrap.min.css" rel = "stylesheet">
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
<script src = "/assets/js/bootstrap.min.js"></script>
</head>
<body>
<nav class = "navbar navbar-inverse navbar-fixed-top">
<div class = "container">
<div class = "navbar-header">
<button type = "button" class = "navbar-toggle collapsed"
datatoggle = "collapse" data-target = "#navbar"
aria-expanded = "false" ariacontrols = "navbar">
<span class= "sr-only">Toggle navigation</span>
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
</button>
<a class = "navbar-brand" href = "#">FuelPHP Sample</a>
</div>
<div id = "navbar" class = "collapse navbar-collapse">
<ul class = "nav navbar-nav">
<li class = "active"><a href = "/book/index">Home</a></li>
<li><a href = "/book/add">Add book</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class = "container">
<div class = "starter-template" style = "padding: 50px 0 0 0;">
<?php echo $content; ?>
</div>
</div><!-- /.container -->
</body>
</html>
這裡,我們使用 Bootstrap 模板。FuelPHP 對 Bootstrap 模板具有良好的支援。我們建立了兩個變數,title 和 content。title 用於指定當前頁面的標題,content 用於指定當前頁面的詳細資訊。
步驟 3:建立控制器
建立一個新的控制器 Controller_Book 來顯示、新增、編輯和刪除書籍。建立一個新檔案 fuel/app/classes/controller/book.php 並放置以下程式碼。
fuel/app/classes/controller/book.php
<?php
class Controller_Book extends Controller_Template {
public $template = 'layout';
public function action_index() {
// Create the view object
$view = View::forge('book/index');
// set the template variables
$this->template->title = "Book index page";
$this->template->content = $view;
}
}
這裡,我們透過繼承模板控制器建立了 book 控制器,並將預設模板設定為 fuel/app/views/layout.php。
步驟 4:建立索引檢視
在 fuel/app/views 資料夾下的 views 目錄中建立一個資料夾 book。然後,在 book 資料夾內建立一個檔案 index.php 並新增以下程式碼:
fuel/app/views/index.php
<h3>index page</h3>
目前,我們已經建立了一個基本的 book 控制器。
步驟 5:修改預設路由
更新預設路由,將應用程式的主頁設定為 book 控制器。開啟預設路由配置檔案 fuel/app/config/routes.php 並將其更改如下。
fuel/app/config/routes.php
<?php
return array (
'_root_' => 'book/index', // The default route
'_404_' => 'welcome/404', // The main 404 route
'hello(/:name)?' => array('welcome/hello', 'name' => 'hello'),
);
現在,請求 URL https://:8080/ 將返回 book 控制器的 index 頁面,如下所示:
步驟 6:建立資料庫
使用以下命令在 MySQL 伺服器中建立一個新資料庫:
create database tutorialspoint_bookdb
然後,使用以下命令在資料庫中建立一個表:
CREATE TABLE book ( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(80) NOT NULL, author VARCHAR(80) NOT NULL, price DECIMAL(10, 2) NOT NULL );
使用以下 SQL 語句將一些示例記錄插入表中。
INSERT
INTO
book(title,
author,
price)
VALUES(
'The C Programming Language',
'Dennie Ritchie',
25.00
),(
'The C++ Programming Language',
'Bjarne Stroustrup',
80.00
),(
'C Primer Plus (5th Edition)',
'Stephen Prata',
45.00
),('Modern PHP', 'Josh Lockhart', 10.00),(
'Learning PHP, MySQL & JavaScript, 4th Edition',
'Robin Nixon',
30.00
)
步驟 7:配置資料庫
使用位於 fuel/app/config/ 的資料庫配置檔案 db.php 配置資料庫。
fuel/app/config/db.php
<?php
return array (
'development' => array (
'type' => 'mysqli',
'connection' => array (
'hostname' => 'localhost',
'port' => '3306',
'database' => 'tutorialspoint_bookdb',
'username' => 'root',
'password' => 'password',
'persistent' => false,
'compress' => false,
),
'identifier' => '`',
'table_prefix' => '',
'charset' => 'utf8',
'enable_cache' => true,
'profiling' => false,
'readonly' => false,
),
'production' => array (
'type' => 'mysqli',
'connection' => array (
'hostname' => 'localhost',
'port' => '3306',
'database' => 'tutorialspoint_bookdb',
'username' => 'root',
'password' => 'password',
'persistent' => false,
'compress' => false,
),
'identifier' => '`',
'table_prefix' => '',
'charset' => 'utf8',
'enable_cache' => true,
'profiling' => false,
'readonly' => false,
),
);
步驟 8:包含 ORM 包
更新主配置檔案以包含 ORM 包。它位於“fuel/app/config/”。
fuel/app/config/config.php
'always_load' => array (
'packages' => array (
'orm'
),
),
步驟 9:建立模型
在位於“fuel/app/classes/model”的 book.php 中建立一個 book 模型。其定義如下:
fuel/app/classes/model/book.php
<?php
class Model_Book extends Orm\Model {
protected static $_connection = 'production';
protected static $_table_name = 'book';
protected static $_primary_key = array('id');
protected static $_properties = array (
'id',
'title' => array (
'data_type' => 'varchar',
'label' => 'Book title',
'validation' => array (
'required',
'min_length' => array(3),
'max_length' => array(80)
),
'form' => array (
'type' => 'text'
),
),
'author' => array (
'data_type' => 'varchar',
'label' => 'Book author',
'validation' => array (
'required',
),
'form' => array (
'type' => 'text'
),
),
'price' => array (
'data_type' => 'decimal',
'label' => 'Book price',
'validation' => array (
'required',
),
'form' => array (
'type' => 'text'
),
),
);
protected static $_observers = array('Orm\\Observer_Validation' => array (
'events' => array('before_save')
));
}
這裡,我們將資料庫詳細資訊指定為模型的屬性。它也包含驗證細節。
步驟 10:顯示書籍
更新 book 控制器中的 index 動作以列出資料庫中可用的書籍。
fuel/app/classes/controller/book.php
<?php
class Controller_Book extends Controller_Template {
public $template = 'layout';
public function action_index() {
// Create the view object
$view = View::forge('book/index');
// fetch the book from database and set it to the view
$books = Model_Book::find('all');
$view->set('books', $books);
// set the template variables
$this->template->title = "Book index page";
$this->template->content = $view;
}
}
這裡,我們使用 **ORM** 從資料庫中獲取書籍詳細資訊,然後將書籍詳細資訊傳遞給檢視。
步驟 11:更新索引檢視
更新位於“fuel/app/views/book”的檢視檔案 index.php。完整的更新程式碼如下:
fuel/app/views/book/index.php
<table class = "table">
<thead>
<tr>
<th>#</th>
<th>Title</th>
<th>Author</th>
<th>Price</th>
<th></th>
</tr>
</thead>
<tbody>
<?php
foreach($books as $book) {
?>
<tr>
<td><?php echo $book['id']; ?></td>
<td><?php echo $book['title']; ?></td>
<td><?php echo $book['author']; ?></td>
<td><?php echo $book['price']; ?></td>
<td>
<a href = "/book/edit/<?php echo $book['id']; ?>">Edit</a>
<a href = "/book/delete/<?php echo $book['id']; ?>">Delete</a>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
<ul>
</ul>
現在,請求 URL https://:8080/ 將顯示如下頁面:
步驟 12:建立新增書籍的動作
建立將新書新增到書店的函式。在 book 控制器中建立一個新的動作 action_add,如下所示:
public function action_add() {
// create a new fieldset and add book model
$fieldset = Fieldset::forge('book')->add_model('Model_Book');
// get form from fieldset
$form = $fieldset->form();
// add submit button to the form
$form->add('Submit', '', array('type' => 'submit', 'value' => 'Submit'));
// build the form and set the current page as action
$formHtml = $fieldset->build(Uri::create('book/add'));
$view = View::forge('book/add');
$view->set('form', $formHtml, false);
if (Input::param() != array()) {
try {
$book = Model_Book::forge();
$book->title = Input::param('title');
$book->author = Input::param('author');
$book->price = Input::param('price');
$book->save();
Response::redirect('book');
} catch (Orm\ValidationFailed $e) {
$view->set('errors', $e->getMessage(), false);
}
}
$this->template->title = "Book add page";
$this->template->content = $view; }
這裡執行以下兩個過程:
使用 Fieldset 方法和 Book 模型構建新增書籍的書籍表單。
當用戶輸入書籍資訊並提交表單時,處理書籍表單。可以透過檢查 Input::param() 方法是否存在任何提交的資料來找到它。處理表單包括以下步驟:
收集書籍資訊。
驗證書籍資訊。我們已經在儲存方法之前設定了要呼叫的驗證。如果驗證失敗,它將丟擲 Orm\ValidationFailed 異常。
將書籍資訊儲存到資料庫中。
成功後將使用者重定向到 index 頁面。否則,再次顯示錶單。
我們在同一個動作中同時顯示錶單和處理表單。當用戶第一次呼叫該動作時,它將顯示錶單。當用戶輸入書籍資訊並提交資料時,它將處理表單。
步驟 13:為新增書籍動作建立檢視
為新增書籍動作建立檢視。建立一個新檔案 fuel/app/views/book/add.php 並輸入以下程式碼:
<style>
#form table {
width: 90%;
}
#form table tr {
width: 90%
}
#form table tr td {
width: 50%
}
#form input[type = text], select {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
#form input[type = submit] {
width: 100%;
background-color: #3c3c3c;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
border-radius: 4px;
cursor: pointer;
}
#form div {
border-radius: 5px;
background-color: #f2f2f2;
padding: 20px;
}
</style>
<div id = "form">
<h2>Book form</h2>
<?php
if(isset($errors)) {
echo $errors;
}
echo $form;
?>
</div>
這裡,我們只是顯示在 action 方法中建立的表單。此外,我們還顯示錯誤(如果有)。
步驟 14:檢查新增書籍動作
請求 url https://:8080/book/add 或點選“新增書籍”導航連結,將顯示如下表單:
表單
包含資料的表單
輸入書籍資訊並提交頁面後,書籍資訊將儲存到資料庫中,頁面將重定向到 index 頁面,如下所示。
包含新新增書籍的書籍列表
步驟 15:建立編輯書籍的動作
建立編輯和更新現有書籍資訊的函式。在 book 控制器中建立一個新的動作 action_edit,如下所示。
public function action_edit($id = false) {
if(!($book = Model_Book::find($id))) {
throw new HttpNotFoundException();
}
// create a new fieldset and add book model
$fieldset = Fieldset::forge('book')->add_model('Model_Book');
$fieldset->populate($book);
// get form from fieldset
$form = $fieldset->form();
// add submit button to the form
$form->add('Submit', '', array('type' => 'submit', 'value' => 'Submit'));
// build the form and set the current page as action
$formHtml = $fieldset->build(Uri::create('book/edit/' . $id));
$view = View::forge('book/add');
$view->set('form', $formHtml, false);
if (Input::param() != array()) {
try {
$book->title = Input::param('title');
$book->author = Input::param('author');
$book->price = Input::param('price');
$book->save();
Response::redirect('book');
} catch (Orm\ValidationFailed $e) {
$view->set('errors', $e->getMessage(), false);
}
}
$this->template->title = "Book edit page";
$this->template->content = $view;
}
它與新增動作類似,只是在處理頁面之前按 id 搜尋請求的書籍。如果在資料庫中找到任何書籍資訊,它將繼續並顯示錶單中的書籍資訊。否則,它將丟擲檔案未找到異常並退出。
步驟 16:為編輯動作建立檢視
為編輯書籍動作建立檢視。這裡,我們使用與新增動作相同的檢視。
步驟 17:檢查編輯書籍動作。
點選書籍列表頁面中任何書籍的編輯連結,它將顯示相應的書籍表單,如下所示:
包含書籍詳細資訊的表單
步驟 18:建立刪除書籍的動作
建立從書店刪除書籍的函式。在 book 控制器中建立一個新的動作 action_delete,如下所示:
public function action_delete($id = null) {
if ( ! ($book = Model_Book::find($id))) {
throw new HttpNotFoundException();
} else {
$book->delete();
}
Response::redirect('book');
}
這裡,我們使用提供的書籍 ID 檢查資料庫中是否存在書籍。如果找到書籍,則將其刪除並重定向到 index 頁面。否則,將顯示頁面未找到資訊。
步驟 19:檢查刪除動作
透過點選書籍列表頁面中的刪除連結來檢查刪除動作。它將刪除請求的書籍,然後再次重定向到 index 頁面。
最後,建立了新增、編輯、刪除和列出書籍資訊的所有功能。
與其他基於 MVC 的 PHP 框架相比,FuelPHP 簡單、靈活、可擴充套件且易於配置。它提供現代 MVC 框架的所有功能。它可以按原樣使用,也可以完全更改以適應我們的需求。最重要的是,它是 Web 開發的絕佳選擇。