alexbilbie/proton

微PHP框架

1.4.1 2015-03-26 17:35 UTC

README

Latest Version Software License Build Status Coverage Status Quality Score

Proton 是一个与 StackPHP 兼容的微框架。

底层使用 League\Route 进行路由,League\Container 进行依赖注入,以及 League\Event 进行事件分发。

安装

只需将 "alexbilbie/proton": "~1.4" 添加到您的 composer.json 文件中。

设置

使用匿名函数的基本用法

// index.php
<?php

require __DIR__.'/../vendor/autoload.php';

$app = new Proton\Application();

$app->get('/', function ($request, $response) {
    $response->setContent('<h1>It works!</h1>');
    return $response;
});

$app->get('/hello/{name}', function ($request, $response, $args) {
    $response->setContent(
        sprintf('<h1>Hello, %s!</h1>', $args['name'])
    );
    return $response;
});

$app->run();

使用控制器的基本用法

// index.php
<?php

require __DIR__.'/../vendor/autoload.php';

$app = new Proton\Application();

$app['HomeController'] = function () {
    return new HomeController();
};

$app->get('/', 'HomeController::index'); // calls index method on HomeController class

$app->run();
// HomeController.php
<?php

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class HomeController
{
    public function index(Request $request, Response $response, array $args)
    {
        $response->setContent('<h1>It works!</h1>');
        return $response;
    }
}

使用 StackPHP(使用 Stack\BuilderStack\Run)的基本用法

// index.php
<?php
require __DIR__.'/../vendor/autoload.php';

$app = new Proton\Application();

$app->get('/', function ($request, $response) {
    $response->setContent('<h1>It works!</h1>');
    return $response;
});

$stack = (new Stack\Builder())
    ->push('Some/MiddleWare') // This will execute first
    ->push('Some/MiddleWare') // This will execute second
    ->push('Some/MiddleWare'); // This will execute third

$app = $stack->resolve($app);
Stack\run($app); // The app will run after all the middlewares have run

调试

默认情况下,Proton 以禁用调试选项的方式运行。要启用调试,请添加

$app['debug'] = true;

Proton 内置了对 Monolog 的支持。要访问通道,请调用

$app->getLogger('channel name');

有关通道的更多信息,请阅读此指南 - https://github.com/Seldaek/monolog/blob/master/doc/usage.md#leveraging-channels

自定义异常装饰

$app->setExceptionDecorator(function (\Exception $e) {
    $response = new \Symfony\Component\HttpFoundation\Response;
    $response->setStatusCode(500);
    $response->setContent('Epic fail!');
    return $response;
});

事件

您可以在生命周期中的三个点拦截请求和响应

request.received

$app->subscribe('request.received', function ($event) {
    // access the request using $event->getRequest()
})

当接收到请求但在路由器处理之前触发此事件。

response.created

$app->subscribe('response.created', function ($event) {
    // access the request using $event->getRequest()
    // access the response using $event->getResponse()
})

在创建响应但在输出之前触发此事件。

response.sent

$app->subscribe('response.sent', function ($event) {
    // access the request using $event->getRequest()
    // access the response using $event->getResponse()
})

在输出响应并在应用程序生命周期完成之前触发此事件。

自定义事件

您可以直接使用事件发射器触发自定义事件

// Subscribe
$app->subscribe('custom.event', function ($event, $time) {
    return 'the time is '.$time;
});

// Publish
$app->getEventEmitter()->emit('custom.event', time());

依赖注入容器

Proton 使用 League/Container 作为其依赖注入容器。

您可以使用 ArrayAccess 从主应用程序对象中将单例对象绑定到容器中

$app['db'] = function () {
    $manager = new Illuminate\Database\Capsule\Manager;

    $manager->addConnection([
        'driver'    => 'mysql',
        'host'      => $config['db_host'],
        'database'  => $config['db_name'],
        'username'  => $config['db_user'],
        'password'  => $config['db_pass'],
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci'
    ], 'default');

    $manager->setAsGlobal();

    return $manager;
};

或直接访问容器

$app->getContainer()->singleton('db', function () {
    $manager = new Illuminate\Database\Capsule\Manager;

    $manager->addConnection([
        'driver'    => 'mysql',
        'host'      => $config['db_host'],
        'database'  => $config['db_name'],
        'username'  => $config['db_user'],
        'password'  => $config['db_pass'],
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci'
    ], 'default');

    $manager->setAsGlobal();

    return $manager;
});

可以使用容器的 add 方法添加多重实例

$app->getContainer()->add('foo', function () {
        return new Foo();
});

可以使用 Proton 应用程序的 register 方法或容器的 addServiceProvider 方法注册服务提供者

$app->register('\My\Service\Provider');
$app->getContainer()->addServiceProvider('\My\Service\Provider');

有关服务提供者的更多信息,请参阅此页面 - http://container.thephpleague.com/service-providers/

为了方便将来的测试,建议您采用构造函数注入

$app->getContainer()->add('Bar', function () {
        return new Bar();
});

$app->getContainer()->add('Foo', function () use ($app) {
        return new Foo(
            $app->getContainer()->get('Bar')
        );
});