# Micro Applications
使用Phalcon框架開發者可以創建微框架應用。 這樣開發者只需要書寫極少的代碼即可創建一個PHP應用。 微應用適用于書寫小的應用, API或原型等
~~~
<?php
use Phalcon\Mvc\Micro;
$app = new Micro();
$app->get(
"/say/welcome/{name}",
function ($name) {
echo "<h1>Welcome $name!</h1>";
}
);
$app->handle();
~~~
## 創建微應用(Creating a Micro Application)
Phalcon中 使用[Phalcon\\Mvc\\Micro](http://docs.iphalcon.cn/api/Phalcon_Mvc_Micro.html)來實現微應用。
~~~
<?php
use Phalcon\Mvc\Micro;
$app = new Micro();
~~~
## 定義路由(Defining routes)
實例化后, 開發者需要添加一些路由規則。 Phalcon內部使用[Phalcon\\Mvc\\Router](http://docs.iphalcon.cn/api/Phalcon_Mvc_Router.html)來管理路由。 路由必須以 / 開頭。 定義路由時通常會書寫http方法約束, 這樣路由規則只適用于那些和規則及htttp方法相匹配的路由。 下面的方法展示了如何定義了HTTP get方法路由:
~~~
<?php
$app->get(
"/say/hello/{name}",
function ($name) {
echo "<h1>Hello! $name</h1>";
}
);
~~~
get 方法指定了要匹配的請求方法。 路由規則`/say/hello/{name}`中含有一個參數`{$name}`, 此參數會直接傳遞給路由的處理器(此處為匿名函數)。 路由規則匹配時處理器即會執行。 處理器是PHP中任何可以被調用的項。 下面的示例中展示了如何定義不同種類的處理器:
~~~
<?php
// 函數
function say_hello($name) {
echo "<h1>Hello! $name</h1>";
}
$app->get(
"/say/hello/{name}",
"say_hello"
);
// 靜態方法
$app->get(
"/say/hello/{name}",
"SomeClass::someSayMethod"
);
// 對象內的方法
$myController = new MyController();
$app->get(
"/say/hello/{name}",
[
$myController,
"someAction"
]
);
// 匿名函數
$app->get(
"/say/hello/{name}",
function ($name) {
echo "<h1>Hello! $name</h1>";
}
);
~~~
[Phalcon\\Mvc\\Micro](http://docs.iphalcon.cn/api/Phalcon_Mvc_Micro.html)提供了一系列的用于定義http方法的限定方法:
~~~
<?php
// 匹配HTTP GET 方法:
$app->get(
"/api/products",
"get_products"
);
// 匹配HTTP POST方法
$app->post(
"/api/products/add",
"add_product"
);
// 匹配HTTP PUT 方法
$app->put(
"/api/products/update/{id}",
"update_product"
);
// 匹配HTTP DELETE方法
$app->delete(
"/api/products/remove/{id}",
"delete_product"
);
// 匹配HTTP OPTIONS方法
$app->options(
"/api/products/info/{id}",
"info_product"
);
// 匹配HTTP PATCH方法
$app->patch(
"/api/products/update/{id}",
"info_product"
);
// 匹配HTTP GET 或 POST方法
$app->map(
"/repos/store/refs",
"action_product"
)->via(
[
"GET",
"POST",
]
);
~~~
To access the HTTP method data`$app`needs to be passed into the closure:
~~~
<?php
// Matches if the HTTP method is POST
$app->post(
"/api/products/add",
function () use ($app) {
echo $app->request->getPost("productID");
}
);
~~~
### 路由參數(Routes with Parameters)
如上面的例子中展示的那樣在路由中定義參數是非常容易的。 參數名需要放在花括號內。 參數格式亦可使用正則表達式以確保數據一致性。 例子如下:
~~~
<?php
// 此路由有兩個參數每個參數有一格式
$app->get(
"/posts/{year:[0-9]+}/{title:[a-zA-Z\-]+}",
function ($year, $title) {
echo "<h1>Title: $title</h1>";
echo "<h2>Year: $year</h2>";
}
);
~~~
### 起始路由(Starting Route)
通常情況下, 應用一般由 / 路徑開始訪問, 當然此訪問多為 GET方法。 這種情況代碼如下:
~~~
<?php
// 超始路由
$app->get(
"/",
function () {
echo "<h1>Welcome!</h1>";
}
);
~~~
### 重寫規則(Rewrite Rules)
下面的規則用來實現apache重寫:
~~~
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^((?s).*)$ index.php?_url=/$1 [QSA,L]
</IfModule>
~~~
## 處理響應(Working with Responses)
開發者可以在路由處理器中設置任務種類的響應:直接輸出, 使用模板引擎, 包含視圖, 返回json數據等。
~~~
<?php
// 直接輸出
$app->get(
"/say/hello",
function () {
echo "<h1>Hello! $name</h1>";
}
);
// 包含其它文件
$app->get(
"/show/results",
function () {
require "views/results.php";
}
);
// 返回JSON
$app->get(
"/get/some-json",
function () {
echo json_encode(
[
"some",
"important",
"data",
]
);
}
);
~~~
另外開發者還可以使用[“response”](http://docs.iphalcon.cn/reference/response.html), 這樣開發者可以更好的處理結果:
~~~
<?php
$app->get(
"/show/data",
function () use ($app) {
// 設置返回頭部內容格式
$app->response->setContentType("text/plain");
$app->response->sendHeaders();
// 輸出文件內容
readfile("data.txt");
}
);
~~~
或回復response對象:
~~~
<?php
$app->get(
"/show/data",
function () {
// 創建Response類實例
$response = new Phalcon\Http\Response();
// Set the Content-Type header 設置返回內容的類型
$response->setContentType("text/plain");
// 設置文件內容參數
$response->setContent(file_get_contents("data.txt"));
// 返回response實例對象
return $response;
}
);
~~~
## 重定向(Making redirections)
重定向用來在當前的處理中跳轉到其它的處理流:
~~~
<?php
// 此路由重定向到其它的路由
$app->post("/old/welcome",
function () use ($app) {
$app->response->redirect("new/welcome");
$app->response->sendHeaders();
}
);
$app->post("/new/welcome",
function () use ($app) {
echo "This is the new Welcome";
}
);
~~~
## 根據路由生成 URL(Generating URLs for Routes)
Phalcon中使用[Phalcon\\Mvc\\Url](http://docs.iphalcon.cn/reference/url.html)來生成其它的基于路由的URL。 開發者可以為路由設置名字, 通過這種方式 “url” 服務可以產生相關的路由:
~~~
<?php
// 設置名為 "show-post"的路由
$app->get(
"/blog/{year}/{title}",
function ($year, $title) use ($app) {
// ... Show the post here
}
)->setName("show-post");
// 產生URL
$app->get(
"/",
function () use ($app) {
echo '<a href="', $app->url->get(
[
"for" => "show-post",
"title" => "php-is-a-great-framework",
"year" => 2015
]
), '">Show the post</a>';
}
);
~~~
## 與依賴注入的交互(Interacting with the Dependency Injector)
微應用中,[Phalcon\\Di\\FactoryDefault](http://docs.iphalcon.cn/reference/di.html)是隱含生成的, 不過開發者可以明確的生成此類的實例以用來管理相關的服務:
~~~
<?php
use Phalcon\Mvc\Micro;
use Phalcon\Di\FactoryDefault;
use Phalcon\Config\Adapter\Ini as IniConfig;
$di = new FactoryDefault();
$di->set(
"config",
function () {
return new IniConfig("config.ini");
}
);
$app = new Micro();
$app->setDI($di);
$app->get(
"/",
function () use ($app) {
// Read a setting from the config
echo $app->config->app_name;
}
);
$app->post(
"/contact",
function () use ($app) {
$app->flash->success("Yes!, the contact was made!");
}
);
~~~
服務容器中可以使用數據類的語法來設置或取服務實例:
~~~
<?php
use Phalcon\Mvc\Micro;
use Phalcon\Db\Adapter\Pdo\Mysql as MysqlAdapter;
$app = new Micro();
// 設置數據庫服務實例
$app["db"] = function () {
return new MysqlAdapter(
[
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "test_db"
]
);
};
$app->get(
"/blog",
function () use ($app) {
$news = $app["db"]->query("SELECT * FROM news");
foreach ($news as $new) {
echo $new->title;
}
}
);
~~~
## 處理Not-Found(Not-Found Handler)
當用戶訪問未定義的路由時, 微應用會試著執行 “Not-Found”處理器。 示例如下:
~~~
<?php
$app->notFound(
function () use ($app) {
$app->response->setStatusCode(404, "Not Found");
$app->response->sendHeaders();
echo "This is crazy, but this page was not found!";
}
);
~~~
## 微應用中的模型(Models in Micro Applications)
Phalcon中開發者可以直接使用[Models](http://docs.iphalcon.cn/reference/models.html), 開發者只需要一個類自動加載器來加載模型:
~~~
<?php
$loader = new \Phalcon\Loader();
$loader->registerDirs(
[
__DIR__ . "/models/"
]
)->register();
$app = new \Phalcon\Mvc\Micro();
$app->get(
"/products/find",
function () {
$products = Products::find();
foreach ($products as $product) {
echo $product->name, "<br>";
}
}
);
$app->handle();
~~~
## Inject model instances
By using class[Phalcon\\Mvc\\Model\\Binder](http://docs.iphalcon.cn/api/Phalcon_Mvc_Model_Binder.html)you can inject model instances into your routes:
~~~
<?php
$loader = new \Phalcon\Loader();
$loader->registerDirs(
[
__DIR__ . "/models/"
]
)->register();
$app = new \Phalcon\Mvc\Micro();
$app->setModelBinder(new \Phalcon\Mvc\Model\Binder());
$app->get(
"/products/{product:[0-9]+}",
function (Products $product) {
// do anything with $product object
}
);
$app->handle();
~~~
> Since Binder object is using internally Reflection Api which can be heavy there is ability to set cache. This can be done by using second argument in`setModelBinder()`which can also accept service name or just by passing cache instance to`Binder`constructor.
> Currently the binder will only use the models primary key to perform a`findFirst()`on. An example route for the above would be /products/1
## 微應用中的事件(Micro Application Events)
當有事件發生時[Phalcon\\Mvc\\Micro](http://docs.iphalcon.cn/api/Phalcon_Mvc_Micro.html)會發送事件到[EventsManager](http://docs.iphalcon.cn/reference/events.html)。 這里使用 “micro” 來綁定處理事件。 支持如下事件:
下面的例子中, 我們闡述了如何使用事件來控制應用的安全性:
~~~
<?php
use Phalcon\Mvc\Micro;
use Phalcon\Events\Event;
use Phalcon\Events\Manager as EventsManager;
// 創建事件監聽器
$eventsManager = new EventsManager();
$eventsManager->attach(
"micro:beforeExecuteRoute",
function (Event $event, $app) {
if ($app->session->get("auth") === false) {
$app->flashSession->error("The user isn't authenticated");
$app->response->redirect("/");
$app->response->sendHeaders();
// 返回false來中止操作
return false;
}
}
);
$app = new Micro();
// 綁定事件管理器到應用
$app->setEventsManager($eventsManager);
~~~
## 中間件事件(Middleware events)
此外, 應用事件亦可使用 ‘before’, ‘after’, ‘finish’等來綁定:
~~~
<?php
$app = new Phalcon\Mvc\Micro();
// 每個路由匹配之前執行
// 返回false來中止程序執行
$app->before(
function () use ($app) {
if ($app["session"]->get("auth") === false) {
$app["flashSession"]->error("The user isn't authenticated");
$app["response"]->redirect("/error");
// Return false stops the normal execution
return false;
}
return true;
}
);
$app->map(
"/api/robots",
function () {
return [
"status" => "OK",
];
}
);
$app->after(
function () use ($app) {
// 路由處理器執行后執行
echo json_encode($app->getReturnedValue());
}
);
$app->finish(
function () use ($app) {
// 路由處理器執行后執行
}
);
~~~
開發者可以對同一事件注冊多個處理器:
~~~
<?php
$app->finish(
function () use ($app) {
// 第一個結束處理器
}
);
$app->finish(
function () use ($app) {
// 第二個結束處理器
}
);
~~~
把這些代碼放在另外的文件中以達到重用的目的:
~~~
<?php
use Phalcon\Mvc\Micro\MiddlewareInterface;
/**
* CacheMiddleware
*
* 使用緩存來提升性能
*/
class CacheMiddleware implements MiddlewareInterface
{
public function call($application)
{
$cache = $application["cache"];
$router = $application["router"];
$key = preg_replace("/^[a-zA-Z0-9]/", "", $router->getRewriteUri());
// 檢查請示是否被處理了
if ($cache->exists($key)) {
echo $cache->get($key);
return false;
}
return true;
}
}
~~~
添加實例到應用:
~~~
<?php
$app->before(
new CacheMiddleware()
);
~~~
支持如下的中間件事件:
## 使用控制器處理(Using Controllers as Handlers)
中型的應用可以使用`Mvc\Micro`來組織控制器中的處理器。 開發者也可以使用[Phalcon\\Mvc\\Micro\\Collection](http://docs.iphalcon.cn/api/Phalcon_Mvc_Micro_Collection.html)來對控制器中的處理器進行歸組:
~~~
<?php
use Phalcon\Mvc\Micro\Collection as MicroCollection;
$posts = new MicroCollection();
// 設置主處理器,這里是控制器的實例
$posts->setHandler(
new PostsController()
);
// 對所有路由設置前綴
$posts->setPrefix("/posts");
// 使用PostsController中的index action
$posts->get("/", "index");
// 使用PostController中的show action
$posts->get("/show/{slug}", "show");
$app->mount($posts);
~~~
PostsController形如下:
~~~
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function index()
{
// ...
}
public function show($slug)
{
// ...
}
}
~~~
上面的例子中,我們直接對控制器進行了實例化, 使用集合時Phalcon會提供了遲加載的能力, 這樣程序只有在匹配路由時才加載控制器:
~~~
<?php
$posts->setHandler('PostsController', true);
$posts->setHandler('Blog\Controllers\PostsController', true);
~~~
## 返回響應(Returning Responses)
處理器可能會返回原生的[Phalcon\\Http\\Response](http://docs.iphalcon.cn/reference/response.html)實例或實現了相關接口的組件。 當返回Response對象時, 應用會自動的把處理結果返回到客戶端。
~~~
<?php
use Phalcon\Mvc\Micro;
use Phalcon\Http\Response;
$app = new Micro();
// 返回Response實例
$app->get(
"/welcome/index",
function () {
$response = new Response();
$response->setStatusCode(401, "Unauthorized");
$response->setContent("Access is not authorized");
return $response;
}
);
~~~
## 渲染視圖(Rendering Views)
[Phalcon\\Mvc\\View\\Simple](http://docs.iphalcon.cn/reference/views.html)可用來渲染視圖, 示例如下:
~~~
<?php
$app = new Phalcon\Mvc\Micro();
$app["view"] = function () {
$view = new \Phalcon\Mvc\View\Simple();
$view->setViewsDir("app/views/");
return $view;
};
// 返回渲染過的視圖
$app->get(
"/products/show",
function () use ($app) {
// 渲染視圖時傳遞參數
echo $app["view"]->render(
"products/show",
[
"id" => 100,
"name" => "Artichoke"
]
);
}
);
~~~
Please note that this code block uses[Phalcon\\Mvc\\View\\Simple](http://docs.iphalcon.cn/api/Phalcon_Mvc_View_Simple.html)which uses relative paths instead of controllers and actions. If you would like to use[Phalcon\\Mvc\\View\\Simple](http://docs.iphalcon.cn/api/Phalcon_Mvc_View_Simple.html)instead, you will need to change the parameters of the`render()`method:
~~~
<?php
$app = new Phalcon\Mvc\Micro();
$app["view"] = function () {
$view = new \Phalcon\Mvc\View();
$view->setViewsDir("app/views/");
return $view;
};
// Return a rendered view
$app->get(
"/products/show",
function () use ($app) {
// Render app/views/products/show.phtml passing some variables
echo $app["view"]->render(
"products",
"show",
[
"id" => 100,
"name" => "Artichoke"
]
);
}
);
~~~
## Error Handling
A proper response can be generated if an exception is raised in a micro handler:
~~~
<?php
$app = new Phalcon\Mvc\Micro();
$app->get(
"/",
function () {
throw new \Exception("An error");
}
);
$app->error(
function ($exception) {
echo "An error has occurred";
}
);
~~~
If the handler returns “false” the exception is stopped.
## 相關資源(Related Sources)
* [Creating a Simple REST API](http://docs.iphalcon.cn/reference/tutorial-rest.html)例子中講解了如何使用微應用來創建Restfull服務:
* [Stickers Store](http://store.phalconphp.com/)也是一個簡單的使用微應用的例子 \[[Github](https://github.com/phalcon/store)\].
- 簡介
- 安裝
- 安裝(installlation)
- XAMPP下的安裝
- WAMP下安裝
- Nginx安裝說明
- Apache安裝說明
- Cherokee 安裝說明
- 使用 PHP 內置 web 服務器
- Phalcon 開發工具
- Linux 系統下使用 Phalcon 開發工具
- Mac OS X 系統下使用 Phalcon 開發工具
- Windows 系統下使用 Phalcon 開發工具
- 教程
- 教程 1:讓我們通過例子來學習
- 教程 2:INVO簡介
- 教程 3: 保護INVO
- 教程4: 使用CRUD
- 教程5: 定制INVO
- 教程 6: V?kuró
- 教程 7:創建簡單的 REST API
- 組件
- 依賴注入與服務定位器
- MVC架構
- 使用控制器
- 使用模型
- 模型關系
- 事件與事件管理器
- Behaviors
- 模型元數據
- 事務管理
- 驗證數據完整性
- Workingwith Models
- Phalcon查詢語言
- 緩存對象關系映射
- 對象文檔映射 ODM
- 使用視圖
- 視圖助手
- 資源文件管理
- Volt 模版引擎
- MVC 應用
- 路由
- 調度控制器
- Micro Applications
- 使用命名空間
- 事件管理器
- Request Environmen
- 返回響應
- Cookie 管理
- 生成 URL 和 路徑
- 閃存消息
- 使用 Session 存儲數據
- 過濾與清理
- 上下文編碼
- 驗證Validation
- 表單_Forms
- 讀取配置
- 分頁 Pagination
- 使用緩存提高性能
- 安全
- 加密與解密 Encryption/Decryption
- 訪問控制列表
- 多語言支持
- 類加載器 Class Autoloader
- 日志記錄_Logging
- 注釋解析器 Annotations Parser
- 命令行應用 Command Line Applications
- Images
- 隊列 Queueing
- 數據庫抽象層
- 國際化
- 數據庫遷移
- 調試應用程序
- 單元測試
- 進階技巧與延伸閱讀
- 提高性能:下一步該做什么?
- Dependency Injection Explained
- Understanding How Phalcon Applications Work
- Api
- Abstract class Phalcon\Acl