rawebone/razor-library

提供核心Razor处理

dev-master 2014-08-25 20:41 UTC

This package is not auto-updated.

Last update: 2024-09-24 02:23:55 UTC


README

Razor是一个基于REST概念的轻量级微框架。它类似于许多项目,如SlimSilex,但设计得更加易于使用,这是基于个人偏好的。

如上所述,该框架专注于RESTful Web应用程序。假设我们正在开发必做的TODO应用程序,我们将在API中有一个表示TODO项目集合的端点,或者更准确地说,是资源

在Razor中建模,我们将在面向Web的文件夹中创建一个名为todos.php的文件,其中包含以下代码

<?php

// File: todos.php

require_once "/path/to/vendor/autoload.php";

use Razor\EndPoint;

(new EndPoint())

    ->run();

我们可以把这个文件看作是我们的资源集合;即如果我们想要添加、编辑、获取或删除TODO项,那么这些更改将通过这个文件来实现。Razor针对这种思维方式,因此所有与资源相关的逻辑都被封装在EndPoint对象中。为了能够对资源执行操作,我们必须将代表HTTP请求方法的槽中的代理或闭包分配给,或者更简单地说

<?php

// File: todos.php

require_once "/path/to/vendor/autoload.php";

use Razor\EndPoint;

(new EndPoint())

    ->get(function ()
    {
        // Hey, that was easy!
    })

    ->run();

熟悉其他微框架格式的用户应该会认出这种语法。本质上,当Web浏览器发起HTTP GET请求时,传递给get()方法的代理(或闭包)中的代码会被调用。每个主要的HTTP动词都有一个方法调用,未来可能还会支持更多。

太好了!因此,我们的客户端可以通过浏览器访问我们的todo.php页面,但他们看到的是...什么也没有。让我们通过向浏览器发送消息来解决这个问题

<?php

// File: todos.php

require_once "/path/to/vendor/autoload.php";

use Razor\EndPoint;
use Razor\Services\Http;

(new EndPoint())

    ->get(function (Http $http)
    {
        return $http->response->standard("Hello, world!");
    })

    ->run();

现在当客户端连接时,他们将收到消息Hello, world!。你可能已经注意到,你不必在这个文件中指定$http对象的存在,并且它已经作为参数传递给代理。这里发生的事情被称为服务注入。

服务是提供应用程序某些功能的对象或值。当Razor决定调用HTTP GET请求的代理时,它会检查指定的参数,看看是否能提供它们。如果可以,它将在调用代理时注入这些参数。如果你有AngularJS背景,这对你来说可能很自然,如果没有,这可能会有些陌生。目标是使你的代理无状态,即不是这个

<?php

// File: todos.php

require_once "/path/to/vendor/autoload.php";

use Razor\EndPoint;
use Razor\Services\Http;

$http = new Http(/* Have to supply all the arguments here ... */);

(new EndPoint())

    ->get(function () use ($http)
    {
        return $http->response->standard("Hello, world!");
    })

    ->run();

这是因为,首先,你总是必须创建对象或编写相当丑陋的代码来懒加载它,其次是因为function () use (...)非常简短、丑陋,并且随着时间的推移变得难以维护和阅读。

在这个特定的例子中,$http是Razor附带的一个服务,但你也可以在你的代码中使用服务。假设我们已经有一个处理todo数据库管理的对象,我们可以在代码中这样指定

<?php

// File: todos.php

require_once "/path/to/vendor/autoload.php";

use Razor\Razor;
use Razor\EndPoint;
use Razor\Services\Http;

Razor::environment()
     ->services()
     ->register("todoRepo", function ()
     {
        return new TodoRepo(/* ... */);
     });

(new EndPoint())

    ->get(function (Http $http, TodoRepo $todoRepo)
    {
        $id = $http->request->get("id");

        $data = $todoRepo->get($id);

        return $http->response->json($data);
    })

    ->run();

在这里,我们使用代理将服务与框架的Environment注册。然后在我们的代码中,我们将这个服务指定为依赖项。重要的是要注意,我们使用的是名称todoRepo来查找服务,而不是类型提示。这是因为我们可能会遇到多个具有相同类型需要注入的对象,比如使用相同API的不同日志对象。

同样重要的是要注意,这个代理也可以接收注入的服务,比如

Razor::environment()
     ->services()
     ->registerMany(array(
         "conn", function ()
         {
            return new PDO(/* ... */);
         },

         "todoRepo", function (PDO $conn)
         {
            return new TodoRepo($conn);
         }
     ));

注意。建议您将这些服务注册移动到bootstrap.php文件中,这样随着您的应用程序不断增长,您可以更好地管理它。

假设您想将此应用程序公开到网络上,但您想确保有安全措施。您可以公开一个服务来处理此操作,但无疑会导致大量模板代码。因此,该框架提供了众所周知的中间件概念。

中间件是一个小对象,设计在您的代理之前调用,并执行请求过滤或响应修改。这意味着您可以编写小段功能代码,并从这些代码中组合您的处理。一个中间件的例子是

// File: src/SecurityMiddleware.php

use Razor\Middleware;
use Razor\Services\Http;

class SecurityMiddleware extends Middleware
{
    public function __invoke(Http $http)
    {
        if (!$http->request->isSecure()) {
            return $http->response->standard("Whoa! Your connection is not secure!", 400);
        }

        return $this->invokeDelegate();
    }
}

然后我们可以通过以下方式使用SecurityMiddleware

<?php

// File: todos.php

require_once "/path/to/vendor/autoload.php";

use Razor\EndPoint;
use Razor\Services\Http;

(new EndPoint())

    ->get(new SecurityMiddleware(function (Http $http, TodoRepo $todoRepo)
    {
        $id = $http->request->get("id");

        $data = $todoRepo->get($id);

        return $http->response->json($data);
    }))

    ->run();

因此,SecurityMiddleware将被首先调用,如果连接安全,它将随后调用我们的应用程序逻辑来处理GET请求。我们还可以将中间件串联起来

<?php

// File: todos.php

require_once "/path/to/vendor/autoload.php";

use Razor\EndPoint;
use Razor\Services\Http;

(new EndPoint())

    ->get(new SecurityMiddleware(new EnsureJsonMiddleware(function (Http $http, TodoRepo $todoRepo)
    {
        $id = $http->request->get("id");

        $data = $todoRepo->get($id);

        return $http->response->json($data);
    })))

    ->run();

关于Razor

该框架旨在为开发者提供便利。您希望编写结构良好的代码,但也需要为项目中每一行代码提供合理的解释?Razor尽可能地轻量级,使用简单的API进行服务注入,并在其HTTP服务中使用备受信赖的Symfony HTTP基础库。

您希望编写易于维护的代码?服务允许您在不增加应用程序逻辑中的模板代码的情况下,保持共享逻辑的可访问性。将应用程序逻辑保留在URL端点,这样您可以轻松地识别正在发生的事情。

总的来说,Razor旨在以一种优雅的方式让您处理HTTP请求,而不添加冗余。如果它符合您的工作流程,那么祝您好运!

安装

安装通过Composer进行,将Razor添加到您的依赖项中

{
    "require": {
        "rawebone/razor-library": "dev-master"
    }
}

一旦项目稳定,将有两个分支可供安装

  • 1.x.y
  • 1.x.y-compat

compat分支将允许PHP5.3及以上版本的用户使用该框架,而主分支将是PHP5.4及以上版本。

请将所有拉取请求基于master分支。

许可

MIT License,尽情使用。