【问题标题】:PHP - Session doesnt work on mobilePHP - 会话在移动设备上不起作用
【发布时间】:2017-10-28 10:02:04
【问题描述】:

对于使用session_start() 登录即时通讯,对于桌面它可以正常工作,但在移动设备上,它不起作用。当我使用变量创建session_id() 时,例如session_id('login') 它可以在移动设备上运行,但会中断其他计算机上的其他会话。但是当session_id() 自动生成时,它在移动设备上不起作用。我该怎么办?

我在 index.php 上的 session_start 代码

session_start();
if (isset($_SESSION['username'])){
    session_id();
}

login.php 文件的完整代码

<?php
require('config.php');
$usernameOK = false; $passwordOK = false;
if (isset($_POST['username']) and isset($_POST['password'])){

        $username = $_POST['username'];
        $password = $_POST['password'];

        $UserQuery = "SELECT username FROM `members` WHERE username='$username'";
        $userTestResult = mysqli_query($connection, $UserQuery);
        $usernameTEST = mysqli_num_rows($userTestResult);
        if($usernameTEST == 1){$usernameOK = true;}

        $PasswordQuery = "SELECT password FROM `members` WHERE username='$username'";
        $result = mysqli_query($connection,$PasswordQuery);
        $row = mysqli_fetch_row($result);

        if (password_verify($password, $row[0])){$passwordOK = true;}

        if($usernameOK == true && $passwordOK == true){
            $_SESSION['username'] = $username;
        }else{
            $error_message = "Incorrect login data";
        }
    }

    if (isset($_SESSION['username'])){
        header("Location: ../");
        exit;
    }else{?>
    <form class="login-form" method="POST">
        <?php if(isset($error_message)){ ?><div class="mini-mes error"> <?php echo $error_message; ?> </div><?php } ?>

        <span class="placeholder">username</span>
        <input type="text" name="username" placeholder="username" required>

        <span class="placeholder">password</span>
        <input type="password" name="password" id="inputPassword" placeholder="password" required>

        <button type="submit">Login</button>
        <a class="form-link" href="register.php">Register</a>
    </form>

<?php } ?>

【问题讨论】:

  • 您是否检查过您的移动设备中是否启用了 cookie?
  • @RicardoOrtegaMagaña 是的,我的移动设备上启用了 cookie
  • 你用的是什么浏览器?
  • @RicardoOrtegaMagaña 我正在使用 iPhone 和 Safari 浏览器,但 iPhone Chrome 也会发生这种情况
  • 在会话变量中设置数据后,您能否检查“重定向”是否与它生成的页面相同,例如:example.com 并且可能重定向看起来像example.com ,应该是一样的,看万维网

标签: php session session-variables


【解决方案1】:

不太确定你的代码做了什么,因为我没有看到任何关于设置用户名或任何类似的东西。您的代码所做的是,它启动会话并检查会话中的用户名变量是否已设置,如果是,则调用session_id

你能用它来检查会话是否创建正确吗?

session_start();
if (session_status() !== PHP_SESSION_NONE)
{
echo session_id();
}

如果 session_status 不是 PHP_SESSION_NONE,则启动会话并显示会话 ID

【讨论】:

  • 我测试了您的解决方案,但仍然无法正常工作,即使在 IE 11 上也是如此
  • 我的登录链接是 example.com/login.php,在提交重定向到 example.com 后未登录。类似会话未启动
  • 调用会话变量时是否报错?
  • 这是您看到的会话 ID,这意味着您正在运行一个会话 :)
  • 删除整个代码,以便我们解决问题。没有代码就帮不上什么忙了。
【解决方案2】:

您不需要执行 session_id() 来启动会话, session_start() 就足够了。

我在 iPhone 6 上的 Safari 上测试了以下内容(如果需要,只需添加 db 查询部分):

testa.php

<?php
//require('config.php');

session_start();
echo "Session ID: ".session_id()." <br>\n";

$usernameOK = false;
$passwordOK = false;

if (isset($_POST['username']) and isset($_POST['password'])) {

    $username = $_POST['username'];
    $password = $_POST['password'];

    $usernameOK = true;
    $passwordOK = true;

    if ($usernameOK == true && $passwordOK == true) {
        $_SESSION['username'] = $username;
    } else {
        $error_message = "Incorrect login data";
    }
}

if (isset($_SESSION['username'])) {
    header("Location: ../");
    exit;
} else {
?>
    <form class="login-form" method="POST">
        <?php if (isset($error_message)) { ?>
            <div class="mini-mes error"> <?php echo $error_message; ?> </div><?php } ?>

        <span class="placeholder">username</span>
        <input type="text" name="username" placeholder="username" required>

        <span class="placeholder">password</span>
        <input type="password" name="password" id="inputPassword" placeholder="password" required>

        <button type="submit">Login</button>
        <a class="form-link" href="register.php">Register</a>
    </form>
<?php } ?>

testb.php

<?php

session_start();
echo "Session ID: ".session_id()." <br>\n";
echo "Data stored in session: {$_SESSION['username']}<br>\n";
  1. 清除移动浏览器上的数据/cookies(或进入隐身模式)。这将确保您“从头开始”。

  2. 在您的移动浏览器上打开 testa.php。记下显示的会话 ID。输入您的登录详细信息,然后点击提交。下一页可能显示为空白。

  3. 打开 testb.php。再次注意显示的会话 ID。它应该等于 test1.php 中显示的会话 ID。如果它们不同,那么您的移动浏览器可能被配置为不接受 cookie。

我已经在 iPhone 6 上的 Safari 上亲自测试过,并且能够从会话中获取用户名数据。

PS。友情提醒:不要忘记转义您在查询中使用的数据(即 $username 和 $password)。使用mysqli_real_escape_string,或使用prepared statements。为了安全。

【讨论】:

  • 还是同样的问题,iPhone 没有启动会话。现在它显示一个错误 - Notice: A session had already been started - ignoring session_start()(我更新了我的帖子)
  • 这可能是因为您的 config.php 中已经有了 session_start()。此外,当您调用 session_id() 时,不要输入参数。我已经更新了我的帖子以包含有关查看您的浏览器是否接受/拒绝会话 cookie 的说明。
【解决方案3】:

也许您遇到了一些冲突问题:

我的 session_start 代码

if (isset($_SESSION['username'])){
    session_id();
} else if (!isset($_SESSION)){
   session_start();
}

login.php 文件的完整代码

<?php
require('config.php');
$usernameOK = false; $passwordOK = false;
if (isset($_POST['username']) and isset($_POST['password'])){

        $username = $_POST['username'];
        $password = $_POST['password'];

        $UserQuery = "SELECT username FROM `members` WHERE username='$username'";
        $userTestResult = mysqli_query($connection, $UserQuery);
        $usernameTEST = mysqli_num_rows($userTestResult);
        if($usernameTEST == 1){$usernameOK = true;}

        $PasswordQuery = "SELECT password FROM `members` WHERE username='$username'";
        $result = mysqli_query($connection,$PasswordQuery);
        $row = mysqli_fetch_row($result);

        if($usernameOK == true && password_verify($password, $row[0])){
            if (isset($_SESSION)){
               $_SESSION['username'] = $username;
            } else{
               session_start();
               $_SESSION['username'] = $username;
            }
        }else{
            $error_message = "Incorrect login data";
        }
    }

    if (isset($_SESSION['username'])){
        header("Location: ../");
        exit;
    }else{?>
    <form class="login-form" method="POST">
        <?php if(isset($error_message)){ ?><div class="mini-mes error"> <?php echo $error_message; ?> </div><?php } ?>

        <span class="placeholder">username</span>
        <input type="text" name="username" placeholder="username" required>

        <span class="placeholder">password</span>
        <input type="password" name="password" id="inputPassword" placeholder="password" required>

        <button type="submit">Login</button>
        <a class="form-link" href="register.php">Register</a>
    </form>

<?php } ?>

在第一行的 index.php 中我有 -> 删除它,放置第一个会话检查程序

if (!isset($_SESSION)){
   session_start();
}

编辑:我注意到您正在使用header 函数重定向到索引页面。除非您将用户发送出系统,否则避免此类重定向很重要,因为某些环境不适用于它们。我建议将您的例程更改为用户 POST/GET http 例程:

在 validateSession.php 中

在 validateSession 之外,与会话规则无关,将所有内容都集中在那里

index.php/head.php/一些总是在每个页面开始的代码只开始:

<?php 
include_once('validateSessions.php'); 
?>

你的表格:

<form class="login-form" action="index.php" method="POST"> 
<?php if(isset($error_message)){ ?><div class="mini-mes error"> <?php echo $error_message; ?> </div><?php } ?> 

<span class="placeholder">username</span> 
<input type="text" name="username" placeholder="username" required> 

<span class="placeholder">password</span> 
<input type="password" name="password" id="inputPassword" placeholder="password" required> 

<button type="submit">Login</button> 
<a class="form-link" href="register.php">Register</a> 
</form>

编辑:我查看了您的例程,注意 validateSessions.php,我忘记在每个调用该文件的例程中加载 session_start()。将 validateSessions 放入包含目录中。

更新:即使我的代码帮助了 OP,主要问题是使用 session.save_path 将 SESSION 配置到 php.ini 文件中,导致有关会话例程的问题。 php.ini 修复解决了这个问题,我希望代码可以帮助 OP 考虑一些针对 Session 的例程。

【讨论】:

  • 为此我的问题没有解决:(我不知道发生了什么
  • 在每个例程中添加一个回显,并跟踪您丢失会话的位置或即使它没有开始
  • 但为什么它不能在桌面和移动设备上启动?
  • 据我所知,移动端对会话的限制更多。顺便说一句,我强烈建议您设置观察点(使用 echoes/var_dumps 和 die/exits)来检查您的会话是否正在开始,至少。如果不是,那是您的环境有问题。
  • 在 index.php 上它不会在移动设备上返回 $_SESSION['username'],但在桌面返回
【解决方案4】:

可能您的会话未设置。根据您使用的 PHP 版本,检查您的会话。

对于 PHP >= 5.4.0

的版本
if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

对于 PHP 版本

if(session_id() == '') {
    session_start();
}

【讨论】:

  • 你把 session_start() 放在哪里了?
  • @aljof 我的 session_start 在 index.php 第一行
【解决方案5】:

Cookies 绝对适用于移动浏览器。

【讨论】:

  • 是的,但手机不检查会话
【解决方案6】:

我已经简化了代码,并在所有检查都通过后开始会话。

<?php
require('config.php');
if (isset($_POST['username']) and isset($_POST['password'])){

    $username = $_POST['username'];
    $password = $_POST['password'];

    $UserQuery = "SELECT password FROM `members` WHERE username='$username'";
    $result = mysqli_query($connection, $UserQuery);
    $usernameTEST = mysqli_num_rows($result);
    if($usernameTEST == 1){
        $row = mysqli_fetch_row($result);
        if(password_verify($password, $row[0])) {
            session_start();
            $_SESSION['username'] = $username;
            header("Location: ../");
            exit();
        }
    }

    $error_message = "Incorrect login data";
}

<form class="login-form" method="POST">
    <?php if(isset($error_message)){ ?><div class="mini-mes error"> <?php echo $error_message; ?> </div><?php } ?>

    <span class="placeholder">username</span>
    <input type="text" name="username" placeholder="username" required>

    <span class="placeholder">password</span>
    <input type="password" name="password" id="inputPassword" placeholder="password" required>

    <button type="submit">Login</button>
    <a class="form-link" href="register.php">Register</a>
</form>

【讨论】:

  • 仍然是同样的问题,当我登录时,它重定向到 index.php 并且没有任何反应
  • 只有三行。哪个部分不工作? session_id 返回一个值,你必须使用echo session_id();
  • 我不知道,在桌面上一切正常,但问题出在移动设备上。 session_id 返回一个值
  • 你必须使用 echo
【解决方案7】:

简化代码以使其更易于理解。忽略对用户名和密码等的检查。您基本上是在尝试设置会话变量。这发生在 login.php 中。代码是。

 <?php
 $username = "Umesh";
 if (isset($_SESSION))
 {
      $_SESSION['username'] = $username;
 }
 else
 {
           session_start();
           $_SESSION['username'] = $username;
 }
 print_r($_SESSION);
?>

在 index.php 中,您尝试检查会话状态。代码如下。

 if (isset($_SESSION['username'])){
session_id();
} else if (!isset($_SESSION)){
    session_start();
}
print_r($_SESSION);

以上内容适用于所有浏览器和设备。我什至在 iphone 上测试了 chrome。它似乎工作正常。请检查一下,看看它是否有效。如果没有,我们将不得不检查您的网络服务器,以查看该系统上的会话对象存在什么问题。

我验证了 print_r ($_SESSION) 在两种情况下都是相同的。

【讨论】:

【解决方案8】:

为什么使用 session_id()。 session 我总是使用这个登录系统。我的桌面或移动会话没有问题。

PHP 代码

&lt;?php
session_start();
include 'connect.php'; 

if(isset($_POST['submit']))
{
  $username = htmlspecialchars($_POST["uname"], ENT_QUOTES, "ISO-8859-1");
  $username = stripslashes($username);
  $password = htmlspecialchars($_POST["pass"], ENT_QUOTES, "ISO-8859-1");
  $password = stripslashes($password);

  $sql="SELECT * FROM member WHERE username= '$username' AND password='$password' AND status='1' ";
  $result=mysql_db_query($dbname,$sql);
  $row=mysql_fetch_row($result);
  $num=mysql_num_rows($result);
  $msg= "<h3 style='padding:0px;margin:0px;font-size:16px;background:#fff;padding:8px;'><font color='red'><center>Incorrect login data</center></font></h3>";

  if($num>0)
  {
    $_SESSION['id']       =$row[0];
    $_SESSION['fullName'] =$row[1];
    $_SESSION['username'] =$row[2];
    $_SESSION['password'] =$row[3];
    $_SESSION['email']    =$row[4];
    $_SESSION['userType'] =$row[5];
    $_SESSION['status']   =$row[6];
    header('location:index.php');
  }
}
?>

我的 HTML 表单

忘记了?

【讨论】:

    【解决方案9】:

    移除 session_start();在 index.php 中 并将其添加到您的 config.php 中

    if (session_status() == PHP_SESSION_NONE) 
    {
        session_start();
    }
    

    【讨论】:

    • 还是和以前一样的问题
    【解决方案10】:

    根据您的最后一条评论,我想这是由于您使用的查询字符串。基本上使用password 作为列名有时会破坏查询,因为password 也是一个mysql 关键字。 此外,关于您的会话,您可以参考session_id() vs session_regenerate_id() 了解有关功能的更多详细信息。 Session_id('login') 基本上将会话 ID 设置为登录,这可以在您的移动设备上使用,因为这会创建具有特定静态 ID 的会话。不过,您可以尝试使用session_regenerate_id(true) 看看是否有帮助。

    我也尝试通过将静态值作为用户名来执行代码,如下所示

    login.php

     <?php
        $username = "deadlock";
        if (isset($_SESSION))
        {
            $_SESSION['username'] = $username;
        }
        else
        {
            session_start();
            $_SESSION['username'] = $username;
        }
         print_r($_SESSION);
    

    index.php

    <?php
    if (isset($_SESSION['username'])){
        session_regenerate_id(true);
    } else if (!isset($_SESSION)){
        session_start();
    }
    print_r(session_id());
    

    我开始使用 index.php 直接使用手机打印输出为array() 没有值。结果是 Login.php 文件没有执行。在我明确执行后 Login.php index.php 打印会话数组。您能否确保正确执行登录 php 文件。 问候

    【讨论】:

      【解决方案11】:

      检查 session_start() 是否放置在任何浏览器输出之前。我发现桌面版 Chrome 比其他浏览器和移动版 Chrome 更宽容

      【讨论】:

        【解决方案12】:

        Chrome“精简模式”会产生此问题,以减少手机的数据负载。如果您使用秘密导航,那么精简模式会自动禁用页面正常工作。您必须在 Chrome 上禁用“精简模式”。 这是最终的解决方案。

        【讨论】:

          【解决方案13】:

          我的问题是在服务器端 session.save_path 未定义到我的服务器。非常感谢所有帮助过我的人:)

          【讨论】:

          • 这如何解释它在桌面而不是移动设备上工作?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-01-12
          • 2014-04-22
          • 1970-01-01
          • 2017-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多