{"id":13609414,"url":"https://github.com/hyperf/nano","last_synced_at":"2025-05-16T12:12:37.581Z","repository":{"id":39667461,"uuid":"263810109","full_name":"hyperf/nano","owner":"hyperf","description":"🧬 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.","archived":false,"fork":false,"pushed_at":"2023-10-08T09:04:28.000Z","size":98,"stargazers_count":410,"open_issues_count":10,"forks_count":27,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-05-13T09:06:37.147Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://nano.hyperf.wiki","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hyperf.png","metadata":{"files":{"readme":"README-CN.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"open_collective":"hyperf","custom":"https://hyperf.wiki/#/zh-cn/donate"}},"created_at":"2020-05-14T03:56:47.000Z","updated_at":"2025-05-01T14:24:49.000Z","dependencies_parsed_at":"2024-01-14T06:56:08.703Z","dependency_job_id":null,"html_url":"https://github.com/hyperf/nano","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fnano","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fnano/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fnano/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperf%2Fnano/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyperf","download_url":"https://codeload.github.com/hyperf/nano/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254527099,"owners_count":22085919,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T19:01:34.722Z","updated_at":"2025-05-16T12:12:37.516Z","avatar_url":"https://github.com/hyperf.png","language":"PHP","readme":"[English](./README.md) | 中文\n\n\u003cp align=\"left\"\u003e\n  \u003ca href=\"https://travis-ci.com/hyperf/nano\"\u003e\u003cimg src=\"https://travis-ci.com/hyperf/nano.svg?branch=master\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://opencollective.com/hyperf\"\u003e\u003cimg src=\"https://opencollective.com/hyperf/all/badge.svg?label=financial+contributors\" alt=\"Financial Contributors on Open Collective\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://secure.php.net/\"\u003e\u003cimg src=\"https://img.shields.io/badge/php-%3E=7.2-brightgreen.svg?maxAge=2592000\" alt=\"Php Version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/swoole/swoole-src\"\u003e\u003cimg src=\"https://img.shields.io/badge/swoole-%3E=4.4-brightgreen.svg?maxAge=2592000\" alt=\"Swoole Version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/hyperf/nano/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/hyperf/nano.svg?maxAge=2592000\" alt=\"Nano License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# Nano, by Hyperf\n\nNano 是一款零配置、无骨架、极小化的 Hyperf 发行版，通过 Nano 可以让您仅仅通过 1 个 PHP 文件即可快速搭建一个 Hyperf 应用。   \n\n## 设计理念\n\n`Svelte` 的作者提出过一个论断：“框架不是用来组织代码的，是用来组织思路的”。而 Nano 最突出的一个优点就是不打断你的思路。Nano 非常擅长于自我声明，几乎不需要了解框架细节，只需要简单读一读代码，就能知道代码的目的。通过极简的代码声明，完成一个完整的 Hyperf 应用。\n\n## 特性\n\n* 无骨架\n* 零配置\n* 快速启动\n* 闭包风格\n* 支持注解外的全部 Hyperf 功能\n* 兼容全部 Hyperf 组件\n* Phar 友好\n\n## 安装\n\n```bash\ncomposer require hyperf/nano\n```\n\n## 快速开始\n\n创建一个 PHP 文件，如 index.php 如下：\n\n```php\n\u003c?php\nuse Hyperf\\Nano\\Factory\\AppFactory;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\n$app = AppFactory::create();\n\n$app-\u003eget('/', function () {\n\n    $user = $this-\u003erequest-\u003einput('user', 'nano');\n    $method = $this-\u003erequest-\u003egetMethod();\n\n    return [\n        'message' =\u003e \"hello {$user}\",\n        'method' =\u003e $method,\n    ];\n\n});\n\n$app-\u003erun();\n```\n\n启动服务：\n\n```bash\nphp index.php start\n```\n\n简洁如此。\n\n## 更多示例\n\n### 路由\n\n`$app` 集成了 Hyperf 路由器的所有方法。\n\n```php\n\u003c?php\nuse Hyperf\\Nano\\Factory\\AppFactory;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\n$app = AppFactory::create();\n\n$app-\u003eaddGroup('/nano', function () use ($app) {\n    $app-\u003eaddRoute(['GET', 'POST'], '/{id:\\d+}', function($id) {\n        return '/nano/'.$id;\n    });\n    $app-\u003eput('/{name:.+}', function($name) {\n        return '/nano/'.$name;\n    });\n});\n\n$app-\u003erun();\n```\n\n### DI 容器\n```php\n\u003c?php\nuse Hyperf\\Nano\\ContainerProxy;\nuse Hyperf\\Nano\\Factory\\AppFactory;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nclass Foo {\n    public function bar() {\n        return 'bar';\n    }   \n}\n\n$app = AppFactory::create();\n$app-\u003egetContainer()-\u003eset(Foo::class, new Foo());\n\n$app-\u003eget('/', function () {\n    /** @var ContainerProxy $this */\n    $foo = $this-\u003eget(Foo::class);\n    return $foo-\u003ebar();\n});\n\n$app-\u003erun();\n```\n\u003e 所有 $app 管理的闭包回调中，$this 都被绑定到了 `Hyperf\\Nano\\ContainerProxy` 上。\n\n### 中间件\n```php\n\u003c?php\nuse Hyperf\\Nano\\Factory\\AppFactory;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\n$app = AppFactory::create();\n\n$app-\u003eget('/', function () {\n    return $this-\u003erequest-\u003egetAttribute('key');\n});\n\n$app-\u003eaddMiddleware(function ($request, $handler) {\n    $request = $request-\u003ewithAttribute('key', 'value');\n    return $handler-\u003ehandle($request);\n});\n\n$app-\u003erun();\n```\n\n\u003e 除了闭包之外，所有 $app-\u003eaddXXX() 方法还接受类名作为参数。可以传入对应的 Hyperf 类。\n\n### 异常处理\n\n```php\n\u003c?php\nuse Hyperf\\HttpMessage\\Stream\\SwooleStream;\nuse Hyperf\\Nano\\Factory\\AppFactory;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\n$app = AppFactory::create();\n\n$app-\u003eget('/', function () {\n    throw new \\Exception();\n});\n\n$app-\u003eaddExceptionHandler(function ($throwable, $response) {\n    return $response-\u003ewithStatus('418')\n        -\u003ewithBody(new SwooleStream('I\\'m a teapot'));\n});\n\n$app-\u003erun();\n```\n\n### 命令行\n\n```php\n\u003c?php\nuse Hyperf\\Contract\\StdoutLoggerInterface;\nuse Hyperf\\Nano\\Factory\\AppFactory;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\n$app = AppFactory::create();\n\n$app-\u003eaddCommand('echo {--name=Nano}', function($name){\n    $this-\u003eoutput-\u003einfo(\"Hello, {$name}\");\n})-\u003esetDescription('The echo command.');\n\n$app-\u003erun();\n```\n\n执行\n\n```bash\nphp index.php echo\n```\n\n### 事件监听\n\n```php\n\u003c?php\nuse Hyperf\\Contract\\StdoutLoggerInterface;\nuse Hyperf\\Framework\\Event\\BootApplication;\nuse Hyperf\\Nano\\Factory\\AppFactory;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\n$app = AppFactory::create();\n\n$app-\u003eaddListener(BootApplication::class, function($event){\n    $this-\u003eget(StdoutLoggerInterface::class)-\u003einfo('App started');\n});\n\n$app-\u003erun();\n```\n\n### 自定义进程\n\n```php\n\u003c?php\nuse Hyperf\\Contract\\StdoutLoggerInterface;\nuse Hyperf\\Nano\\Factory\\AppFactory;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\n$app = AppFactory::create();\n\n$app-\u003eaddProcess(function(){\n    while (true) {\n        sleep(1);\n        $this-\u003econtainer-\u003eget(StdoutLoggerInterface::class)-\u003einfo('Processing...');    \n    }\n})-\u003esetName('nano-process')-\u003esetNums(1);\n\n$app-\u003eaddProcess(function(){\n    $this-\u003econtainer-\u003eget(StdoutLoggerInterface::class)-\u003einfo('根据env判定是否需要启动进程...');\n})-\u003esetName('nano-process')-\u003esetNums(1)-\u003esetEnable(\\Hyperf\\Support\\env('PROCESS_ENABLE', true))));\n\n$app-\u003erun();\n```\n\n### 定时任务\n\n```php\n\u003c?php\nuse Hyperf\\Contract\\StdoutLoggerInterface;\nuse Hyperf\\Nano\\Factory\\AppFactory;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\n$app = AppFactory::create();\n\n$app-\u003eaddCrontab('* * * * * *', function(){\n    $this-\u003eget(StdoutLoggerInterface::class)-\u003einfo('execute every second!');\n})-\u003esetName('nano-crontab')-\u003esetOnOneServer(true)-\u003esetMemo('Test crontab.');\n\n$app-\u003erun();\n```\n\n### AMQP\n\n```php\n\u003c?php\n\nuse Hyperf\\Nano\\Factory\\AppFactory;\nuse Hyperf\\Amqp;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nclass Message extends Amqp\\Message\\ProducerMessage\n{\n    protected $exchange = 'hyperf';\n\n    protected $routingKey = 'hyperf';\n\n    public function __construct($data)\n    {\n        $this-\u003epayload = $data;\n    }\n}\n\n$app = AppFactory::createBase();\n$container = $app-\u003egetContainer();\n\n$app-\u003econfig([\n    'amqp' =\u003e [\n        'default' =\u003e [\n            'host' =\u003e 'localhost',\n            'port' =\u003e 5672,\n            'user' =\u003e 'guest',\n            'password' =\u003e 'guest',\n            'vhost' =\u003e '/',\n            'concurrent' =\u003e [\n                'limit' =\u003e 1,\n            ],\n            'pool' =\u003e [\n                'min_connections' =\u003e 1,\n                'max_connections' =\u003e 10,\n                'connect_timeout' =\u003e 10.0,\n                'wait_timeout' =\u003e 3.0,\n                'heartbeat' =\u003e -1,\n            ],\n            'params' =\u003e [\n                'insist' =\u003e false,\n                'login_method' =\u003e 'AMQPLAIN',\n                'login_response' =\u003e null,\n                'locale' =\u003e 'en_US',\n                'connection_timeout' =\u003e 3.0,\n                'read_write_timeout' =\u003e 6.0,\n                'context' =\u003e null,\n                'keepalive' =\u003e false,\n                'heartbeat' =\u003e 3,\n                'close_on_destruct' =\u003e true,\n            ],\n        ],\n    ],\n]);\n\n$app-\u003eaddProcess(function () {\n    $message = new class extends Amqp\\Message\\ConsumerMessage {\n        protected $exchange = 'hyperf';\n\n        protected $queue = 'hyperf';\n\n        protected $routingKey = 'hyperf';\n\n        public function consumeMessage($data, \\PhpAmqpLib\\Message\\AMQPMessage $message): string\n        {\n            var_dump($data);\n            return Amqp\\Result::ACK;\n        }\n    };\n    $consumer = $this-\u003eget(Amqp\\Consumer::class);\n    $consumer-\u003econsume($message);\n});\n\n$app-\u003eget('/', function () {\n    /** @var Amqp\\Producer $producer */\n    $producer = $this-\u003eget(Amqp\\Producer::class);\n    $producer-\u003eproduce(new Message(['id' =\u003e $id = uniqid()]));\n    return $this-\u003eresponse-\u003ejson([\n        'id' =\u003e $id,\n        'message' =\u003e 'Hello World.'\n    ]);\n});\n\n$app-\u003erun();\n\n```\n\n### 使用更多 Hyperf 组件\n\n```php\n\u003c?php\nuse Hyperf\\DB\\DB;\nuse Hyperf\\Nano\\Factory\\AppFactory;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\n$app = AppFactory::create();\n\n$app-\u003econfig([\n    'db.default' =\u003e [\n        'host' =\u003e env('DB_HOST', 'localhost'),\n        'port' =\u003e env('DB_PORT', 3306),\n        'database' =\u003e env('DB_DATABASE', 'hyperf'),\n        'username' =\u003e env('DB_USERNAME', 'root'),\n        'password' =\u003e env('DB_PASSWORD', ''),\n    ]\n]);\n\n$app-\u003eget('/', function(){\n    return DB::query('SELECT * FROM `user` WHERE gender = ?;', [1]);\n});\n\n$app-\u003erun();\n```\n\n\n### 热更新\n\n热更新组件 [hyperf/watcher](https://github.com/hyperf/watcher) 在 `v2.2.6` 版本开始，支持 `Nano` 热更新。\n\n首先我们需要引入组件\n\n```shell\ncomposer require hyperf/watcher\n```\n\n接下来编写样例代码 `index.php`\n\n```php\n\u003c?php\n\nuse Hyperf\\Nano\\Factory\\AppFactory;\nuse Hyperf\\Watcher\\Driver\\ScanFileDriver;\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\n$app = AppFactory::createBase();\n$app-\u003econfig([\n    'server.settings.pid_file' =\u003e BASE_PATH . '/hyperf.pid',\n    'watcher' =\u003e [\n        'driver' =\u003e ScanFileDriver::class,\n        'bin' =\u003e 'php',\n        'command' =\u003e 'index.php start',\n        'watch' =\u003e [\n            'dir' =\u003e [],\n            'file' =\u003e ['index.php'],\n            'scan_interval' =\u003e 2000,\n        ],\n    ],\n]);\n\n$app-\u003eget('/', function () {\n\n    $user = $this-\u003erequest-\u003einput('user', 'nano');\n    $method = $this-\u003erequest-\u003egetMethod();\n\n    return [\n        'message' =\u003e \"Hello {$user}\",\n        'method' =\u003e $method,\n    ];\n\n});\n\n$app-\u003erun();\n```\n\n启动服务\n\n```shell\n$ php index.php server:watch\n```\n\n最后我们只需要修改 `index.php` 的源码，就可以看到具体效果了。\n\n### 如何使用 Swow\n\n- 安装兼容层\n\n```shell\ncomposer require \"hyperf/engine-swow:^2.0\"\n```\n\n- 运行代码\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nuse Hyperf\\Nano\\Factory\\AppFactory;\n\nrequire_once __DIR__ . '/../vendor/autoload.php';\n\n$app = AppFactory::createSwow();\n\n$app-\u003eget('/', function () {\n    return 'Hello World';\n});\n\n$app-\u003erun();\n```\n","funding_links":["https://opencollective.com/hyperf","https://hyperf.wiki/#/zh-cn/donate"],"categories":["Frameworks","PHP"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperf%2Fnano","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyperf%2Fnano","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperf%2Fnano/lists"}