codeeverything/planck-framework

此软件包的最新版本(0.1)没有可用的许可证信息。

0.1 2016-06-02 09:19 UTC

This package is not auto-updated.

Last update: 2024-09-23 12:47:31 UTC


README

一个用于RESTful PHP应用的轻量级框架

这是一个为PHP编写[小型] RESTful框架的实验。使用Burlap容器来管理依赖项。

以普朗克时间和长度命名——分别是时间和长度的最小度量单位,具有任何意义。

注意:这是一个处于婴儿期的持续项目,所以请预期会有许多缺失的功能,并且许多功能可能无法正常工作 ;)

开源

这是一个开源项目,尽管它只是我的一个宠物项目,但欢迎贡献!所以请分支并提交PR :)

请随意添加问题以提出建议和评论。

有关更多信息(MIT),请参阅LICENSE.md

编写简单应用

Planck旨在最小化并帮助您快速进行RESTful响应。

RESTful请求的路由仍然由您的路由器和路由负责,但使用默认的Junction路由器,这很容易实现。

应用结构

您所有的应用代码都将位于/src/App文件夹中,除非您定义了任何路由、服务或监听器。

Planck需要以下两点才能让您快速启动

  • 一个路由,返回一个包含控制器实例条目、在该控制器上要调用的操作以及从路由传递的任何变量的数组。
  • 一个与路由中给出的名称匹配的控制器,后缀为"Controller",以及一个与路由中给出的操作匹配的操作。

例如

// config/routes.php
$router->add('GET /hello', function () {
    return [
        'controller' => 'Hello',
        'action' => 'hello',
        'vars' => func_get_args(),
    ];
});
// src/App/Controller/HelloController.php
namespace Planck\App\Controller;

class HelloController {
    
    public function hello() {
        return 'hello, world';
    }
    
}

Planck中的控制器是业务逻辑的入口和出口点。由于我们关注的是RESTful应用程序,我们希望控制器返回一些数据,这可以通过两种方式完成

  • 在控制器内部通过调用$this->set('property_name', 'property_value');设置返回值
  • 通过从控制器返回一个值或一组值return ['property' => 'value', 'result' => 1234];
    • 注意:此返回可以是任何可序列化的数据类型(在PHP中使用JsonSerializable接口,这甚至可以是POPO)

响应

Planck的默认行为是以JSON格式返回响应,但可以通过使用其他内置的ResponseFormatters之一或自己构建来更改此行为。

保持RESTful

Planck包括一个RESTController,您可以扩展它以访问一些有用的便利方法——例如

  • $this->ok() - 设置响应代码为200
  • $this->created() - 设置响应代码为201
  • $this->created(false) - 设置响应代码为202(已接受,稍后创建)
  • $this->blank() - 设置响应代码为204(无消息正文)
  • $this->unchanged() - 设置响应代码为304(移除消息正文)

RESTController还包括一个方便的afterAction回调,它将嗅探您的请求方法,并尝试为您设置适当的代码和正文内容。例如

  • GET - 200 OK
  • POST - 201 CREATED
  • PUT - 201 CREATED
  • 删除 - 204 无内容

如果这些不符合您的需求,您目前可以通过在控制器中有一个空的(或自定义的)afterAction函数来覆盖行为。未来我打算使这个过程更加灵活。

抛出RESTful错误

如果您的应用程序中存在错误条件(例如,带有 $id 的记录不存在),则抛出异常来捕获它,并返回一个合适的HTTP状态码消息,所有这些都被包装在一个整洁的包中。

Planck包括最常见的RESTful错误响应的异常,包括

  • 错误(400)
  • 未找到(404)
  • 未授权(401)
  • 禁止(403)
  • 冲突(409)
  • 服务器错误(500)

错误以整洁的包形式返回,通过定义一个名为 errorResponseBuilder 的服务来处理,该服务返回一个接受单个参数的函数 - 已抛出的异常。

默认包是一个包含“错误”和“代码”项的数组,分别显示异常消息和HTTP状态码。您可以通过重新定义服务来将其更改为您想要的任何内容。

服务和依赖注入

Planck对您使用的容器是中立的,尽管它期望它实现容器互操作性接口。

默认情况下,Planck使用轻量级的Burlap容器。

控制器依赖项来自容器,并且可以通过在控制器的init()函数中将容器服务作为参数来注入,例如

// controller code

// inject the service labelled as "db" into this function
public function init($db) {
    $this->db = $db;
}

// more controller code

监听器

Planck实现了一个简单的事件系统,您可以使用自己的应用程序特定事件来扩展它。

事件监听器在config/listeners.php文件中定义,并且按照惯例,Planck期望这些位于src/App/Listener文件夹中,但这由您决定。

一个示例监听器
//src/App/Listener/ExampleListener.php
<?php

namespace Planck\App\Listener;

use Planck\Core\Event\IEventListener;

class ExampleListener implements IEventListener {
    public function attachedEvents() {
        return [
            'controller.beforeAction' => 'doSomething', // core Planck event, triggered before the controller function resolved from the route is called
            'app.hello' => 'hello', // app specific event
        ];
    }
    
    public function doSomething($controller) {
        $controller->set([
            'externalListener' => true,
        ]);
    }
    
    public function hello($controller, $name) {
        $controller->set([
            "hello.message" => "Why hello $name! How you doin'? :)"
        ]);
    }
}
“发射”(触发)事件的示例
// src/App/Controller/HelloController

use Planck\Core\Event\Event;

public function hello($name) {
    echo "Hello, $name";
    // emit an event and pass the current object plus some more stuff. you can pass anything you want here
    Event::emit('app.welcomed', [$this, $moreData]);
}

// more goodness

待办事项

一个不断变化的需要查看的事项列表! :)

  • 删除src/App/view
  • 删除src/Core/View
  • 添加响应格式化程序
  • 使响应静态?
  • 添加一些测试和PHPUnit配置
  • 集成Junction路由器
  • 解耦路由器(某些定义的接口或映射?)
    • 通过提供一个应用程序配置“app.router.handler”,其中定义了一个要在路由器对象上调用的方法来处理请求并匹配路由来解耦。将很高兴找到类似于容器和实现它的标准
  • 解耦容器(容器互操作性接口)
  • 将“核心”拉入单独的框架存储库。也许可以用子树附加,或者只是通过Composer?
  • 将“分发”逻辑从index.php推入框架/应用程序/内核类中
    • 也许可以将其与实用函数(如pr()和debug())联系起来,让它们将输出添加到响应中,而不是在调用时内联(类似于CakePHP)?
  • 使请求和响应类符合PSR-7规范,并分成各自的存储库/包
    • 也许允许它们接收事件管理器和如何使用它来发出事件的详细信息,这样我们就可以执行“afterBodySet”等操作,例如设置调试输出?
  • 添加一些RESTful响应助手,例如
    • 返回错误
    • 返回“链接”
    • 指定操作的默认响应代码(查找为200,创建为201...)
  • 将配置和公共目录移至src/App下。然后允许插件共享应用程序的目录结构
    • 将config/database.php和config/app.php移动到/config目录中。这些跨越应用程序或插件
  • 在核心中定义一个插件类,这将“加载”插件,即处理任何配置并在需要时添加任何路径指针(例如,用于公共Web资源,如JS或图像)
  • 将PlanckPlugin添加到composer的安装类型列表中
  • 将Planck添加到composer的create-project列表中,插件到?