google 应用引擎 (php) 的会话变量错误

error with sessions variables at google app engine (php)

每次我将应用程序部署到 google 应用程序引擎时,我都会遇到同样的问题:在同一网站中从一个页面转到另一个页面时,我的会话变量会消失。 运行 在我的本地主机上运行我的应用程序时我没有这个问题,所以我相信这是因为错误的 GAE 配置(我是 GAE 的新手)。

我将在这里展示我的一个项目:

app.yaml:

runtime: php73

# Defaults to "serve index.php" and "serve public/index.php". Can be used to
# serve a custom PHP front controller (e.g. "serve backend/index.php") or to
# run a long-running PHP script as a worker process (e.g. "php worker.php").
#
# Serve your app through a front controller at index.php or public/index.php.
runtime_config:
  document_root: .

handlers:
# Serve images as static resources.
- url: /(.+\.(gif|png|jpg|css|js|map|PNG|svg))$
  static_files: 
  upload: .+\.(gif|png|jpg|css|js|map|PNG|svg)$

- url: /.*
  script: auto

index.php:

<?php
ini_set('allow_url_fopen',1);
switch (@parse_url($_SERVER['REQUEST_URI'])['path']) {
    case '/':
        require 'first.php';
        break;
    case '/first.php':
        require 'first.php';
        break;
    case '/first':
        require 'first.php';
        break;
    case '/second.php':
        require 'second.php';
        break;
        case '/second':
            require 'second.php';
            break;
    default:
        require 'first.php';
        break;
}
 ?>

first.php:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>fisrt</title>
  </head>
  <body>
    <h1>first</h1>
    <?php
      session_start();
      $_SESSION['id'] = 123;
      $_SESSION['nombre'] = 'franc';
     ?>
     <script>
        window.location.href="second.php";
     </script>
  </body>
</html>

second.php:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Second</title>
  </head>
  <body>
    <h1>Second</h1>
    <?php
      session_start();
      echo $_SESSION['id'];
      echo $_SESSION['nombre'];
     ?>
  </body>
</html>

在我的本地主机中,当我 运行 这个项目时,它按预期工作:索引处的前端控制器重定向到 first.php。 first.php 创建会话变量并将其重定向到 second.php。最后 second.php 打印来自会话变量的值。

但是,当我将相同的项目部署到 GAE 时,它显示 secon.php 页面但没有会话变量: image of second.php at GAE

PD:我只是在没有数据库实例的 google 应用引擎上部署了项目。

我相信 session_start() 应该出现在文件的顶部(在输出任何数据之前),即尝试将其放在 <!DOCTYPE html>

之前

我在本地和 GAE 中测试了您的文件,看到了与您所做的相同的结果,适用于本地,而不是部署的 GAE。您的 yaml 文件很好,但是您的 php 文件应该在顶部包含 session_start(),在任何 html 甚至 <!DOCTYPE html> 之前,正如@NoCommandLine 提到的。

我找不到任何确切的官方文档来说明为什么它应该放在首位,但社区众所周知,最佳实践要求这样,this 其他人分享了我更详细的见解找不到其他地方。

这是在应用后端发送的错误:...session_start(): Cannot start session when headers already sent in...。 要在您的应用程序中查看日志和事件,请查看日志浏览器的 documentation。此工具可以帮助您识别此类错误和警告,以正确调试您的代码。

以下是您正确使用 session_start() 发送过来的片段:

index.php

我稍作调整并继续在此处添加 session_start(),在 if 条件内以确定 header 是否已发送或 session id 是否为空

<?php
ini_set('allow_url_fopen',1);

if( !headers_sent() && '' == session_id() ) {
session_start();
}

switch (@parse_url($_SERVER['REQUEST_URI'])['path']) {
    case '/':
        require 'first.php';
        break;
    case '/first.php':
        require 'first.php';
        break;
    case '/first':
        require 'first.php';
        break;
    case '/second.php':
        require 'second.php';
        break;
        case '/second':
            require 'second.php';
            break;
    default:
        require 'first.php';
        break;
}
 ?>

first.php

<?php
session_start();
?>

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>fisrt</title>
  </head>
  <body>
    <h1>first 1</h1>
    <?php

      $_SESSION['id'] = 123;
      $_SESSION['nombre'] = 'franc';
     ?>
     <script>
        window.location.href="second.php";
     </script>
  </body>
</html>

second.php

<?php
session_start();
?>

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Second</title>
  </head>
  <body>
    <h1>Second 1</h1>
    <?php

      echo $_SESSION['id'];
      echo $_SESSION['nombre'];
     ?>
  </body>
</html>

使用这些文件,您应该能够正确执行测试。同样,我建议您最终研究一个 PHP 框架,它可以帮助您对每个文件进行简单处理。 Here 是关于 PHP 框架的更多信息。

编码愉快!