PHP code example of kode / context

1. Go to this page and download the library: Download kode/context 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/ */

    

kode / context example snippets


use Kode\Context\Context;

// 设置上下文值
Context::set('user', $user);

// 获取上下文值
$request = Context::get('request');

// 判断是否存在
if (Context::has('trace_id')) { ... }

// 删除键
Context::delete('tmp_data');

// 复制当前上下文快照
$ctx = Context::copy();

// 在新上下文中运行闭包(不影响父上下文)
Context::run(fn() => {
    Context::set('temp', 'value');
    // ...
}); // 自动恢复原始上下文

// 继承当前上下文运行闭包
Context::fork(fn() => {
    // 可以访问外部上下文
    $user = Context::get('user');
    Context::set('temp', 'value'); // 不影响外部
});

// 清空当前上下文
Context::clear();

use Kode\Context\Context;

// 设置一些上下文数据
Context::set('user_id', 123);
Context::set('trace_id', uniqid('trace_'));

// 在任意深度获取
function getCurrentUser() {
    return UserService::find(Context::get('user_id'));
}

// 输出 trace_id
echo Context::get('trace_id'); // e.g., trace_abc123

Context::set('role', 'admin');

Context::run(function () {
    Context::set('role', 'guest'); // 不影响外部
    echo Context::get('role'); // "guest"
});

echo Context::get('role'); // 仍然是 "admin"

Context::set('user_id', 123);

Context::fork(function () {
    // 可以访问外部上下文
    echo Context::get('user_id'); // 123
    
    // 修改不影响外部
    Context::set('user_id', 456);
});

echo Context::get('user_id'); // 仍然是 123

$http->on('request', function ($req, $resp) {
    Context::set('request', $req);
    Context::set('response', $resp);
    Context::set('trace_id', generateTraceId());

    try {
        $handler->handle(); // 在业务逻辑中可随时通过 Context::get() 获取
    } catch (\Throwable $e) {
        Log::error($e->getMessage(), ['trace_id' => Context::get('trace_id')]);
        $resp->end('Server Error');
    }
});

use Kode\Context\Context;

// 设置父进程上下文
Context::set('user_id', 123);
Context::set('trace_id', 'abc-123');

// 准备 fork
Context::prepareFork();

$pid = pcntl_fork();

if ($pid === 0) {
    // 子进程:继承父进程上下文
    Context::afterFork(true);
    
    echo Context::get('user_id'); // 123
    echo Context::get('trace_id'); // 'abc-123'
    
    // 子进程的修改不影响父进程
    Context::set('user_id', 456);
    
    exit(0);
} else {
    // 父进程
    pcntl_wait($status);
    
    echo Context::get('user_id'); // 仍然是 123
}

use Kode\Context\Context;

// 设置共享上下文
Context::set('config', $config);

// 定义任务
$tasks = [
    'task1' => fn() => processUserData($users1),
    'task2' => fn() => processUserData($users2),
    'task3' => fn() => generateReport($data),
];

// 并行执行(最大 4 个进程)
$results = Context::parallelProcesses($tasks, maxProcesses: 4, inheritContext: true);

// 获取结果
print_r($results['task1']);
print_r($results['task2']);
print_r($results['task3']);

// parallelProcesses 自动处理进程间通信
$results = Context::parallelProcesses([
    'heavy_task' => fn() => [
        'status' => 'success',
        'data' => $computedData,
    ],
]);

use Kode\Context\Context;

if (Context::isThread()) {
    echo "运行在多线程环境中";
}

$threadId = Context::getThreadId();

use Kode\Context\Context;

// 设置共享上下文
Context::set('shared_data', $data);

// 在新线程中运行(继承上下文)
$thread = Context::runInThread(function () {
    // 可以访问共享上下文
    $data = Context::get('shared_data');
    return processInThread($data);
}, inheritContext: true);

// 等待结果(pthreads)
$thread->join();
$result = $thread->result;

// 或 parallel 扩展
// $result = $thread->value();

use Kode\Context\Context;

$tasks = [
    'task1' => fn() => computeTask1(),
    'task2' => fn() => computeTask2(),
    'task3' => fn() => computeTask3(),
];

// 并行执行(最大 4 个线程)
$results = Context::parallelThreads($tasks, maxThreads: 4, inheritContext: true);

use Kode\Context\Context;

// 在入口处启动追踪
$traceId = Context::startTrace(null, 'node-1');

// 获取追踪信息
$traceInfo = Context::getTraceInfo();
// ['trace_id' => '...', 'span_id' => '...', 'parent_span_id' => null, 'node_id' => 'node-1']

// 创建子 Span
$spanId = Context::startSpan();

// 序列化为 JSON(用于跨节点传递)
$json = Context::toJson();
// 或仅序列化分布式追踪相关的键
$json = Context::toJson(Context::getDistributedKeys());

// 从 JSON 反序列化
Context::fromJson($json);        // 替换当前上下文
Context::fromJson($json, true);  // 合并到当前上下文

// 导出为 HTTP Headers(用于 HTTP 客户端请求)
$headers = Context::toHeaders();
// ['X-Context-Trace-Id' => '...', 'X-Context-Span-Id' => '...', ...]

// 在服务端从 Headers 导入
Context::fromHeaders($request->headers->all());

// === 节点 A(调用方) ===
Context::startTrace(null, 'node-a');
Context::set('user_id', 123);

// 准备跨节点调用
$headers = Context::toHeaders();
$response = $httpClient->post('http://node-b/api', [
    'headers' => $headers,
    'json' => ['data' => '...']
]);

// === 节点 B(被调用方) ===
// 从请求中恢复上下文
Context::fromHeaders($request->headers->all());

// 现在可以访问追踪信息
$traceId = Context::get(Context::TRACE_ID);
$sourceNode = Context::get(Context::NODE_ID); // 'node-a'

// 创建子 Span
Context::startSpan();

// 业务逻辑...

use Kode\Context\Context;
use Kode\Fibers\Fibers;

// 设置分布式追踪上下文
Context::startTrace(null, 'node-1');

// 使用 Fibers 进行分布式任务调度
$result = Fibers::scheduleDistributedRemote(
    ['task1' => fn() => doWork()],
    ['node-2' => ['weight' => 1]],
    new HttpNodeTransport() // 自定义传输实现
);

// 运行时类型
Context::RUNTIME_FIBER    // 'fiber'
Context::RUNTIME_SWOOLE   // 'swoole'
Context::RUNTIME_SWOW     // 'swow'
Context::RUNTIME_THREAD   // 'thread'
Context::RUNTIME_PROCESS  // 'process'
Context::RUNTIME_SYNC     // 'sync'

// 分布式追踪键
Context::TRACE_ID         // 'trace_id'
Context::SPAN_ID          // 'span_id'
Context::PARENT_SPAN_ID   // 'parent_span_id'
Context::NODE_ID          // 'node_id'
Context::SOURCE_NODE_ID   // 'source_node_id'
Context::REQUEST_ID       // 'request_id'
Context::CORRELATION_ID   // 'correlation_id'

// 进程/线程键
Context::PROCESS_ID       // 'process_id'
Context::THREAD_ID        // 'thread_id'
Context::PARENT_PROCESS_ID // 'parent_process_id'