[TOC]
# 基礎教程
在本教程中,我們將引導您從頭開始創建一個簡單注冊表單的應用程序。以下指南將向您介紹Phalcon框架的設計方面。
本教程介紹了一個簡單的MVC應用程序的實現,展示了使用Phalcon可以快速輕松地完成它。本教程將幫助您入門并幫助創建可擴展的應用程序以滿足許多需求。本教程中的代碼也可以用作學習其他Phalcon特定概念和想法之地。
<div class="alert alert-info">
<p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/75W-emM4wNQ" frameborder="0" allowfullscreen></iframe>
</p>
</div>
如果您只是想開始使用,可以跳過此步驟并使用我們的開發者工具自動創建Phalcon項目。(如果你沒有經驗,如果你遇到困難,可以回到這里)
使用本指南的最佳方式是跟隨并嘗試獲得樂趣。您可以在此處獲取完整的代碼。如果您對某些事情感到不知所措,請訪問我們的[Discord](https://phalcon.link/discord)或我們的[論壇](https://phalcon.link/forum)。
## 文件結構
Phalcon的一個關鍵特性是松散耦合,您可以構建一個Phalcon項目,其目錄結構便于您的特定應用程序。這表示在與其他人合作時,一些統一性是有用的,因此本教程將使用“標準”結構,如果您過去曾與其他MVC合作過,您應該有賓至如歸的感覺。
```text
.
└── tutorial
├── app
│?? ├── controllers
│?? │?? ├── IndexController.php
│?? │?? └── SignupController.php
│?? ├── models
│?? │?? └── Users.php
│?? └── views
└── public
├── css
├── img
├── index.php
└── js
```
>[warning] 注意:您不會看到`vendor`目錄,因為所有Phalcon的核心依賴項都是通過您應該安裝的Phalcon擴展加載到內存中的。如果您錯過了那部分尚未安裝Phalcon擴展請返回并完成安裝,然后繼續。
如果這是全新的,建議您安裝Phalcon Devtools,因為它利用PHP的內置服務器來運行您的應用程序,而無需通過將此[.htrouter](https://github.com/phalcon/phalcon-devtools/blob/master/templates/.htrouter.php) 添加到項目的根目錄來配置Web服務器。
否則,如果你想使用Nginx,請查看`Web服務器設置`章節。
Apache也可以在`Web服務器設置`使用這些附加設置。
最后,如果你的最愛是Cherokee,請查看`Web服務器設置`章節。
## Bootstrap
您需要創建的第一個文件是啟動程序文件。此文件充當應用程序的入口點和配置。在此文件中,您可以實現組件的初始化以及應用程序行為。
這個文件處理3件事:
- 注冊自動加載組件
- 配置服務并使用依賴注入上下文注冊它們
- 解析應用程序的HTTP請求
### 自動加載
自動加載器利用通過Phalcon運行的兼容[PSR-4](http://www.php-fig.org/psr/psr-4/)的文件加載器。應添加到自動裝帶器的常見事項是控制器和模型。您可以注冊將在應用程序命名空間中搜索文件的目錄。如果您想了解其他可以使用自動加載器的方法,請訪問`類加載器`章節。
首先,讓我們注冊我們的應用程序的`controllers`和`models`目錄。不要忘記包括`Phalcon\Loader`的加載器。
`public/index.php`
```php
<?php
use Phalcon\Loader;
// 定義一些絕對路徑常量以幫助定位資源
define('BASE_PATH', dirname(__DIR__));
define('APP_PATH', BASE_PATH . '/app');
// ...
$loader = new Loader();
$loader->registerDirs(
[
APP_PATH . '/controllers/',
APP_PATH . '/models/',
]
);
$loader->register();
```
### 依賴管理
由于Phalcon松耦合,因此服務在框架依賴管理中注冊,因此可以將它們自動注入包含在[IoC](https://en.wikipedia.org/wiki/Inversion_of_control)容器中的組件和服務。通常你會遇到DI這個詞代表依賴注入。依賴注入和控制反轉(IoC)可能聽起來像一個復雜的功能,但在Phalcon中它們的使用非常簡單實用。Phalcon的IoC容器包含以下概念:
- 服務容器:一個“包”,我們在全局存儲我們的應用程序需要運行的服務。
- 服務或組件:將注入組件的數據處理對象
每次框架需要組件或服務時,它都會使用商定的名稱來詢問容器。不要忘記在設置服務容器時包含`Phalcon\Di`.
>[warning] 如果您對詳細信息仍感興趣,請參閱[Martin Fowler](https://martinfowler.com/articles/injection.html)的這篇文章。我們在`依賴注入與服務定位`章節也涵蓋了很多用例。
### 默認工廠
`Phalcon\Di\FactoryDefault`是`Phalcon\Di`的變種。為了簡化操作,它將自動注冊Phalcon附帶的大多數組件。我們建議您手動注冊您的服務,但這已經包含在內,以幫助降低習慣依賴管理時的入門門檻。之后,一旦您對這個概念感到滿意,您就可以隨時指定。
服務可以通過多種方式注冊,但是對于我們的教程,我們將使用[匿名函數](http://php.net/manual/en/functions.anonymous.php):
`public/index.php`
```php
<?php
use Phalcon\Di\FactoryDefault;
// ...
// Create a DI
$di = new FactoryDefault();
```
在下一部分中,我們注冊“view”服務,指示框架將查找視圖文件的目錄。由于視圖與類不對應,因此無法使用自動加載器載入。
`public/index.php`
```php
<?php
use Phalcon\Mvc\View;
// ...
// Setup the view component
$di->set(
'view',
function () {
$view = new View();
$view->setViewsDir(APP_PATH . '/views/');
return $view;
}
);
```
接下來,我們注冊一個基URI,以便Phalcon生成的所有URI都與應用程序的基本路徑“/”匹配。當我們使用`Phalcon\Tag` 類生成超鏈接時,這將在本教程的后面變得很重要。
`public/index.php`
```php
<?php
use Phalcon\Mvc\Url as UrlProvider;
// ...
// Setup a base URI
$di->set(
'url',
function () {
$url = new UrlProvider();
$url->setBaseUri('/');
return $url;
}
);
```
### 處理應用請求
在這個文件的最后一部分,我們找到了`Phalcon\Mvc\Application`。其目的是初始化請求環境,路由傳入的請求,然后分派任何發現的操作;它聚合任何響應并在過程完成時返回它們。
`public/index.php`
```php
<?php
use Phalcon\Mvc\Application;
// ...
$application = new Application($di);
$response = $application->handle();
$response->send();
```
### 合并
`tutorial/public/index.php`文件應如下所示:
`public/index.php`
```php
<?php
use Phalcon\Loader;
use Phalcon\Mvc\View;
use Phalcon\Mvc\Application;
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Url as UrlProvider;
// Define some absolute path constants to aid in locating resources
define('BASE_PATH', dirname(__DIR__));
define('APP_PATH', BASE_PATH . '/app');
// Register an autoloader
$loader = new Loader();
$loader->registerDirs(
[
APP_PATH . '/controllers/',
APP_PATH . '/models/',
]
);
$loader->register();
// Create a DI
$di = new FactoryDefault();
// Setup the view component
$di->set(
'view',
function () {
$view = new View();
$view->setViewsDir(APP_PATH . '/views/');
return $view;
}
);
// Setup a base URI
$di->set(
'url',
function () {
$url = new UrlProvider();
$url->setBaseUri('/');
return $url;
}
);
$application = new Application($di);
try {
// Handle the request
$response = $application->handle();
$response->send();
} catch (\Exception $e) {
echo 'Exception: ', $e->getMessage();
}
```
如您所見,bootstrap文件非常短,我們不需要包含任何其他文件。恭喜您在不到30行代碼中創建靈活的MVC應用程序。
## 創建控制器
默認情況下,Phalcon將查找名為`IndexController`的控制器。它是在請求中未添加任何控制器或操作的起點(例如,`http://localhost:8000/`)。IndexController及其IndexAction應類似于以下示例:
`app/controllers/IndexController.php`
```php
<?php
use Phalcon\Mvc\Controller;
class IndexController extends Controller
{
public function indexAction()
{
echo '<h1>Hello!</h1>';
}
}
```
控制器類必須具有后綴`Controller`,控制器操作必須具有后綴`Action`。如果您從瀏覽器訪問該應用程序,您應該看到如下內容:

恭喜你,你正在使用Phalcon!
## 將輸出發送到視圖
有時需要從控制器向屏幕發送輸出,但不可取,因為MVC社區中的大多數純粹主義者都會證明。必須將所有內容傳遞給負責在屏幕上輸出數據的視圖。Phalcon將查找與名稱為最后執行的控制器的目錄中最后執行的操作同名的視圖。在我們的例子中(`app/views/index/index.phtml`):
`app/views/index/index.phtml`
```php
<?php echo "<h1>Hello!</h1>";
```
我們的控制器(`app/controllers/IndexController.php`)現在有一個空的動作定義:
`app/controllers/IndexController.php`
```php
<?php
use Phalcon\Mvc\Controller;
class IndexController extends Controller
{
public function indexAction()
{
}
}
```
瀏覽器輸出應保持不變。當動作執行結束時,將自動創建`Phalcon\Mvc\View`靜態組件。在`使用視圖`章節詳細了解視圖使用情況。
## 設計注冊表單
現在我們將更改`index.phtml`視圖文件,以添加指向名為“signup”的新控制器的鏈接。目標是允許用戶在我們的應用程序中注冊。
`app/views/index/index.phtml`
```php
<?php
echo "<h1>Hello!</h1>";
echo PHP_EOL;
echo PHP_EOL;
echo $this->tag->linkTo(
'signup',
'Sign Up Here!'
);
```
生成的HTML代碼顯示鏈接到新控制器的錨(`<a>`)HTML標記:
`app/views/index/index.phtml` (渲染)
```html
<h1>Hello!</h1>
<a href="/signup">Sign Up Here!</a>
```
要生成標記,我們使用`Phalcon\Tag`類。這是一個實用程序類,它允許我們構建具有框架約定的HTML標記。由于此類也是在DI中注冊的服務,因此我們使用`$this->tag`來訪問它。
A more detailed article regarding HTML generation [can be found here](/[[language]]/[[version]]/tag).
有關HTML生成的更詳細的文章可以在`視圖助手(標簽)`章節找到。

這是注冊控制器(`app/controllers/SignupController.php`):
`app/controllers/SignupController.php`
```php
<?php
use Phalcon\Mvc\Controller;
class SignupController extends Controller
{
public function indexAction()
{
}
}
```
空索引操作使用表單定義(`app/views/signup/index.phtml`)為視圖提供干凈的傳遞:
`app/views/signup/index.phtml`
```html
<h2>Sign up using this form</h2>
<?php echo $this->tag->form("signup/register"); ?>
<p>
<label for="name">Name</label>
<?php echo $this->tag->textField("name"); ?>
</p>
<p>
<label for="email">E-Mail</label>
<?php echo $this->tag->textField("email"); ?>
</p>
<p>
<?php echo $this->tag->submitButton("Register"); ?>
</p>
</form>
```
在瀏覽器中查看表單將顯示如下內容:

`Phalcon\Tag`還提供了構建表單元素的有用方法。
`Phalcon\Tag::form()`方法僅接收一個參數,例如,應用程序中控制器/操作的相對URI。
通過單擊“Send”按鈕,您將注意到框架中拋出的異常,表明我們在控制器注冊中缺少`register`操作。我們的`public/index.php`文件拋出此異常:
Exception: Action "register" was not found on handler "signup"
實現該方法將除去異常:
`app/controllers/SignupController.php`
```php
<?php
use Phalcon\Mvc\Controller;
class SignupController extends Controller
{
public function indexAction()
{
}
public function registerAction()
{
}
}
```
如果再次單擊“Send”按鈕,您將看到一個空白頁面。用戶提供的名稱和電子郵件輸入應存儲在數據庫中。根據MVC指南,數據庫交互必須通過模型完成,以確保干凈的面向對象的代碼。
## 創建模型
Phalcon為PHP提供了第一個完全用C語言編寫的ORM。它不是增加開發的復雜性,而是簡化了它。
在創建我們的第一個模型之前,我們需要在Phalcon之外創建一個數據庫表來映射它。可以像這樣創建一個存儲注冊用戶的簡單表:
`create_users_table.sql`
```sql
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(70) NOT NULL,
`email` varchar(70) NOT NULL,
PRIMARY KEY (`id`)
);
```
模型應位于`app/models`目錄(`app/models/Users.php`)中。該模型映射到“users”表:
`app/models/Users.php`
```php
<?php
use Phalcon\Mvc\Model;
class Users extends Model
{
public $id;
public $name;
public $email;
}
```
## 設置數據庫連接
為了使用數據庫連接并隨后通過我們的模型訪問數據,我們需要在我們的引導過程中指定它。數據庫連接只是我們的應用程序可以用于多個組件的另一個服務:
`public/index.php`
```php
<?php
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
// Setup the database service
$di->set(
'db',
function () {
return new DbAdapter(
[
'host' => '127.0.0.1',
'username' => 'root',
'password' => 'secret',
'dbname' => 'tutorial1',
]
);
}
);
```
使用正確的數據庫參數,我們的模型可以工作并與應用程序的其余部分進行交互。
## 使用模型存儲數據
`app/controllers/SignupController.php`
```php
<?php
use Phalcon\Mvc\Controller;
class SignupController extends Controller
{
public function indexAction()
{
}
public function registerAction()
{
$user = new Users();
// Store and check for errors
$success = $user->save(
$this->request->getPost(),
[
"name",
"email",
]
);
if ($success) {
echo "Thanks for registering!";
} else {
echo "Sorry, the following problems were generated: ";
$messages = $user->getMessages();
foreach ($messages as $message) {
echo $message->getMessage(), "<br/>";
}
}
$this->view->disable();
}
}
```
在`registerAction`的開頭,我們從Users類創建一個空的用戶對象,該類管理用戶的記錄。該類的公共屬性映射到數據庫中`users`表的字段。在新記錄中設置相關值并調用`save()`會將數據存儲在該記錄的數據庫中。`save()`方法返回一個布爾值,指示數據的存儲是否成功。
ORM自動轉義阻止SQL注入的輸入,因此我們只需要將請求傳遞給`save()`方法。
在定義為非null(必需)的字段上自動進行附加驗證。如果我們沒有在注冊表單中輸入任何必填字段,我們的屏幕將如下所示:

## Conclusion
如您所見,使用Phalcon開始構建應用程序很容易。Phalcon從擴展中運行的事實大大減少了項目的占地面積,并使其具有相當大的性能提升。
如果您準備了解更多信息,請查看`教程:創建一個簡單的REST API`章節。
- 常規
- Welcome
- 貢獻
- 生成回溯
- 測試重現
- 單元測試
- 入門
- 安裝
- Web服務器設置
- WAMP
- XAMPP
- 教程
- 基礎教程
- 教程:創建一個簡單的REST API
- 教程:V?kuró
- 提升性能
- 教程:INVO
- 開發環境
- Phalcon Compose (Docker)
- Nanobox
- Phalcon Box (Vagrant)
- 開發工具
- Phalcon開發者工具的安裝
- Phalcon開發者工具的使用
- 調試應用程序
- 核心
- MVC應用
- 微應用
- 創建命令行(CLI)應用程序
- 依賴注入與服務定位
- MVC架構
- 服務
- 使用緩存提高性能
- 讀取配置
- 上下文轉義
- 類加載器
- 使用命名空間
- 日志
- 隊列
- 數據庫
- 數據庫抽象層
- Phalcon查詢語言(PHQL)
- ODM(對象文檔映射器)
- 使用模型
- 模型行為
- ORM緩存
- 模型事件
- 模型元數據
- 模型關系
- 模型事務
- 驗證模型
- 數據庫遷移
- 分頁
- 前端
- Assets管理
- 閃存消息
- 表單
- 圖像
- 視圖助手(標簽)
- 使用視圖
- Volt:模板引擎
- 業務邏輯
- 訪問控制列表(ACL)
- 注解解析器
- 控制器
- 調度控制器
- 事件管理器
- 過濾與清理
- 路由
- 在session中存儲數據
- 生成URL和路徑
- 驗證
- HTTP
- Cookies管理
- 請求環境
- 返回響應
- 安全
- 加密/解密
- 安全
- 國際化
- 國際化
- 多語言支持