【问题标题】:Fatal error on prepared statement准备好的语句上的致命错误
【发布时间】:2013-10-07 07:50:21
【问题描述】:

更新...

我正在编写准备好的语句,但收到以下错误消息:

注意:未定义索引:第 34 行 C:\Program Files (x86)\EasyPHP-12.1\www\inlogg_och_lagar\core.inc.php 中的用户名

致命错误:未捕获异常 'PDOException' 并带有消息 'SQLSTATE[42000]:语法错误或访问冲突:1064 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册以获取正确的语法,以便在 C:\Program Files (x86)\EasyPHP-12.1\www\inlogg_och_lagar\core.inc.php:34 中的第 1 行的 ''' 附近使用跟踪:#0 C:\Program Files (x86)\EasyPHP-12.1\www\inlogg_och_lagar\core.inc.php(34): PDOStatement->execute(Array) #1 C:\Program Files (x86)\EasyPHP- 12.1\www\inlogg_och_lagar\index.php(23): getuserrow('username') #2 {main} 抛出 C:\Program Files (x86)\EasyPHP-12.1\www\inlogg_och_lagar\core.inc.php 上线34

谁能告诉我我做错了什么? 这是一个简单的登录脚本。

这里是 loginform.inc.php

    <?php 
        if (isset($_POST['username'])&&isset($_POST['password'])) {

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

        $password_hash = md5 ($password);   


        if ($username && $password)
        {     
          $query  ="SELECT * FROM USERDATA where `username` = :username AND `password` = :password";
$stmt = $pdo->prepare($query);
$stmt->execute(array(
   ':username' => $_POST['username'],
   ':password' => $password_hash
));

$row = (bool) $stmt->fetch();
            if (!$rows)
            {   
                  echo '<p class="warning">Fel användarnamn/lösenords kombination.</p>';
            } else {    
                $_SESSION['user_id'] = $row;
                header('Location: index.php');
                exit;
            }
        } else {    
              echo '<p class="warning">Du måste fylla i ett användarnamn och lösenord</p>';
            }
    }
    ?>

        <!--- LOGIN FORM --->
        <div id="form-column">
            <p>You need to be loggedin.</p>
            <p>Fill out username and password.</p>
            <form action="<?php echo $current_file; ?>" method="POST"> 
                Användarnamn: <input type="text" name="username"> 
                Lösenord: <input type="password" name="password">
                <input type="submit" value="Log in">
            </form>
        </div>

这里是core.inc.php

    <?php 
    ob_start();
    session_start();
    $current_file = $_SERVER['SCRIPT_NAME'];

    if (isset($_SERVER['HTTP_REFERER'])&&!empty($_SERVER['HTTP_REFERER'])) {
        $http_referer = $_SERVER['HTTP_REFERER'];
    }


    function loggedin () {
        if (isset($_SESSION['user_id'])&&!empty($_SESSION['user_id'])) {
            return true;
        }   else {
            return false;
        }
    }

    function getuserrow ($row) {
    $sql  ="SELECT * FROM USERDATA where id = ?".$_SESSION['user_id']."'";
    global $pdo;
    $stmt = $pdo->prepare($sql);
    $stmt->execute(array($_POST['username']));
    $row = $stmt->fetch();
}

    ?>

这里是connect.inc.php

<?php

$dsn = "mysql:host=localhost;dbname=users;charset=utf8";
$opt = array(
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
$pdo = new PDO($dsn,'root','', $opt);

?>

【问题讨论】:

  • $dbh$pdo。选择一个。
  • 你的 PDO 对象被引用到$pdo 为什么你使用$dbh
  • 感谢您的回复,我现在尝试更改并使用 pdo,但随后收到另一条错误消息。我已经对上面的代码和问题进行了更新,如果您知道出了什么问题,请告诉我。 @hjpotter92
  • 感谢您的回复,我现在尝试更改并使用 pdo,但随后收到另一条错误消息。我已经对上面的代码和问题进行了更新,如果您知道出了什么问题,请告诉我。 @Shushant

标签: php mysql pdo prepared-statement


【解决方案1】:

您的 PDO 对象被定义为 $pdo,但后来被引用为 $dbh

  • 来自connect.inc.php

    $pdo = new PDO($dsn,'root','', $opt);
    
  • 来自loginform.inc.php

    global $dbh;
    // ...
    $stmt = $dbh->prepare($sql);
    

此外,loginform.inc.php 似乎不包括 connect.inc.php

【讨论】:

  • 您好,感谢您的回复!好的,我明白你的意思,我可以在每个写入 $dbh 的地方将 $dbh 更改为 $pdo 吗? connect.inc.php 文件和 lohinform.inc.php 都包含在您可以登录的页面上。所以在 index.php 上它们都包含在内,在我开始使用准备好的语句但使用准备好的语句之前它工作正常我还需要在 loginform.inc.php 中包含 connect.in.php 吗? @eggyal
  • 嗨,我刚刚用代码中的建议更改更新了问题,但我收到了另一条错误消息...你能告诉我我做错了什么吗?
【解决方案2】:

您在$stmt-&gt;execute(array($_POST['username'])) 处缺少第二个参数 应该是

$sql  ="SELECT * FROM USERDATA where username = ? AND password = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute(array($_POST['username'], md5($_POST['password'])));//<== here

【讨论】:

  • 啊,是的,你是对的!我试图改变它,但我仍然无法让脚本登录。它只是说密码/用户名组合错误。 if (!$row) { echo '&lt;p class="warning"&gt;Wrong password/username combination.&lt;/p&gt;'; } else { $_SESSION['user_id'] = $row; header('Location: index.php'); exit; }
  • 我已经更新了我的帖子,我认为你不习惯使用 PDO 考虑使用fluentpdo.com
  • 好的,现在我回到这个错误消息:注意:数组到字符串的转换... 致命错误:调用成员函数prepare( ) 在...中的非对象上
  • 旧错误是$pdo 不是对象PDO 的实例尝试自己解决
【解决方案3】:

替换这个,

global $pdo;  // <- You don't need this one
$sql  ="SELECT * FROM USERDATA where username = ? AND password = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute(array($_POST['username']));
$row = $stmt->fetch();

$query  ="SELECT * FROM USERDATA where `username` = :username AND `password` = :password";
$stmt = $pdo->prepare($query);
$stmt->execute(array(
   ':username' => $_POST['username'],
   ':password' => $password_hash
));

$row = (bool) $stmt->fetch();

为了避免这种情况,您最好坚持使用命名占位符而不是未命名占位符(例如?)。

【讨论】:

  • 您好,感谢分享!我已经尝试过了,但脚本仍然没有登录。它只是说错误的密码/用户名组合。知道有什么问题吗?这部分似乎有什么问题:if (!$row) { echo '&lt;p class="warning"&gt;Wrong password/username combination.&lt;/p&gt;'; } else { $_SESSION['user_id'] = $row; header('Location: index.php'); exit; }
  • @GeekGirl 更新了答案
  • 嗨,刚刚也试过了,错误消息不断出现。我已经用错误消息和 core.inc.php 中的代码更新了问题。我认为函数 getuserrow 有问题。对不起,我是这方面的初学者,只是不知道出了什么问题:/
  • 没关系,我会让我的老师向我解释这一点,因为我真的迷路了......我不会检查这个问题是否已解决,因为它没有解决,但我会支持你的回答!:) 感谢您的帮助!
  • 既然你在写一个登录表单,你应该把它当作一个“任务”。然后你应该把任务分解成小任务。然后你应该解决那些小任务。这到底是什么意思?好吧,您可能知道登录表单由Input ValidationRecord Validation(输入和记录验证器不一样)、存储(“记住我”功能的会话或 cookie)、存储验证(检查用户是否已经登录)。因此,您实际上有 4 个问题需要解决。您的问题是您混合了所有内容,因此您的代码越来越难以阅读。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-04
  • 2010-10-05
  • 2015-10-28
  • 2014-06-18
相关资源
最近更新 更多