本文目录导读:

在 PHP 中,请求上下文的共享有几种方式,让我详细说明:
超全局变量(最常用)
$_GET, $_POST, $_REQUEST
// 请求参数共享
function getUserInput() {
// 可以在任何函数中访问
return $_POST['username'] ?? $_GET['username'] ?? '';
}
$_SESSION - 会话级共享
// 设置
session_start();
$_SESSION['user_id'] = 123;
// 在其他请求中读取
function getCurrentUser() {
session_start();
return $_SESSION['user_id'] ?? null;
}
$_COOKIE - Cookie 共享
// 设置 Cookie
setcookie('theme', 'dark', time() + 3600);
// 读取
$theme = $_COOKIE['theme'] ?? 'light';
全局变量(谨慎使用)
// 使用 global 关键字
$appContext = [];
function setContext($key, $value) {
global $appContext;
$appContext[$key] = $value;
}
function getContext($key) {
global $appContext;
return $appContext[$key] ?? null;
}
静态属性(推荐方式)
class Context {
private static array $data = [];
private static ?User $currentUser = null;
public static function set($key, $value) {
self::$data[$key] = $value;
}
public static function get($key) {
return self::$data[$key] ?? null;
}
public static function setUser(User $user) {
self::$currentUser = $user;
}
public static function getUser(): ?User {
return self::$currentUser;
}
}
// 使用
Context::setUser($user);
Context::set('request_id', uniqid());
依赖注入容器(框架实现)
// 简单容器实现
class Container {
private array $instances = [];
public function set($key, $instance) {
$this->instances[$key] = $instance;
}
public function get($key) {
return $this->instances[$key] ?? null;
}
}
// 初始化
$container = new Container();
$container->set('db', new PDO(...));
$container->set('logger', new Logger());
// 通过构造函数注入
class UserService {
private Container $container;
public function __construct(Container $container) {
$this->container = $container;
}
public function getDb() {
return $this->container->get('db');
}
}
使用单例模式
class AppContext {
private static ?self $instance = null;
private array $data = [];
private function __construct() {}
public static function getInstance(): self {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function set($key, $value) {
$this->data[$key] = $value;
}
public function get($key) {
return $this->data[$key] ?? null;
}
}
// 使用
$context = AppContext::getInstance();
$context->set('request_time', microtime(true));
文件或 Redis 缓存(跨请求)
// Redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->set('user_' . $userId, json_encode($userData), 3600);
$user = json_decode($redis->get('user_' . $userId), true);
// 文件
$cacheFile = '/tmp/cache_' . $userId . '.json';
file_put_contents($cacheFile, json_encode($userData));
$user = json_decode(file_get_contents($cacheFile), true);
最佳实践建议
class RequestContext {
private static array $context = [];
// 初始化请求上下文
public static function init(array $config = []) {
self::$context = [
'request_id' => uniqid(),
'start_time' => microtime(true),
'ip' => $_SERVER['REMOTE_ADDR'] ?? '',
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'config' => $config,
];
}
public static function set($key, $value) {
self::$context[$key] = $value;
}
public static function get($key, $default = null) {
return self::$context[$key] ?? $default;
}
public static function all() {
return self::$context;
}
}
// 入口文件初始化
RequestContext::init(['debug' => true]);
RequestContext::set('user_id', 123);
// 业务代码中使用
function processRequest() {
$requestId = RequestContext::get('request_id');
$userId = RequestContext::get('user_id');
// 处理逻辑...
}
注意事项
- FPM 模式下:每个请求是独立的进程,全局变量不会跨请求共享
- 避免过度使用全局状态:会增加代码耦合度
- 使用框架:如 Laravel 的
Request门面、服务容器等 - 考虑线程安全:在使用共享数据时要注意并发问题
- 清理资源:请求结束后及时清理临时数据
选择哪种方式取决于你的具体场景和项目架构,对于小项目,超全局变量和静态属性就足够了;对于大型项目,建议使用依赖注入容器。