Skip to content

Latest commit

 

History

History
459 lines (330 loc) · 9.95 KB

README-CN.md

File metadata and controls

459 lines (330 loc) · 9.95 KB

English | 中文

Financial Contributors on Open Collective Php Version Swoole Version Nano License

Nano, by Hyperf

Nano 是一款零配置、无骨架、极小化的 Hyperf 发行版,通过 Nano 可以让您仅仅通过 1 个 PHP 文件即可快速搭建一个 Hyperf 应用。

设计理念

Svelte 的作者提出过一个论断:“框架不是用来组织代码的,是用来组织思路的”。而 Nano 最突出的一个优点就是不打断你的思路。Nano 非常擅长于自我声明,几乎不需要了解框架细节,只需要简单读一读代码,就能知道代码的目的。通过极简的代码声明,完成一个完整的 Hyperf 应用。

特性

  • 无骨架
  • 零配置
  • 快速启动
  • 闭包风格
  • 支持注解外的全部 Hyperf 功能
  • 兼容全部 Hyperf 组件
  • Phar 友好

安装

composer require hyperf/nano

快速开始

创建一个 PHP 文件,如 index.php 如下:

<?php
use Hyperf\Nano\Factory\AppFactory;

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

$app = AppFactory::create();

$app->get('/', function () {

    $user = $this->request->input('user', 'nano');
    $method = $this->request->getMethod();

    return [
        'message' => "hello {$user}",
        'method' => $method,
    ];

});

$app->run();

启动服务:

php index.php start

简洁如此。

更多示例

路由

$app 集成了 Hyperf 路由器的所有方法。

<?php
use Hyperf\Nano\Factory\AppFactory;

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

$app = AppFactory::create();

$app->addGroup('/nano', function () use ($app) {
    $app->addRoute(['GET', 'POST'], '/{id:\d+}', function($id) {
        return '/nano/'.$id;
    });
    $app->put('/{name:.+}', function($name) {
        return '/nano/'.$name;
    });
});

$app->run();

DI 容器

<?php
use Hyperf\Nano\ContainerProxy;
use Hyperf\Nano\Factory\AppFactory;

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

class Foo {
    public function bar() {
        return 'bar';
    }   
}

$app = AppFactory::create();
$app->getContainer()->set(Foo::class, new Foo());

$app->get('/', function () {
    /** @var ContainerProxy $this */
    $foo = $this->get(Foo::class);
    return $foo->bar();
});

$app->run();

所有 $app 管理的闭包回调中,$this 都被绑定到了 Hyperf\Nano\ContainerProxy 上。

中间件

<?php
use Hyperf\Nano\Factory\AppFactory;

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

$app = AppFactory::create();

$app->get('/', function () {
    return $this->request->getAttribute('key');
});

$app->addMiddleware(function ($request, $handler) {
    $request = $request->withAttribute('key', 'value');
    return $handler->handle($request);
});

$app->run();

除了闭包之外,所有 $app->addXXX() 方法还接受类名作为参数。可以传入对应的 Hyperf 类。

异常处理

<?php
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\Nano\Factory\AppFactory;

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

$app = AppFactory::create();

$app->get('/', function () {
    throw new \Exception();
});

$app->addExceptionHandler(function ($throwable, $response) {
    return $response->withStatus('418')
        ->withBody(new SwooleStream('I\'m a teapot'));
});

$app->run();

命令行

<?php
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Nano\Factory\AppFactory;

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

$app = AppFactory::create();

$app->addCommand('echo {--name=Nano}', function($name){
    $this->output->info("Hello, {$name}");
})->setDescription('The echo command.');

$app->run();

执行

php index.php echo

事件监听

<?php
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Framework\Event\BootApplication;
use Hyperf\Nano\Factory\AppFactory;

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

$app = AppFactory::create();

$app->addListener(BootApplication::class, function($event){
    $this->get(StdoutLoggerInterface::class)->info('App started');
});

$app->run();

自定义进程

<?php
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Nano\Factory\AppFactory;

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

$app = AppFactory::create();

$app->addProcess(function(){
    while (true) {
        sleep(1);
        $this->container->get(StdoutLoggerInterface::class)->info('Processing...');    
    }
})->setName('nano-process')->setNums(1);

$app->addProcess(function(){
    $this->container->get(StdoutLoggerInterface::class)->info('根据env判定是否需要启动进程...');
})->setName('nano-process')->setNums(1)->setEnable(\Hyperf\Support\env('PROCESS_ENABLE', true))));

$app->run();

定时任务

<?php
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Nano\Factory\AppFactory;

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

$app = AppFactory::create();

$app->addCrontab('* * * * * *', function(){
    $this->get(StdoutLoggerInterface::class)->info('execute every second!');
})->setName('nano-crontab')->setOnOneServer(true)->setMemo('Test crontab.');

$app->run();

AMQP

<?php

use Hyperf\Nano\Factory\AppFactory;
use Hyperf\Amqp;

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

class Message extends Amqp\Message\ProducerMessage
{
    protected $exchange = 'hyperf';

    protected $routingKey = 'hyperf';

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

$app = AppFactory::createBase();
$container = $app->getContainer();

$app->config([
    'amqp' => [
        'default' => [
            'host' => 'localhost',
            'port' => 5672,
            'user' => 'guest',
            'password' => 'guest',
            'vhost' => '/',
            'concurrent' => [
                'limit' => 1,
            ],
            'pool' => [
                'min_connections' => 1,
                'max_connections' => 10,
                'connect_timeout' => 10.0,
                'wait_timeout' => 3.0,
                'heartbeat' => -1,
            ],
            'params' => [
                'insist' => false,
                'login_method' => 'AMQPLAIN',
                'login_response' => null,
                'locale' => 'en_US',
                'connection_timeout' => 3.0,
                'read_write_timeout' => 6.0,
                'context' => null,
                'keepalive' => false,
                'heartbeat' => 3,
                'close_on_destruct' => true,
            ],
        ],
    ],
]);

$app->addProcess(function () {
    $message = new class extends Amqp\Message\ConsumerMessage {
        protected $exchange = 'hyperf';

        protected $queue = 'hyperf';

        protected $routingKey = 'hyperf';

        public function consumeMessage($data, \PhpAmqpLib\Message\AMQPMessage $message): string
        {
            var_dump($data);
            return Amqp\Result::ACK;
        }
    };
    $consumer = $this->get(Amqp\Consumer::class);
    $consumer->consume($message);
});

$app->get('/', function () {
    /** @var Amqp\Producer $producer */
    $producer = $this->get(Amqp\Producer::class);
    $producer->produce(new Message(['id' => $id = uniqid()]));
    return $this->response->json([
        'id' => $id,
        'message' => 'Hello World.'
    ]);
});

$app->run();

使用更多 Hyperf 组件

<?php
use Hyperf\DB\DB;
use Hyperf\Nano\Factory\AppFactory;

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

$app = AppFactory::create();

$app->config([
    'db.default' => [
        'host' => env('DB_HOST', 'localhost'),
        'port' => env('DB_PORT', 3306),
        'database' => env('DB_DATABASE', 'hyperf'),
        'username' => env('DB_USERNAME', 'root'),
        'password' => env('DB_PASSWORD', ''),
    ]
]);

$app->get('/', function(){
    return DB::query('SELECT * FROM `user` WHERE gender = ?;', [1]);
});

$app->run();

热更新

热更新组件 hyperf/watcherv2.2.6 版本开始,支持 Nano 热更新。

首先我们需要引入组件

composer require hyperf/watcher

接下来编写样例代码 index.php

<?php

use Hyperf\Nano\Factory\AppFactory;
use Hyperf\Watcher\Driver\ScanFileDriver;

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

$app = AppFactory::createBase();
$app->config([
    'server.settings.pid_file' => BASE_PATH . '/hyperf.pid',
    'watcher' => [
        'driver' => ScanFileDriver::class,
        'bin' => 'php',
        'command' => 'index.php start',
        'watch' => [
            'dir' => [],
            'file' => ['index.php'],
            'scan_interval' => 2000,
        ],
    ],
]);

$app->get('/', function () {

    $user = $this->request->input('user', 'nano');
    $method = $this->request->getMethod();

    return [
        'message' => "Hello {$user}",
        'method' => $method,
    ];

});

$app->run();

启动服务

$ php index.php server:watch

最后我们只需要修改 index.php 的源码,就可以看到具体效果了。

如何使用 Swow

  • 安装兼容层
composer require "hyperf/engine-swow:^2.0"
  • 运行代码
<?php

declare(strict_types=1);

use Hyperf\Nano\Factory\AppFactory;

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

$app = AppFactory::createSwow();

$app->get('/', function () {
    return 'Hello World';
});

$app->run();