PHP code example of veasin / nx-tiny

1. Go to this page and download the library: Download veasin/nx-tiny library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

veasin / nx-tiny example snippets


// 获取所有配置
$all = container();

// 清空请求级配置
container(null);

// 清空持久级配置
container(null, true);
container(null, '^');

// 读取值(支持 . 分隔,先查请求级再查持久级)
$host = container('database.host');

// 仅读取持久级(^ 前缀)
$host = container('^database.host');

// 设置值(写入请求级)
container('database.host', 'localhost');
container('app.debug', true);

// 设置值(写入持久级,^ 前缀)
container('^database.host', 'localhost');

// 删除键(设置 null)
container('database.host', null);

// 批量读取(list 数组)
$values = container(['database.host', 'app.debug']);

// 批量设置(map 数组,写入请求级)
container([
    'database.host' => '127.0.0.1',
    'database.port' => 3306,
]);

// 批量持久设置
container(['k' => 'v'], true);
container(['k' => 'v'], '^');

// 数组 key 支持 ^ 修饰符单独控制
container(['^persist.k' => 'v', 'request.k' => 'v']);

// 闭包工厂:存入闭包,用 * 后缀执行
container('version', fn() => file_get_contents('version.txt'));
$closure = container('version');  // 返回闭包本身
$result  = container('version*'); // 执行闭包返回结果

// 非闭包值忽略 *
container('plain', 'string');
container('plain*');  // 返回 'string'

// 读取环境变量
$debug = env('APP_DEBUG');   // 自动类型转换: 'true' → true, 'false' → false, 'null' → null
$host  = env('DB_HOST');     // 不存在返回 null
$name  = env('APP_NAME');    // 字符串原样返回

// .env 文件路径可通过容器配置
container('#env', '/path/to/.env');
env('APP_KEY');

// 默认自动查找:从 src/ 向上搜索 .env(最多 3 层)

// 字符串输入
$args = args('-v --file=test.php input.txt');
// 结果: ['v' => true, 'file' => 'test.php', 'input.txt']

// 数组输入
$args = args(['-abc', '--verbose', '--name=John', 'data.txt']);
// 结果: ['a' => true, 'b' => true, 'c' => true, 'verbose' => true, 'name' => 'John', 'data.txt']

// 带引号的值
$args = args('--message="Hello World" --path=\'/usr/local\'');
// 结果: ['message' => 'Hello World', 'path' => '/usr/local']

// 获取当前请求方法
$method = method();  // 返回: 'get', 'post', 'cli' 等

// 检查是否匹配指定方法
if (method('POST')) {
    // 处理 POST 请求
}

// 预置请求方法(通过容器)
container('#method', 'put');

// 无参调用
$users = safe(fn() => db('SELECT * FROM users'));

// 带参数调用
$user = safe(fn($id) => db('SELECT * FROM users WHERE id=?', [$id]), 1);

// 多参数
$result = safe(fn($a, $b) => $a / $b, 10, 0);  // 返回 null

// 异常时静默降级
$data = safe(fn() => json_decode($raw, true, 512, JSON_THROW_ON_ERROR));

// 从 Body 获取原始值
$id = from('id', 'body');

// 从 Query 获取原始值
$name = from('name', 'query');

// 从 Header 获取原始值
$token = from('authorization', 'header');

// 直接使用数组作为来源
$data = from('id', ['id' => 123, 'name' => 'test']);

// 获取整个来源
$body = from(null, 'body');

// 批量获取
$result = from(['id', 'name'], 'query');  // ['id' => null, 'name' => 'test']

// 预置输入数据(通过容器缓存)
container('#in.input', ['method' => 'get', 'uri' => '/test', 'params' => []]);
container('#in.params', ['id' => 123]);  // 预置路由参数
container('#in.body', ['name' => 'test']);  // 预置请求体
container('#in.headers', ['Authorization' => 'Bearer xxx']);  // 预置请求头

// 扩展 content-type 解析器
container('#in.content', [
    'application/xml' => fn($raw) => simplexml_load_string($raw),
    'default' => fn($raw) => ['raw' => $raw],
]);

// 类型转换
filter('123', 'int');        // 返回 123 (int)
filter('true', 'bool');      // 返回 true
filter('{"a":1}', 'json');   // 返回 ['a' => 1]

// 验证规则
filter('[email protected]', 'email');  // 返回邮箱字符串
filter('150', 'int', '>100', '<200');  // 返回 150
filter('on', 'bool');                  // 返回 true

// 逗号分隔的组合规则
filter('150', 'int,>100,<200');  // 返回 150

// 自定义验证
filter('abc', fn($v) => strlen($v) > 2);  // 返回 'abc'
filter(10, 'int', '>5');                  // 返回 10
filter(3, 'int', '>5');                   // 返回 null (验证失败)

// 扩展规则(通过容器配置 #filter)
container('#filter', [
    'phone' => [null, null, [fn($v) => preg_match('/^1\d{10}$/', $v)]],
]);
filter('13800138000', 'phone');  // 返回 '13800138000'

// 获取并验证(多个规则)
$age = input('age', 'query', 'int', '>=18', '<=100');

// 组合规则
$age = input('age', 'body,int,>=18,<=100');

// 批量获取
$data = input(['id' => 'int,>0', 'name' => 'str']);

// 开启钩子模式(持久级,Worker 启动时调用一次)
hook(true);                                  // 默认序列 ['after', 'end']
hook(true, ['after', 'end']);                // 自定义默认序列

// 注册回调到钩子(请求级)
hook('after', function() {
    output(['status' => 'ok']);
});
hook('end', function() {
    test('结果验证', $result, $expected);
});

// 触发钩子
hook();                     // 触发默认序列(after → end)
hook('after');              // 触发单个钩子
hook(['after', 'end']);     // 自定义触发顺序

// 不开启钩子模式也能独立注册和触发
hook('custom', fn() => echo 'hello');
hook('custom');

// JSON 输出
output(['status' => 'ok', 'data' => [1, 2, 3]]);

// 设置状态码
output(['error' => 'not found'], 404);

// 指定格式输出
output($data, 'json');

// 输出视图
output($viewData, 'view', 'template.php');
output($viewData, 'view', ['file' => 'template.php']);

// 文件输出(展示文件)
output(null, 'file', '/path/to/file.pdf');

// 文件下载
output(true, 'file', '/path/to/file.pdf');

// 带响应头
output(['token' => $token], 200, ['Authorization' => 'Bearer xxx']);

// 无参调用触发输出(用于 worker 模式显式发送)
output();

// 扩展输出格式(通过容器配置 #out.formats)
container('#out.formats', [
    'xml' => function($response, $formats) {
        $response['headers']['Content-Type'] = 'application/xml';
        $response['body'] = xml_encode($response['body']);
        $formats['http']($response, $formats);
    },
]);
output($data, 'xml');

// 自定义渲染回调
container('#out.callback', function($response) {
    echo json_encode($response['body']);
});

// 基础路由
route('GET:/users', function($next) {
    output(['users' => []]);
});

// 带参数 (:param 或 {param})
route('GET:/user/:id', function() {
    $id = input('id', 'params');
    output(['id' => $id]);
});

// POST 路由
route('POST:/api/user', function() {
    $name = input('name', 'body');
    output(['created' => $name]);
});

// 路由映射数组
route([
    'get:/api/list' => function() { return 'list'; },
    'post:/api/create' => function() { return 'create'; },
]);

// 通配符路由
route('GET:/api/*', function() {
    // 匹配 /api 下的所有路径
});

// CLI 路由
route('cli:verbose', function() { /* ... */ });
route('cli:file=*', function() { /* ... */ });

// APCu 缓存
$result = cache('APCu', function() {
    return db('SELECT * FROM users');
});

// Redis 缓存
$result = cache('Redis', function() {
    return expensiveOperation();
});

// 带 TTL
$result = cache(['fn' => 'Redis', 'ttl' => 3600], function() {
    return $data;
});

// 组合缓存(按顺序尝试)
$result = cache('APCu', 'Redis', function() {
    return $data;
});

// 配置方式(通过容器 cache)
container('cache', [
    'user_list' => ['APCu', 1800],  // APCu, TTL 30分钟
    'api_data' => ['Redis', 3600, 'prefix_'],  // Redis, TTL 1小时, 自定义前缀
]);
$result = cache('user_list', function() {
    return db('SELECT * FROM users', [], 'list');
});

// 查询单行
$user = db('SELECT * FROM users WHERE id = ?', [1], 'row');

// 查询列表
$users = db('SELECT * FROM users', [], 'list');

// 查询单个值
$count = db('SELECT COUNT(*) FROM users', [], 'value');

// 查询单列(返回数组)
$names = db('SELECT name FROM users', [], 'column');

// 查询键值对
$pairs = db('SELECT id, name FROM users', [], 'pairs');

// 查询分组结果
$grouped = db('SELECT status, COUNT(*) FROM users GROUP BY status', [], 'group');

// 插入并获取ID
$id = db('INSERT INTO users (name) VALUES (?)', ['John'], 'id');

// 更新并获取影响行数
$count = db('UPDATE users SET name = ? WHERE id = ?', ['Jane', 1], 'count');

// 批量插入
db('INSERT INTO users (name) VALUES (?), (?)', [['John'], ['Jane']], 'ok');

// 执行模式(返回 PDOStatement)
$stmt = db('SELECT * FROM users', [], true);

// 自定义处理
$result = db('SELECT * FROM users', [], fn($stmt, $pdo) => $stmt->fetchAll());

// 开启事务
db('BEGIN');

// 提交事务
db('COMMIT');

// 回滚事务
db('ROLLBACK');

// 保存点
db('SAVEPOINT sp1');

// 回滚到保存点
db('ROLLBACK TO SAVEPOINT sp1');

container('db.default', [
    'dsn' => 'mysql:host=localhost;dbname=test',
    'username' => 'root',
    'password' => '',
    'options' => [],
]);

// 使用命名配置
$user = db('SELECT * FROM users WHERE id = ?', [1], 'row', 'default');

use nx\helpers\sql;

// 插入数据并获取ID
$id = db(sql::table('users')->insert(['name' => 'John', 'email' => '[email protected]']), 'id');

// 查询单行
$user = db(sql::table('users')->where(['id' => 1])->select(), 'row');

// 条件查询
$activeUsers = db(sql::table('users')->where(['status' => 1])->select(), 'list');

// 更新数据
$affected = db(sql::table('users')->where(['id' => 1])->update(['name' => 'Jane']), 'count');

// 删除数据
$affected = db(sql::table('users')->where(['id' => 1])->delete(), 'count');

// 直接比较
test('数字比较', 5, 5);

// 函数返回值
test('函数返回值', fn() => 2+2, 4);

// 断言函数
test('范围判断', 10, fn($v) => $v > 5);

// 数组验证
test('数组验证', ['a' => 1], function($value) {
    return isset($value['a']) && $value['a'] === 1;
});

// 函数作为待测值
test('函数返回值测试', fn() => 2+2, 4);

// 基础用法
$key = name('user.id');  // 返回 'user.id'

// 命名空间
container('name', ['cache' => ['user' => 'cache:user:{uid}']]);
$key = name('user', ['uid' => 123], 'cache');  // 返回 'cache:user:123'

// 基础用法(默认 level 为 info)
log('用户登录');

// 指定 level
log('发生错误', 'error');

// context 为字符串时作为 level
log('警告信息', 'warning');

// 使用 context 替换占位符 {key}
log('用户 {name} 登录', ['name' => 'admin']);

// 同时使用 context 和 level
log('错误: {msg}', ['msg' => '连接失败'], 'error');

// 非 string 消息自动 json
log(['a' => 1, 'b' => 2]);

// 支持 Stringable 对象
log(new StringableClass());

// 注入 PSR Logger
container('#log', $psrLogger);

// 注入闭包(fn 不会被容器自动执行)
container('#log.fn', fn($level, $message, $context) => ...);

middleware(cors(), auth(), log(), $handler);

container('#mw:auth:validators', [fn($user, $pass) => true]);
middleware(auth(), $handler);
// 获取用户: container('#mw:auth:user')

container('#mw:auth:validators', [fn($user, $pass) => $user]);
middleware(basic(), $handler);

container('#mw:auth:validators', [fn($token) => $user]);
middleware(token(), $handler);
middleware(token('#mw:auth', 'X-Auth-Token'), $handler);  // 自定义请求头

container('#mw:auth:secret', 'your-secret-key');
container('#mw:auth:validators', [fn($payload) => $user]);
middleware(jwt(), $handler);
// 获取 payload: container('#mw:auth:payload')

container('#mw:auth:validators', [fn($apiKey) => $user]);
middleware(apikey(), $handler);

middleware(cors(), $handler);
middleware(cors(['origin' => 'https://example.com']), $handler);

middleware(csrf(), $handler);          // 生成 token
middleware(csrf(verify: true), $handler); // 验证 token

middleware(error(debug: true), $handler);  // 开发环境
middleware(error(), $handler);             // 生产环境

middleware(gzip(), $handler);
middleware(gzip(9), $handler);   // 最高压缩级别

middleware(json(), $handler);
middleware(json(pretty: true), $handler);  // 格式化输出

middleware(log(), $handler);
middleware(log('warning'), $handler);

middleware(rate(), $handler);              // 60次/分钟
middleware(rate(100, 60), $handler);       // 100次/分钟
middleware(rate(30, 60, 'api'), $handler); // 自定义 key 前缀

container('#rate:storage', fn($key) => [...]);           // 读取
container('#rate:storage', fn($key, $value, $ttl) => 1); // 写入

middleware(serve('/var/www/public'), $handler);
// 扩展名映射(如将 .html 指向 index.php)
middleware(serve('/var/www/public', ['html' => 'index.php']), $handler);

container('#static:mimes', ['webp' => 'image/webp']);