マイクロアプリケーション ======================== マイクロフレームワークライクなアプリケーションを構築することができます。 PHPアプリケーションを最小のコードで書くことが可能です。 マイクロアプリケーションは、小規模アプリケーションやAPI、プロトタイプを実装するのに適切です。 .. code-block:: php get( "/say/welcome/{name}", function ($name) { echo "

Welcome $name!

"; } ); $app->handle(); マイクロアプリケーションの作成 ------------------------------ :doc:`Phalcon\\Mvc\\Micro <../api/Phalcon_Mvc_Micro>` は、マイクロアプリケーションを実装するためのクラスです。 .. code-block:: php ` は、ルーティングを管理します。 ルートは、常に/から開始しなければいけません。ルートを設定する際に、HTTPメソッドを任意に制限することができます。 指定したHTTPメソッドに一致したリクエストがあった場合にのみ、正しくルーティングされます。 以下の例では、GETメソッドのルーティングの設定方法を表記しています。 .. code-block:: php get( "/say/hello/{name}", function ($name) { echo "

Hello! $name

"; } ); "get"メソッドは、HTTPメソッドのGETであることを指しています。:code:`/say/hello/{name}` というルートは、:code:`{$name}` というパラメータを持っています。 このパラメータは、無名関数で設定されているハンドラーに渡されます。ハンドラーは、ルートが一致した場合のみ実行されます。 以下の例では、何種類かあるハンドラーの設定方法を表記しています。 .. code-block:: php Hello! $name"; } $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 "

Hello! $name

"; } ); :doc:`Phalcon\\Mvc\\Micro <../api/Phalcon_Mvc_Micro>` はHTTPメソッドを指定するためのメソッドを提供しています。 ルートは以下のように制限できます。 .. code-block:: php 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 :code:`$app` needs to be passed into the closure: .. code-block:: php post( "/api/products/add", function () use ($app) { echo $app->request->getPost("productID"); } ); パラメータ付きのルーティング ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ パラメータ付きのルートは、上記の例のように簡単に設定できます。パラメータ名は括弧で括る必要があります。 パラメータのフォーマットは正規表現を使用して設定できます。 .. code-block:: php get( "/posts/{year:[0-9]+}/{title:[a-zA-Z\-]+}", function ($year, $title) { echo "

Title: $title

"; echo "

Year: $year

"; } ); トップルート ^^^^^^^^^^^^^^ 通常、アプリケーションのトップルートは、/となり、ほとんどの場合、GETメソッドにてアクセスされると思います。 .. code-block:: php get( "/", function () { echo "

Welcome!

"; } ); Rewriteルール ^^^^^^^^^^^^^ URisのrewriteは、以下のようにApacheで制限します。 .. code-block:: apacheconf RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^((?s).*)$ index.php?_url=/$1 [QSA,L] レスポンス ---------------------- ハンドラーの中では自由にレスポンスを設定できます。直接出力したり、テンプレートエンジンを使用したり、ビューをインクルードしたり、JSONを返したり、など。 .. code-block:: php get( "/say/hello", function () { echo "

Hello! $name

"; } ); // Requiring another file $app->get( "/show/results", function () { require "views/results.php"; } ); // Returning JSON $app->get( "/get/some-json", function () { echo json_encode( [ "some", "important", "data", ] ); } ); レスポンスについての詳細は、:doc:`"response" ` を参照してください。 .. code-block:: php get( "/show/data", function () use ($app) { // Set the Content-Type header $app->response->setContentType("text/plain"); $app->response->sendHeaders(); // Print a file readfile("data.txt"); } ); レスポンスオブジェクトを作成して、ハンドラーから返す方法もあります。 .. code-block:: php get( "/show/data", function () { // Create a response $response = new Phalcon\Http\Response(); // Set the Content-Type header $response->setContentType("text/plain"); // Pass the content of a file $response->setContent(file_get_contents("data.txt")); // Return the response return $response; } ); リダイレクト ------------------- リダイレクトによって、別のルートへフォワードすることができます。 .. code-block:: php 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生成 -------------------------- :doc:`Phalcon\\Mvc\\Url ` では、設定したルーティングに基づいてURLを作成できます。 これを使用するためには、ルートに名前を定義する必要があります。 .. code-block:: php get( "/blog/{year}/{title}", function ($year, $title) use ($app) { // ... Show the post here } )->setName("show-post"); // Produce a URL somewhere $app->get( "/", function () use ($app) { echo ' "show-post", "title" => "php-is-a-great-framework", "year" => 2015 ] ), '">Show the post'; } ); Interacting with the Dependency Injector ---------------------------------------- In the micro application, a :doc:`Phalcon\\Di\\FactoryDefault ` services container is created implicitly; additionally you can create outside the application a container to manipulate its services: .. code-block:: php 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!"); } ); The array-syntax is allowed to easily set/get services in the internal services container: .. code-block:: php "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"ハンドラーが実行されます。 .. code-block:: php notFound( function () use ($app) { $app->response->setStatusCode(404, "Not Found"); $app->response->sendHeaders(); echo "This is crazy, but this page was not found!"; } ); マイクロアプリケーションにおけるモデル -------------------------------------- マイクロアプリケーションで、:doc:`Models ` が使用することができます。 モデルは自動読み込みで行う必要があります。 .. code-block:: php registerDirs( [ __DIR__ . "/models/" ] )->register(); $app = new \Phalcon\Mvc\Micro(); $app->get( "/products/find", function () { $products = Products::find(); foreach ($products as $product) { echo $product->name, "
"; } } ); $app->handle(); マイクロアプリケーション イベント --------------------------------- :doc:`Phalcon\\Mvc\\Micro <../api/Phalcon_Mvc_Micro>` is able to send events to the :doc:`EventsManager ` (if it is present). Events are triggered using the type "micro". The following events are supported: +---------------------+----------------------------------------------------------------------------------------------------------------------------+----------------------+ | Event Name | Triggered | Can stop operation? | +=====================+============================================================================================================================+======================+ | beforeHandleRoute | The main method is just called, at this point the application doesn't know if there is some matched route | Yes | +---------------------+----------------------------------------------------------------------------------------------------------------------------+----------------------+ | beforeExecuteRoute | A route has been matched and it contains a valid handler, at this point the handler has not been executed | Yes | +---------------------+----------------------------------------------------------------------------------------------------------------------------+----------------------+ | afterExecuteRoute | Triggered after running the handler | No | +---------------------+----------------------------------------------------------------------------------------------------------------------------+----------------------+ | beforeNotFound | Triggered when any of the defined routes match the requested URI | Yes | +---------------------+----------------------------------------------------------------------------------------------------------------------------+----------------------+ | afterHandleRoute | Triggered after completing the whole process in a successful way | Yes | +---------------------+----------------------------------------------------------------------------------------------------------------------------+----------------------+ In the following example, we explain how to control the application security using events: .. code-block:: php 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(); // Return (false) stop the operation return false; } } ); $app = new Micro(); // Bind the events manager to the app $app->setEventsManager($eventsManager); ミドルウェアイベント -------------------- In addition to the events manager, events can be added using the methods 'before', 'after' and 'finish': .. code-block:: php 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) { // This is executed after the route is executed echo json_encode($app->getReturnedValue()); } ); $app->finish( function () use ($app) { // This is executed when the request has been served } ); You can call the methods several times to add more events of the same type: .. code-block:: php finish( function () use ($app) { // First 'finish' middleware } ); $app->finish( function () use ($app) { // Second 'finish' middleware } ); Code for middlewares can be reused using separate classes: .. code-block:: php getRewriteUri()); // Check if the request is cached if ($cache->exists($key)) { echo $cache->get($key); return false; } return true; } } Then add the instance to the application: .. code-block:: php before( new CacheMiddleware() ); 以下のミドルウェアイベントが利用可能です。 +---------------------+----------------------------------------------------------------------------------------------------------------------------+----------------------+ | Event Name | Triggered | Can stop operation? | +=====================+============================================================================================================================+======================+ | before | Before executing the handler. It can be used to control the access to the application | Yes | +---------------------+----------------------------------------------------------------------------------------------------------------------------+----------------------+ | after | Executed after the handler is executed. It can be used to prepare the response | No | +---------------------+----------------------------------------------------------------------------------------------------------------------------+----------------------+ | finish | Executed after sending the response. It can be used to perform clean-up | No | +---------------------+----------------------------------------------------------------------------------------------------------------------------+----------------------+ ハンドラでコントローラの使用 ----------------------------- :code:`Mvc\Micro` を使用した中規模アプリケーションでは、コントローラーを使用する場合があると思います。 :doc:`Phalcon\\Mvc\\Micro\\Collection <../api/Phalcon_Mvc_Micro_Collection>` を使用することによって、コントローラーのグルーピングができます。 .. code-block:: php setHandler( new PostsController() ); // Set a common prefix for all routes $posts->setPrefix("/posts"); // Use the method 'index' in PostsController $posts->get("/", "index"); // Use the method 'show' in PostsController $posts->get("/show/{slug}", "show"); $app->mount($posts); 'PostsController'を以下の例のように記載します。 .. code-block:: php setHandler("PostsController", true); $posts->setHandler("Blog\Controllers\PostsController", true); レスポンスのリターン -------------------- ハンドラーは、:doc:`Phalcon\\Http\\Response ` を使用した生のレスポンスを返したり、または、ビューなどのインターフェイスコンポーネントを返したりすると思います。 ハンドラーによってレスポンスが返されるとき、アプリケーションによって自動的にそれが送信されます。 .. code-block:: php get( "/welcome/index", function () { $response = new Response(); $response->setStatusCode(401, "Unauthorized"); $response->setContent("Access is not authorized"); return $response; } ); ビューのレンダリング -------------------- :doc:`Phalcon\\Mvc\\View\\Simple ` はビューをレンダリングするために使用します。 .. code-block:: php 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" ] ); } ); Please note that this code block uses :doc:`Phalcon\\Mvc\\View\\Simple <../api/Phalcon_Mvc_View_Simple>` which uses relative paths instead of controllers and actions. If you would like to use :doc:`Phalcon\\Mvc\\View\\Simple <../api/Phalcon_Mvc_View_Simple>` instead, you will need to change the parameters of the :code:`render()` method: .. code-block:: php 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: .. code-block:: php 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. 関連ソース --------------- * :doc:`Creating a Simple REST API ` is a tutorial that explains how to create a micro application to implement a RESTful web service. * `Stickers Store `_ is a very simple micro-application making use of the micro-mvc approach [`Github `_].