简体   繁体   中英

error with sessions variables at google app engine (php)

Every time i deploy an app to google app engine i have the same problem: my session vars disapear when going from a page to another in the same web site. I dont have this issue when runing my app at my localhost, so i belive it is becouse of a wrong GAE configuration (im new at GAE).

i will show here one of my proyects:

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: \1
  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>

in my localhost, when i run this proyect, it works as expected: the front controller at index, redirects to first.php. first.php creates the sessions vars and it redirects to second.php. Finally second.php prints the values from the sesion vars.

However, when i deploy the same proyect to GAE, it shows the secon.php page without the session vars: image of second.php at GAE

PD: i just deploy the proyect at google app engine with no database instance.

I tested your files in local and in GAE and saw the same result you did, works on local, not GAE deployed. Your yaml file is fine but your php files should include session_start() at the top, before any html even <!DOCTYPE html> As @NoCommandLine mentioned.

I couldn't find any exact official documentation stating why it should be on top but it is well known by the community that best practice dictates it be this way, this fellow shared more detailed insight that I wasn't able to find anywhere else.

This is the error that was being sent in the backend for the app: ...session_start(): Cannot start session when headers already sent in... . To view logs and events in your app please look at the documentation for the log explorer. This tool can help you identify errors and warnings such as these to properly debug your code.

Here are the snippets you sent over with proper use of session_start() :

index.php

I made a slight adjustment and went ahead and added session_start() here as well, inside the if condition to determine if header were already sent or if a session id is empty

<?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>

With these files you should be able to perform your testing properly. On that same note, I suggest you eventually look into a PHP framework that can help you with these simple for each file. Here is more information on PHP frameworks.

Happy Coding!

I believe session_start() should appear at the top of your files (before any data is output) ie try putting it before <!DOCTYPE html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM