Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/hyperf/nano

🧬 Nano is a zero-config, no skeleton, minimal Hyperf distribution that allows you to quickly build a Hyperf application with just a single PHP file.
https://github.com/hyperf/nano

Last synced: 10 days ago
JSON representation

🧬 Nano is a zero-config, no skeleton, minimal Hyperf distribution that allows you to quickly build a Hyperf application with just a single PHP file.

Lists

README

        

[English](./README.md) | 中文



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 友好

## 安装

```bash
composer require hyperf/nano
```

## 快速开始

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

```php
get('/', function () {

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

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

});

$app->run();
```

启动服务:

```bash
php index.php start
```

简洁如此。

## 更多示例

### 路由

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

```php
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
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
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
get('/', function () {
throw new \Exception();
});

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

$app->run();
```

### 命令行

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

$app->run();
```

执行

```bash
php index.php echo
```

### 事件监听

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

$app->run();
```

### 自定义进程

```php
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
addCrontab('* * * * * *', function(){
$this->get(StdoutLoggerInterface::class)->info('execute every second!');
})->setName('nano-crontab')->setOnOneServer(true)->setMemo('Test crontab.');

$app->run();
```

### AMQP

```php
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
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/watcher](https://github.com/hyperf/watcher) 在 `v2.2.6` 版本开始,支持 `Nano` 热更新。

首先我们需要引入组件

```shell
composer require hyperf/watcher
```

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

```php
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();
```

启动服务

```shell
$ php index.php server:watch
```

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

### 如何使用 Swow

- 安装兼容层

```shell
composer require "hyperf/engine-swow:^2.0"
```

- 运行代码

```php
get('/', function () {
return 'Hello World';
});

$app->run();
```