【问题标题】:Can't logout in PHP [duplicate]无法在PHP中注销[重复]
【发布时间】:2019-03-11 05:21:54
【问题描述】:

我正在尝试在 PHP 中创建一个注册/登录表单,但我无法退出。我不断收到以下错误。

致命错误:未捕获的 ArgumentCountError:函数 USER::__construct() 的参数太少,在第 4 行的 C:\xampp\htdocs\recepten\logout.php 中传递了 0,而在 C:\xampp\htdocs 中恰好需要 1 \recepten\class.user.php:6 堆栈跟踪:#0 C:\xampp\htdocs\recepten\logout.php(4): USER->__construct() #1 {main} 在 C:\xampp\htdocs 中抛出\recepten\class.user.php 在第 6 行

有人可以告诉我我在做什么以及如何解决问题吗?

这是我的注销脚本代码行:

<?php
session_start();
require_once 'class.user.php';
$user = new USER();

if(!$user->is_logged_in())
{
    $user->redirect('indexlogin.php');
}

if($user->is_logged_in()!="")
{
    $user->logout(); 
    $user->redirect('indexlogin.php');
}
?>

这是我的呼叫用户脚本代码:

<?php
class USER
{
    private $db;

    function __construct($DB_con)
    {
        $this->db = $DB_con;
    }

    public function register($fname,$lname,$uname,$umail,$upass)
    {
       try
       {
           $new_password = password_hash($upass, PASSWORD_DEFAULT);

           $stmt = $this->db->prepare("INSERT INTO users(user_name,user_email,user_pass) 
                                                       VALUES(:uname, :umail, :upass)");

           $stmt->bindparam(":uname", $uname);
           $stmt->bindparam(":umail", $umail);
           $stmt->bindparam(":upass", $new_password);            
           $stmt->execute(); 

           return $stmt; 
       }
       catch(PDOException $e)
       {
           echo $e->getMessage();
       }    
    }

    public function login($uname,$umail,$upass)
    {
       try
       {
          $stmt = $this->db->prepare("SELECT * FROM users WHERE user_name=:uname OR user_email=:umail LIMIT 1");
          $stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
          $userRow=$stmt->fetch(PDO::FETCH_ASSOC);
          if($stmt->rowCount() > 0)
          {
             if(password_verify($upass, $userRow['user_pass']))
             {
                $_SESSION['user_session'] = $userRow['user_id'];
                return true;
             }
             else
             {
                return false;
             }
          }
       }
       catch(PDOException $e)
       {
           echo $e->getMessage();
       }
   }

   public function is_loggedin()
   {
      if(isset($_SESSION['user_session']))
      {
         return true;
      }
   }

   public function redirect($url)
   {
       header("Location: $url");
   }

  public function logout()
  {
      session_destroy();
      $_SESSION['user_session'] = true;
  }
}
?>

如果有人能帮忙就好了!

【问题讨论】:

  • function __construct($DB_con)$user = new USER();
  • 以上是问题所在,但使用干净安全的注册/登录系统值得称赞。这出奇的罕见:)
  • 那个注销功能太可怕了。调用 session_destroy 后无法写入会话。
  • 您没有将数据库连接传递给 USER。
  • @jacob kuh-chan 表示问题出在这些行中,而不是复制粘贴文本。

标签: php mysql pdo


【解决方案1】:

class.user.php 你有一个:

function __construct($DB_con)
{
  $this->db = $DB_con;
}

当你在logout.php中使用它时:

$user = new USER();

您必须将$DB_con 传递给__constructor,或者创建一个没有参数的__constructor,然后添加另一个函数来初始化DB

function __construct()
{
} 
public function initDB($DB_con)
{
  $this->db = $DB_con;
}

然后你可以这样使用它:

$YourDB = whatever_get_DB();
$user = new USER();
// And when you need:
$user.initDB($YourDB);

或者没有这个:

$YourDB = whatever_get_DB();
$user = new USER($YourDB);

【讨论】:

  • 我确实尝试添加另一个函数,现在我在 call.user.php 上没有错误消息,但只有在 Logout.php 上。这给了我以下错误:致命错误:未捕获的错误:调用 C:\xampp\htdocs\recepten\logout.php:6 中未定义的方法 USER::is_logged_in() 堆栈跟踪:#0 {main} 在 C 中抛出: \xampp\htdocs\recepten\logout.php 在第 6 行
  • @jacob 你的函数定义的不是is_logged_in,而是is_loggedin,在第6行和第11行更改class.user.phplogout.php中的名称。
  • 谢谢,但我在尝试登录时遇到以下问题,当注销终于奏效时。注意:未定义变量:第 46 行 C:\xampp\htdocs\recepten\Sign_up.php 中的 fname 注意:未定义变量:第 46 行 C:\xampp\htdocs\recepten\Sign_up.php 中的 lname 致命错误:未捕获错误:在 C:\xampp\htdocs\recepten\class.user.php:20 中的 null 上调用成员函数 prepare() 堆栈跟踪:#0 C:\xampp\htdocs\recepten\Sign_up.php(46): USER- >register(NULL, NULL, 'johan22', 'johan@live.nl', 'joohaann') #1 {main} 在第 20 行的 C:\xampp\htdocs\recepten\class.user.php 中抛出
  • 错误信息清楚地描述了它:1.您在第46行的sign_up.php中使用了未定义的变量fnamelname。2.您的$this-&gt;db为NULL,这意味着您没有'不要将数据库传递给构造函数或initDB,您需要先初始化数据库。这就是为什么它说 NULL 没有prepare 功能。
【解决方案2】:

您必须将数据库连接传递给 USER 构造函数。

【讨论】:

  • 更准确地说是一个 PDO 数据库连接。
  • 在构造函数中没有 typehint 它可以是任何使用类似 api 作为 PDO 并在某些情况下抛出 PDOException 的东西?
  • 即使类型提示假设它扩展它,情况也是如此。
  • 如果它长得像鸭子,走路像鸭子,叫起来像鸭子...en.wikipedia.org/wiki/Duck_typing
  • 是的,在这个意义上duck是db连接器,但是我们不能说它的Pdo连接器还是没有typehint的MyCustomDb连接器
【解决方案3】:

抛出的错误非常清楚。您的构造函数中缺少一个参数,预期 1 有 0 个参数。

所以,基本上当您实例化一个类new ClassName() 时,构造函数参数放在括号中。

//               v Arguments of the constructor goes here 
$user = new USER( );

在您的情况下,您缺少类构造函数所需的参数($DB)

【讨论】:

  • 是的,我尝试填写缺少的参数,但是在登录或注册时不断出现此错误。致命错误:未捕获的错误:在 C:\xampp\htdocs\recepten\class.user.php:40 中调用成员函数 prepare() 堆栈跟踪:#0 C:\xampp\htdocs\recepten\indexlogin.php (15): USER->login('johan22', 'johan22', 'johan12345') #1 {main} 在 C:\xampp\htdocs\recepten\class.user.php 第 40 行抛出
  • @jacob 你传递给构造函数的参数是空的......也许你没有连接到数据库......你的$DB是什么样的,你传递给构造函数的$DB跨度>
  • setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { echo $e->getMessage(); } include_once 'class.user.php'; $user = new USER($DB_con);
  • @jacob 看来您的连接语法很好。您可以在构造函数中开始调试。你能在那里做一个print_r($this-&gt;db); 并检查它是否不为空
猜你喜欢
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 2013-06-18
  • 2013-07-15
  • 2014-10-17
  • 2012-01-21
  • 2018-02-21
相关资源
最近更新 更多