
当使用本地域名(如 local.mydev.com)访问 php 应用时,`session_start()` 无法恢复已有会话,导致 `$_session` 为空、`session_id()` 每次刷新都变化——这通常由跨域 cookie 冲突引起,而非配置错误。
在本地开发中,通过 IP 地址(如 http://192.168.33.10/)访问时会话正常,但切换到自定义域名(如 http://local.mydev.com/)后会话失效,是一个典型且易被忽视的 Cookie 作用域问题。
根本原因在于:浏览器将 Cookie 的 Domain 属性按“公共后缀规则”自动扩展。例如,当你访问 local.myCompanyWebsite.com,而生产环境同时存在 myCompanyWebsite.com(如 https://myCompanyWebsite.com),PHP 默认设置 session.cookie_domain = "" 时,浏览器会将 PHPSESSID Cookie 的 Domain 自动设为 .myCompanyWebsite.com(注意开头的点),使其对所有子域(包括 local.myCompanyWebsite.com)生效。此时若生产站点已写入同名 Cookie,两个域名会共享同一 PHPSESSID,但 session 文件路径或存储上下文不同,导致 session_start() 无法正确加载对应会话数据——表现为 ID 不变但 $_SESSION 为空,或 ID 被覆盖为新值。
你通过隐身窗口验证成功,正是因为它隔离了原有 Cookie 上下文;修改 hosts 中的域名(如改用 local-dev.mycompany.test)也有效,因其彻底规避了与主域的 Cookie 域匹配。
✅ 推荐解决方案(按优先级排序):
立即学习“PHP免费学习笔记(深入)”;
-
显式设置 session.cookie_domain(最稳妥)
在 stest1.php 和 stest2.php 开头(session_start() 之前)强制指定 Cookie 作用域:⚠️ 注意:.local.mydev.com 表示匹配 local.mydev.com 及其所有子域;local.mydev.com(无点)则严格匹配该主机名,更安全,避免意外共享。
-
使用符合公共后缀规范的本地测试域名
避免与真实生产域名存在父子关系。推荐使用:- myapp.test(IANA 官方保留域名,推荐)
- myapp.localhost
- myapp.docker.internal(容器环境)
并在 hosts 中配置:192.168.33.10 myapp.test
-
开发环境独立 Cookie 前缀(进阶)
若需多环境共存,可动态设置 session.name,使不同域名使用不同 Cookie 名:$domain = $_SERVER['HTTP_HOST'] ?? ''; if (strpos($domain, 'local.') === 0 || strpos($domain, 'dev.') === 0) { ini_set('session.name', 'DEVSESSID'); } session_start();
? 关键检查项:
- 使用 Chrome DevTools → Application → Cookies,确认 PHPSESSID 的 Domain 列是否为 .myCompanyWebsite.com(泄露信号);
- phpinfo() 中核对 session.cookie_domain 是否仍为 no value;
- 确保 session.use_only_cookies = 1(默认开启),禁用 URL 传递 SID,防止混淆。
总结:这不是 Apache 或 VirtualBox 的配置缺陷,而是浏览器 Cookie 同源策略与 PHP 默认宽松域设置共同作用的结果。明确控制 session.cookie_domain 是本地多域名开发的必备实践——它让会话行为可预测、可隔离,从根本上杜绝生产与开发环境的 Cookie 干扰。











