1.06.29 aura_Aura.Web:Aura的MVC页面控制器

1.06.29 aura

MVC is an acronym that means Model-View-Controller. In this tutorial I would like to introduce you to Aura.Web, the controller component of the Aura Library. Here I’ll show you how to use it to build your own controller, and also how to use a response transfer object to issue HTTP response headers, and integrate a templating engine like Mustache for rendering views.

MVC是首字母缩写,表示Model-View-Controller。 在本教程中,我想向您介绍Aura库的控制器组件Aura.Web。 在这里,我将向您展示如何使用它来构建自己的控制器,以及如何使用响应传输对象来发出HTTP响应标头,以及如何集成诸如Mustache之类的模板引擎来呈现视图。

建筑 (Architecture)

The controller is the entry point for a page, and communicates with view and model components. Aura.Web helps us to easily build controllers that follow the Page Controller design pattern.

控制器是页面的入口点,并与视图和模型组件进行通信。 Aura.Web帮助我们轻松构建遵循页面控制器设计模式的控制器。

Each page of an application is usually unique, and Aura.Web provides the AuraWebControllerAbstractPage class that provides the basic functionality that we can extend and use. But in order to create an object that extends the AbstractPage class, we need to provide some dependencies, usually through the constructor. The dependencies are:

应用程序的每个页面通常都是唯一的,并且Aura.Web提供了AuraWebControllerAbstractPage类,该类提供了我们可以扩展和使用的基本功能。 但是,为了创建扩展AbstractPage类的对象,我们通常需要通过构造函数来提供一些依赖关系。 依赖项是:

  1. An instance of an AuraWebContext class that represents the environment.

    代表环境的AuraWebContext类的实例。

  2. An instance of an AuraWebAccept class which helps retrieve Accept headers.

    AuraWebAccept类的实例,可帮助检索Accept标头。

  3. An instance of an AuraWebResponse which creates a response transfer object.

    创建响应传递对象的AuraWebResponse的实例。

  4. An implementation of the AuraWebSignalInterface which is a signal manager to execute hooks (similar to an observer/event handler).

    AuraWebSignalInterface的实现,它是一个执行挂钩的信号管理器(类似于观察器/事件处理程序)。

  5. An implementation of the AuraWebRendererRendererInterface to incorporate our rendering system.

    AuraWebRendererRendererInterface的实现,以合并我们的渲染系统。

  6. A parameter array in which we can pass the action methods.

    我们可以在其中传递操作方法的参数数组。

The Context class accepts an array of global values, which in most cases will be $GLOBALS. From inside the controller we can use the Context object as $this->context, and can access $_GET, $_POST, $_FILES, raw php://input, and JSON decoded values using the object’s methods getQuery(), getPost(), getFiles(), getInput(), and getJsonInput() respectively. We can also check whether the request was made using GET via isGet(), PUT via isPut(), or an Ajax call via isXhr().

Context类接受一系列全局值,在大多数情况下为$GLOBALS 。 在控制器内部,我们可以将Context对象用作$this->context ,并可以使用对象的方法getQuery()getPost() getQuery()访问$_GET$_POST$_FILES ,raw php://input和JSON解码值。 getPost()getFiles()getInput()getJsonInput() 。 我们还可以检查请求是使用isGet() GET还是通过isGet() PUT还是通过isPut()的Ajax调用isXhr()

Let’s assume a request to http://localhost/?name=Hello is made. An example to get the value of the name parameter from within our controller is:

假设发出了对http:// localhost /?name = Hello的请求。 从我们的控制器中获取name参数值的示例是:

<?php
$this->context->getQuery('name', 'default value');

The second parameter to getQuery() is optional; it specifies a default value to be returned if the actual value is empty.

getQuery()的第二个参数是可选的; 如果实际值为空,它指定要返回的默认值。

The Accept class accepts an array of $_SERVER information. The reason why it’s not just hardcoded in the constructor is to give us the flexibility to pass whatever we like for testing and such. The object is also available in our controller using $this->accept. It’s methods give us the accepted media type as an array via getContentType(), the character set via getCharset(), encoding via getEncoding(), and language via getLanguage(). A basic example from the action would be:

Accept类接受$_SERVER信息数组。 之所以不仅仅在构造函数中对其进行硬编码,是为了使我们能够灵活地传递我们想要进行的测试等。 该对象也可以在我们的控制器中使用$this->accept 。 它的方法通过getContentType()为我们提供了可接受的媒体类型,通过getCharset()设置了字符集,通过getEncoding()编码,并通过getLanguage()语言getLanguage() 。 该操作的一个基本示例是:

<?php
$this->accept->getContentType();

Note that an array of key/values is returned, similar to:

请注意,返回的键/值数组类似于:

Array
(
    [text/html] => 1
    [application/xhtml+xml] => 1
    [application/xml] => 0.9
    [*/*] => 0.8
)

You may be familiar with using PHP’s header() function to add values to the HTTP response that is sent back to the client. Instead, a Response object is used as a web response transfer object. The object holds the values which we can pass along, and later convert to a proper HTTP response using tools like Aura.Http.

您可能熟悉使用PHP的header()函数向发送回客户端的HTTP响应中添加值。 而是将Response对象用作Web响应传输对象。 该对象保存我们可以传递的值,然后使用诸如Aura.Http之类的工具将其转换为正确的HTTP响应。

The Response object is also made available in the controller via $this->getResponse(). The object lets us set the response’s body content via setContent(), HTTP header values via setHeader(), cookies via setCookie(), and a redirect header via setRedirect(). We can also set the HTTP status code via setStatusCode() and the status text via the setStatusText() methods.

还可以通过$this->getResponse()在控制器中使用Response对象。 对象让我们通过设置响应的主体内容setContent()通过HTTP标头值setHeader()通过cookie setCookie()并且经由重定向头setRedirect() 我们还可以通过setStatusCode()设置HTTP状态代码,并通过setStatusText()方法设置状态文本。

Here’s what extending and using an AbstractPage object looks like:

这是扩展和使用AbstractPage对象的样子:

<?php
namespace SitePointTutorialWebController;
use AuraWebControllerAbstractPage;

class Index extends AbstractPage
{
    public function actionGreet() {
        $this->response->setContent(
            '<html>' . 
            '<head><title>Aura web controller</title></head>' .
            '<body>Hello World!</body>' . 
            '</html>'
        );
    }
}
<?php
use AuraWebContext;
use AuraWebAccept;
use AuraWebResponse;
use AuraWebSignal;
use AuraWebRendererNone as Renderer;
use SitePointTutorialWebControllerIndex;

$page = new Index(
    new Context($GLOBALS),
    new Accept($_SERVER),
    new Response(),
    new Signal(),
    new Renderer(),
    [
        'action' => 'greet',
    ]
);
$response = $page->exec();
echo $response->getContent();

The array of parameters passed as the last argument to our extended AbstractPage specifies which actions need to be called, which format needs to be passed to the rendering strategy, and any other parameters for the action method.

作为最后一个参数传递给扩展的AbstractPage的参数数组指定了需要调用的动作,需要将哪种格式传递给呈现策略以及action方法的任何其他参数。

In the execution cycle initiated by exec(), the following are invoked:

在由exec()启动的执行周期中,将调用以下命令:

  1. pre_exec, a hook which calls the page’s preExec() method.

    pre_exec ,一个钩子,调用页面的preExec()方法。

  2. pre_action, a hook calling the preAction() method.

    pre_action ,一个调用preAction()方法的钩子。

  3. action() to find and invoke the action method (it actually creates a Reflection class to retrieve the parameters for the method and then calls it).

    action()查找并调用action方法(它实际上创建了Reflection类,以检索该方法的参数,然后对其进行调用)。

  4. post_action, a hook calling the postAction() method.

    post_action ,一个调用postAction()方法的钩子。

  5. pre_render, a hook which calls the preRender() method.

    pre_render ,一个调用preRender()方法的钩子。

  6. render() to render the view.

    render()渲染视图。

  7. post_render, a hook calling the postRender() method.

    post_render ,一个调用postRender()方法的钩子。

  8. post_exec, a hook which calls the postExec() method.

    post_exec ,一个调用postExec()方法的钩子。

渲染图 (Rendering)

In the example above we explicitly set the content in the controller, but this is not really the best way to organize our code. The view should be separated. Aura.Web doesn’t provide a rendering strategy by default, so it’s easy to integrate any rendering strategy we like. Here I’ll use Mustache.

在上面的示例中,我们在控制器中显式设置了内容,但这并不是组织代码的最佳方法。 视图应分开。 Aura.Web默认情况下不提供渲染策略,因此可以轻松集成我们喜欢的任何渲染策略。 在这里,我将使用小胡子。

To create a rendering strategy, we need to extend the AuraWebRendererAbstractRenderer class, in which we define the exec() method. The controller is available to us in the rendering strategy via $this->controller.

要创建渲染策略,我们需要扩展AuraWebRendererAbstractRenderer类,在其中定义exec()方法。 可以通过$this->controller在渲染策略中使用该$this->controller

<?php
namespace SitePointFrameworkWebRenderer;
use AuraWebRendererAbstractRenderer;

class Mustache extends AbstractRenderer
{
    protected $mustache;

    public function __construct($mustache) {
        $this->mustache = $mustache;
    }

    public function exec() {
        $format = $this->controller->getFormat();
        if (! $format) {
            $format = '.html';
        }
        $response = $this->controller->getResponse();
        if (!$response->getContent()) {
            $data    = (array)$this->controller->getData();
            $view    = strtolower($this->controller->getAction());
            $lastval = basename(
                str_replace('\', '/', strtolower(
                    get_class($this->controller)
                ))
            );
            $file =  $lastval . '/' . $view . $format;
            $response->setContent(
                $this->mustache->render($file, $data)
            );
        }
        $response->setContentType($this->getContentType($format));
    }

    public function getContentType($format) {
        $mimetypes = [
            '.json' => 'application/json',
            '.xml'  => 'application/xml',
            '.html' => 'text/html',
            '.htm'  => 'text/html'
        ];
        return array_search($format, $mimetypes);
    }
}

I’ve made the assumption that we’re keeping all of the Mustache templates saved using the convention <controller name>/<action name>.<format>, where the folders mirror <controller name> and <action name>.<format> is the template’s filename. For example, a controller class Example with the action hello would find it’s template in example/hello.<format>.

我假设我们将保留所有使用约定<controller name> / <action name> . <format>的Mustache模板<controller name> / <action name> . <format> <controller name> / <action name> . <format> ,其中文件夹镜像<controller name><action name> . <format> <action name> . <format>是模板的文件名。 例如,带有动作hello的控制器类Example将在example/hello. <format>找到它的模板example/hello. <format> example/hello. <format>

建立HTTP回应 (Building HTTP Responses)

We still haven’t built a proper HTTP response, so let’s see how we can do that now. Once we call the execution cycle of the controller with it’s exec() method we will get back a response transfer object.

我们仍未建立适当的HTTP响应,因此让我们看看现在如何做到这一点。 一旦我们使用exec()方法调用控制器的执行周期,我们将获得一个响应传递对象。

The object contains the HTTP status code, status text, cookies, and header values. We can build the HTTP response from it with code similar to that given below:

该对象包含HTTP状态代码,状态文本,cookie和标头值。 我们可以使用类似于以下代码的代码构建HTTP响应:

<?php
$response = $page->exec();

// header('Status: 200 OK');
$statusCode = $response->getStatusCode();
$statusText = $response->getStatusText();

$response->getVersion();
$headers = $response->getHeaders();
foreach ($headers as $header => $value) {
    // header('Content-Type: text/html; charset=utf-8');
    header($header . ': ' . $value);
}

$cookies = $response->getCookies();
foreach ($cookies as $name => $cookie) {
    setcookie(
        $name,
        $cookie['value'],
        $cookie['expire'],
        $cookie['path'],
        $cookie['domain'],
        $cookie['secure'],
        $cookie['httponly']
    );
}

$contentType = $response->getContentType();
if (!$contentType) {
    $contentType = 'text/html; charset=utf-8';
}
header('Content-Type: ' . $contentType);
echo $response->getContent();

I’ve demonstrated only a pure PHP implementation so it’s easy for everyone to understand, but ideally we would use something like Aura.Http or another library which provides the necessary functionality for us.

我仅演示了一个纯PHP实现,因此每个人都易于理解,但是理想情况下,我们将使用Aura.Http之类的东西或另一个为我们提供必要功能的库。

结论 (Conclusion)

In this article I’ve covered the basic working principles of Aura.Web, and also showed how we can integrate a rendering strategy and how to build proper HTTP responses. You can use the power of a routing library like Aura.Router which I discussed earlier to dynamically call the controller. Maybe in a future article I’ll show how to integrate all of this and build your own framework from Aura components. Stay tuned!

在本文中,我介绍了Aura.Web的基本工作原理,还展示了如何集成渲染策略以及如何构建正确的HTTP响应。 您可以使用我之前讨论的路由库(如Aura.Router)的功能来动态调用控制器。 也许在以后的文章中,我将展示如何集成所有这些内容并从Aura组件构建您自己的框架。 敬请关注!

Image via Fotolia

图片来自Fotolia

翻译自: https://www.sitepoint.com/aura-web-auras-page-controller-for-mvc/

1.06.29 aura

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值