【问题标题】:Connecting mysql database using PDO in external PHP file [duplicate]在外部PHP文件中使用PDO连接mysql数据库[重复]
【发布时间】:2023-03-22 01:45:02
【问题描述】:

我有一个 Index.php,它有一个用于在提交该表单时获取用户详细信息的表单,它会将数据触发到一个新的 program.php 以在 program.php 中进行验证我已经链接了我已经链接的 db.php连接数据库,db.php的代码如下:

<?php
    $link=mysql_connect('localhost', 'root', '') or die ("mysql_connect_error()");
    $dbselect=mysql_select_db('test',$link) or die ("Error while connecting the database");
?>

因为使用这种方式可以进行 sql 注入,所以我尝试将其更改为下面给出的代码:

<?php
$hostname='localhost';
$username='root';
$password='';

try
{
    $dbh = new PDO("mysql:host=$hostname;dbname=test",$username,$password);

    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // <== add this line
    $dbh = null;
}
catch(PDOException $e)
{
    echo $e->getMessage();
}
?>

但是当我连接提交表单时出现错误。在我的 program.php 中,我通过 include "db.php"; 调用了 db.php。由于我是 PDO 的新手,我不确定我哪里出错了。

更新 program.php 代码

<?php
if($_POST)
{
    include "link_db.php";

    if ($_POST[admin_sign_up])
    {
        $fname=$_POST[fname];
        $lname=$_POST[lname];   
        $id   =$_POST[id];
        $id_pass=$_POST[id_pass];
        $sql="insert into admin_database(fname, lname, id, id_pass) 
        value ('$fname','$lname','$id','$id_pass')";

        mysql_query($sql);

        $error=mysql_error();

        if(empty($error))
        {
            echo "<script>alert('Registration Successful...')</script>";
            header("Location:index.php",true);
        }
        else 
        {
            echo "Registration Failed...<br> Email Id already in use<br>";
            echo "<a href='failed.php'>Click to SignUp again</a>";
        }
    }

    if ($_POST[admin_login])
    {

        $id   =$_POST[id];
        $id_pass=$_POST[id_pass];

        $sql="select * from admin_database where id = '$id' and id_pass= '$id_pass'";
        $result=mysql_query($sql);
        echo mysql_error();
        $row=mysql_fetch_array($result);
        $rowcnt=mysql_num_rows($result);

        if($rowcnt==1)
        {
            session_start();
            $_SESSION['id']=$id;
            $_SESSION['fname']=$row['fname'];
            $_SESSION['lname']=$row['lname'];
            $_SESSION['varn']="Y";
            echo "Login Successfully....";
            header("Location:home.php",true);
        }
        else
        {
            $id   =$_POST[id];
            $id_pass=$_POST[id_pass];
            $sql="insert into adminfailure(id, id_pass, date_time) 
            value ('$id','$id_pass',NOW())";
            mysql_query($sql);
            $error=mysql_error();
            if(empty($error))
            {
                Echo "Invalid Login ID or Password....";
                header("Location:fail.php",true);
            }
            else
            {
                echo "incorrect details";
            }
        }
    }
    if ($_POST[logout])
    {
        header("location:destroy.php",true);
    }
}
?>

我得到的更新错误

注意:使用未定义的常量 test_sign_up - 在第 6 行的 B:\XAMPP\htdocs\test\program.php 中假设为“test_sign_up”

注意:未定义索引:第 6 行 B:\XAMPP\htdocs\test\program.php 中的 test_sign_up

注意:使用未定义的常量 test_login - 在第 32 行的 B:\XAMPP\htdocs\test\program.php 中假设为“test_login”

注意:使用未定义的常量 id - 在第 35 行的 B:\XAMPP\htdocs\test\program.php 中假定为“id”

注意:使用未定义的常量 id_pass - 在第 36 行的 B:\XAMPP\htdocs\test\program.php 中假定为“id_pass” 没有选择数据库 警告:mysql_fetch_array() 期望参数 1 是资源,布尔值在第 41 行的 B:\XAMPP\htdocs\test\program.php 中给出

警告:mysql_num_rows() 期望参数 1 是资源,布尔值在第 42 行的 B:\XAMPP\htdocs\test\program.php 中给出

注意:使用未定义的常量 id - 在第 56 行的 B:\XAMPP\htdocs\test\program.php 中假定为“id”

注意:使用未定义的常量 id_pass - 在第 57 行的 B:\XAMPP\htdocs\test\program.php 中假定为“id_pass” 不正确的细节 注意:使用未定义的常量注销 - 在第 73 行的 B:\XAMPP\htdocs\test\program.php 中假设为“注销”

注意:未定义索引:第 73 行 B:\XAMPP\htdocs\test\program.php 中的注销

【问题讨论】:

  • 你得到的错误是什么?
  • $hostname = 'localhost is missing '; 这是仅此 sn-p 中的错字还是您复制了真实代码?
  • @Jite 抱歉,在添加被错误删除的空格时更新了代码
  • @donald123 我遇到了很多错误,我无法在此处复制粘贴,也没有关于连接的错误,但它与从数据库中获取文件有关,我猜连接有效,但因为它是在外部完成的是不是有点问题

标签: php mysql pdo mysqli connection


【解决方案1】:

在您的代码中,您首先创建与数据库的连接,然后将其设置为 null。
之后,无论您何时尝试访问 $dbh 对象,它都会为 null

$dbh = new PDO("mysql:host=$hostname;dbname=test",$username,$password);

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh = null;  // <= Right here.

删除$dbh = null; 行,您应该能够按预期使用该对象。

$dbh 对象不仅是您在 mysql_* 代码中所做的“链接”,而且是您用来调用数据库的对象,这与您在 @ 中使用的对象不同987654327@ 来电。
即,您不能使用早期的 mysql_* 代码,而只需将 pdo 对象而不是 mysql 链接传递给调用。
因此,该代码将与您之前的代码有所不同。

例子:

// Earlier code using `mysql_* API`:
$sql="select * from admin_database where id = '$id' and id_pass= '$id_pass'";
$result=mysql_query($sql);
$row=mysql_fetch_array($result);


// Would look something like this using PDO:
$statement = $dbh->prepare('SELECT * FROM admin_database WHERE id =:id AND id_pass =:idpass');
// Here you can either use the bindParam method, or pass the params right into the execute call:
$statement->execute(array('id' => $id, 'idpass' => $id_pass);
$row = $statement->fetch(); 

如果您在转换代码时遇到问题,我建议您阅读docs 中的PDO


进一步的建议

当您包含这样的文件时,您只想在每个脚本运行时包含一次,确保它只包含一次总是一个好主意。这可以通过使用include_once 关键字来完成,而不仅仅是include。现在,如果您使用包含,这将尽可能包含脚本,如果不能,它将继续运行脚本,并且当您尝试使用文件中设置的变量时,脚本将崩溃。
在这种情况下,我建议不要使用include,而是使用require(或者更确切地说是require_once)关键字。其中将包含该文件,如果不能,则停止执行脚本并显示错误消息(如果您有错误报告)。

【讨论】:

  • 我试过了,但问题还是一样
  • 你是如何查询数据库的?你得到什么错误?在您显示的代码中,这是我能注意到的唯一问题,它可能在您包含 db.php 文件的文件中出现问题。
  • 我已经更新了我的代码
  • 是的,正如我所提到的,您不能调用您之前的 mysql_* 查询并期望它们能够工作(尤其是当您不再像以前那样创建 mysql 连接时),您将不得不将所有查询更改为使用 PDO$dbh 对象。
  • 以示例编辑答案。
【解决方案2】:

您不仅要更改 db.php,还要更改对代码的所有查询。并且始终使用准备好的语句将变量传递给查询。否则 PDO 将无法保护您免受注射。

目前我正在写tutorial on PDO,它仍然不完整,但可以为您提供可以开始的基础知识。

【讨论】:

    猜你喜欢
    • 2021-12-06
    • 2013-08-03
    • 2017-11-29
    • 1970-01-01
    • 2021-02-25
    • 2018-10-28
    • 1970-01-01
    • 2018-02-11
    相关资源
    最近更新 更多