larkframe / template
LarkFrame application template
Requires
- php: >=8.1
- ext-gd: *
- ext-pdo: *
- genkgo/mail: ^2.12
- larkframe/core: 0.1.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-10-20 14:43:08 UTC
README
基于 LarkFrame Core 框架的项目模板,开箱即用。
环境要求
- PHP >= 8.1
- ext-json, ext-pdo, ext-gd
- Redis(队列
/api/queue、Task 示例依赖;默认使用 phpredis 扩展,未安装时在config/config.php的 redis 配置中加'client' => 'predis') - MySQL(
/api/db示例依赖) - Composer
快速开始
# 1. 创建项目 composer create-project larkframe/template myapp cd myapp # 2. 启动开发服务器 php server.php
默认监听 http://0.0.0.0:8080
首次启动时,框架会自动在项目根目录创建
.env文件(包含APP_NAME、TIME_ZONE、RUN_MODE),无需手动配置。
项目结构
myapp/
├── app/ # 应用代码
│ ├── Base/ # 基类
│ │ ├── Controller.php # 控制器基类
│ │ ├── ErrorHandler.php # 错误处理器
│ │ └── Model.php # 模型基类
│ ├── Controller/ # 控制器
│ │ ├── DefaultController.php
│ │ └── ShellController.php
│ ├── Job/ # 队列任务
│ │ └── SendEmailJob.php
│ ├── Library/ # 业务类库
│ │ └── Notify.php
│ ├── Middleware/ # 中间件
│ │ └── CorsMiddleware.php
│ ├── Model/ # 数据模型
│ │ └── UserModel.php
│ └── Task/ # 常驻任务
│ ├── ConsumeTask.php
│ └── CronTask.php
├── config/ # 配置文件
│ ├── config.php # 主配置
│ ├── notify.php # 通知配置(自动加载)
│ ├── route.php # 路由定义
│ └── task.php # 任务配置
├── public/ # Web 入口
│ └── index.php # FPM 入口
├── template/ # 视图模板
│ ├── default/
│ └── user/
├── .gitignore
├── composer.json
├── server.php # Server 模式入口
├── shell.php # Shell 模式入口
├── task.php # Task 模式入口
└── README.md
框架文档
框架 larkframe/core 的完整组件文档随包分发(不在本模板内):
- composer 安装态:
vendor/larkframe/core/docs/*.md(16 个组件专题文档) - 本地 path 仓库开发态:
../core/docs/*.md - AI 辅助编程入口:
AGENTS.md(含框架文档索引与 API 速查)
核心功能示例
路由
路由定义在 config/route.php:
use LarkFrame\Route; // 基础路由 Route::get('/users', [UserController::class, 'index']); Route::post('/users', [UserController::class, 'store']); Route::put('/users/{id}', [UserController::class, 'update']); Route::delete('/users/{id}', [UserController::class, 'destroy']); // 带参数的路由 Route::get('/users/{id:\d+}', function ($request) { $id = $request->route()->param('id'); return json(['user_id' => $id]); }); // 命令行路由 Route::shell('/migrate', [MigrateController::class, 'run']);
控制器
namespace App\Controller; use LarkFrame\Request; class UserController { public function indexAction(Request $request) { $page = $request->input('page', 1); $users = \LarkFrame\Db::table('users')->paginate(15, ['*'], 'page', $page); return json(['code' => 0, 'data' => $users]); } public function showAction(Request $request) { $id = $request->route()->param('id'); $user = \LarkFrame\Db::table('users')->where('id', $id)->first(); return json(['code' => 0, 'data' => $user]); } }
数据库
use LarkFrame\Db; // 查询构建器 $users = Db::table('users')->where('status', 'active')->get(); // 多库切换 $orders = Db::use('order_db')->table('orders')->get(); // Eloquent Model $user = \App\Model\UserModel::find(1); $user = \App\Model\UserModel::create(['name' => 'John', 'email' => 'john@example.com']);
缓存
use LarkFrame\Cache\Cache; Cache::set('key', 'value', 3600); $value = Cache::get('key'); Cache::delete('key');
Redis
use LarkFrame\Cache\Redis; Redis::set('key', 'value'); Redis::get('key'); Redis::use('cache', 1)->set('key', 'value'); // 切换连接和数据库
队列
use LarkFrame\Queue; // 推送任务 Queue::push('emails', \App\Job\SendEmailJob::class, ['to' => 'user@example.com']); // 延迟推送 Queue::later('emails', 60, \App\Job\SendEmailJob::class, ['to' => 'user@example.com']); // 队列大小 $size = Queue::size('emails');
队列任务类:
namespace App\Job; use LarkFrame\Queue\Job; class SendEmailJob { public function handle(Job $job, mixed $data): void { // 处理逻辑 $job->ack(); } }
中间件
use LarkFrame\MiddlewareInterface; use LarkFrame\Request; use LarkFrame\Response; class AuthMiddleware implements MiddlewareInterface { public function process(Request $request, callable $handler): Response { if (!$request->header('authorization')) { // json() 状态码固定 200,自定义状态码用 ->withStatus() return json(['error' => 'Unauthorized'])->withStatus(401); } return $handler($request); } }
注册中间件:
// 全局中间件 — config/config.php 的 server.middleware 'middleware' => [ \App\Middleware\CorsMiddleware::class, ], // 路由中间件 Route::get('/admin', [AdminController::class, 'index']) ->middleware(AuthMiddleware::class);
工具集
use LarkFrame\Util; Util::str()->mask('13800138000'); // 138****8000 Util::rand()->uuid(); // UUID v4 Util::base64()->urlEncode($data); // URL 安全 Base64 Util::str()->formatBytes(1048576); // 1 MB Util::file()->ensureDir($dir); // 确保目录存在
视图
// 原生 PHP 模板(模板文件 template/default/index.php) return raw_view('default/index', ['username' => 'world'], 'php'); // Twig 模板(模板文件 template/user/test.html,示例路由 /user/test) return twig_view('user/test', ['name' => 'larkframe'], 'html');
配置说明
环境变量 (.env)
.env 文件仅用于定义应用启动参数,框架首次启动时会自动创建(默认 RUN_MODE=prod)。它不会注入到 config() 配置系统中。
APP_NAME=myapp # 应用名称,定义为 APP_NAME 常量 TIME_ZONE=Asia/Shanghai # 时区 RUN_MODE=prod # 运行模式:dev/test/stage/prod,定义为 RUN_MODE 常量;框架据此加载 config.{RUN_MODE}.php 覆盖配置
敏感配置(数据库密码、Redis 密码等)应通过
config/config.{env}.php环境覆盖文件管理,而非.env。
config/config.php中app.debug默认false(生产安全)。开发时将.env的RUN_MODE改为dev,并创建config/config.dev.php覆盖['app' => ['debug' => true]]即可开启堆栈详情。
多环境配置
config/
config.php # 主配置
config.dev.php # 开发环境覆盖
config.prod.php # 生产环境覆盖
注意(浅合并):环境覆盖为顶层
array_merge——覆盖文件中的顶层键 (如server)会整体替换主配置的对应键,必须携带完整子结构。 例如config.dev.php覆盖server.socketName时需同时带上server.middleware, 否则全局中间件会被清空。
自定义类库配置
app/Library/Notify.php 对应 config/notify.php,配置自动加载到 $this->config:
// config/notify.php return [ 'mail' => ['host' => 'smtp.example.com', ...], ]; // app/Library/Notify.php class Notify extends \LarkFrame\Library { public function send() { $config = $this->config['mail']; // 自动加载 } }
运行模式
框架通过入口文件显式指定运行模式(App::run(LarkFrame\Consts::RUN_TYPE_*)):
| 模式 | 启动方式 | 入口文件 |
|---|---|---|
| Server | php server.php |
server.php |
| Shell | php shell.php route "key=value" |
shell.php |
| Task | php task.php <taskname> [start|stop|restart|reload|status] [args] |
task.php |
| Web | 浏览器访问 | public/index.php |
Server 模式(推荐)
常驻内存,事件驱动,高性能,支持多 Worker 进程。
# 启动 Server(前台运行,开发调试) php server.php # 后台守护运行 # 在 config/config.php 中设置 'daemonize' => true,然后启动 php server.php # 停止服务(通过 PID) kill $(cat runtime/server.pid)
Server 模式启动后监听 config.server.socketName 指定的地址(默认 http://0.0.0.0:8080),通过 HTTP 协议接收请求,路由匹配和请求处理在 Worker 进程中完成。
配置项(config/config.php):
'server' => [ 'socketName' => 'http://0.0.0.0:8080', // 监听地址 'daemonize' => false, // 是否守护进程 'worker' => [ 'count' => 4, // Worker 进程数 'reusePort' => true, // 端口复用 ], 'middleware' => [...], // 全局中间件 ],
Shell 模式
命令行执行单次任务,路由匹配 Route::shell() 定义的路由。
# 执行 shell 路由 php shell.php migrate php shell.php queue/work # 路由参数 php shell.php users/import "file=data.csv"
Shell 模式下:
- HTTP 方法自动设为
SHELL - 路由取
$_SERVER['argv'][1](自动补/前缀) - 参数取
$_SERVER['argv'][2],格式为"key=value&key2=value2"(通过parse_str解析为 GET/POST 参数) - 请求源为
LarkFrame\Request\ShellSource - 执行完毕后进程退出
Task 模式
常驻内存 Worker 进程执行自定义任务,适合队列消费、定时任务、后台处理等场景。taskname 对应 config/task.php 中定义的任务配置。
# 前台运行(默认 start) php task.php cron # 停止任务 php task.php cron stop # 重启任务 php task.php cron restart # 查看状态 php task.php cron status # 带参数启动 php task.php cleanup "days=30"
配置项(config/task.php):
return [ 'cron' => [ 'handler' => \App\Task\CronTask::class, // 任务处理类(必须) 'options' => ['interval' => 60], // 传递给 run() 的选项 'daemonize' => false, // 是否守护进程 'worker' => ['count' => 1], // Worker 进程数 'pidFile' => 'task-cron.pid', // PID 文件(runtime/ 下) 'stdoutFile' => 'task-cron.stdout.log', // 标准输出文件(runtime/ 下) 'logFile' => 'task-cron.log', // 日志文件(runtime/ 下) ], ];
任务类需实现 run 静态方法:
namespace App\Task; use LarkFrame\Worker; class CronTask { public static function run(array $options, array $args): void { $interval = $options['interval'] ?? 60; Worker::log("[CronTask] Starting, interval: {$interval}s"); // 注册定时器 Worker::$globalEvent->repeat($interval, function () { // 定时执行的逻辑 Worker::log("[CronTask] tick"); }); } }
$options:来自配置的options键$args:来自命令行参数(parse_str解析后的关联数组)- 使用
Worker::log()输出日志(同时写入终端和日志文件),不要使用echo
运行时文件在 runtime/ 目录下:task-{name}.pid、task-{name}.log、task-{name}.stdout.log
Web 模式(PHP-FPM)
传统 PHP-FPM 部署,每次请求独立进程。站点根目录必须指向 public/,不要指向项目根目录。
# Nginx 配置 — root 指向 public 目录 server { root /var/www/myapp/public; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
访问示例:http://example.com/api
Web 模式下:
- 请求源为
LarkFrame\Request\WebSource(从$_GET/$_POST/$_SERVER读取) - 中间件与 Server 模式行为一致:全局/路由/控制器中间件照常执行, CORS 等响应头中间件在 FPM 下同样生效(404/405 兜底响应也穿全局中间件管道)
- 无需连接池(每次请求独立进程)
- 适合低流量或无法运行常驻进程的环境
License
MIT