-1

当我使用mysql_*函数进行数据库操作时,我曾经将连接数据库和初始化代码放在一个单独的文件中,并将其包含在其他页面上,效果很好。

我最近学习了 PDO,所以我想用 PDO 尝试一下。所以我有 4 个 PHP 文件。

config.php文件存储所有数据库相关信息。

<?php

$host = "localhost";
$username = "root";
$password = "abc123";
$dbname = "blog";

?>

init.php包含 config.php 文件并初始化数据库连接。

<?php

include_once("config.php");

$db = new PDO('mysql:host=' . $host . ';dbname=' . $dbname, $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

?>

还有一个名为functions.php的单独文件,其中包含所有功能。它包括 init.php 文件。

<?php

include_once("init.php");

function AddCategory($_name)
{
    $param = $_name;
    $query = $db->prepare("INSERT INTO categories SET name = :name");
    $query->bindParam(':name', $param, PDO::PARAM_STR);
    $query->execute();
}

function CategoryExists($_name)
{
    $param = $_name;
    $query = $db->prepare("SELECT COUNT(1) FROM categories WHERE name = :name");
    $query->bindParam(':name', $param, PDO::PARAM_STR);
    $query->execute();

    $results = $query->fetch();

    return ($results == '0') ? false : true;
}

?>

以及显示一个小表格的index.php文件。

<?php

include_once("functions.php");

if(isset($_POST['name']))
{
    $name = trim($_POST['name']);

    if(empty($name))
    {
        $error = "You must enter a category name";
    }
    else if (CategoryExists($name))
    {
        $error = "That category already exists";
    }
    else if (strlen($name) > 24)
    {
        $error = "Category name can only be upto 24 characters";
    }

    if(!isset($error))
    {
        AddCategory($name);
    }
}

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Add a Category</title>
</head>
<body>

    <h1>Add a Category</h1>

    <form action="" method="post">
        <div>
            <label for="name">Name</label>
            <input type="text" name="name" value=""></input>
        </div>
        <div>
            <input type="submit" value="Add Category"></input>
        </div>
    </form>

</body>
</html>

但是当我输入一些东西并提交它时,即使我已经包含了必要的文件,它也会抛出这个错误。

在此处输入图像描述

有人可以告诉我我在这里做错了什么吗?我真的很感激。还是有更简单/有效/正确的方法来实现这一点?

谢谢你。

4

3 回答 3

3

您的辅助函数正在尝试访问$db不在范围内的全局变量。可以global $db;在每个函数的顶部修复此错误。

这种方法是您学习时的自然步骤,但从工程的角度来看,这是非常不可取的,因为您的函数依赖于全局状态。将来,您应该研究如何创建一个扩展PDO(或聚合 PDO 实例)的类,并使这些函数成为该类的方法。如果你这样做,那么$db变量将成为类的“一部分”或封装在类中,这是一个有价值的目标。

于 2012-09-05T08:12:42.917 回答
1

在您的函数内部, $db 是一个未知变量。

快速而肮脏的方式:

function AddCategory($_name)
{
    global $db;
    $param = $_name;
    $query = $db->prepare("INSERT INTO categories SET name = :name");
    $query->bindParam(':name', $param, PDO::PARAM_STR);
    $query->execute();
}

当然有一个更好的解决方案:让它成为一个类并将它们放在一起:

class mymodel
{
    private $db;

    function __construct( $host, $dbnam, $username, $password)
    {
      $this->db = 
        new PDO('mysql:host=' . $host . ';dbname=' . $dbname, $username, $password);
      $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }

    function AddCategory($_name)
    {
        $param = $_name;
        $query = $this->db->prepare("INSERT INTO categories SET name = :name");
        $query->bindParam(':name', $param, PDO::PARAM_STR);
        $query->execute();
    }
} 
于 2012-09-05T08:13:36.063 回答
0

这里的问题是变量范围。您需要将 $db 对象作为函数参数传入。

function AddCategory($_name, $db)
{
    $param = $_name;
    $query = $db->prepare("INSERT INTO categories SET name = :name");
    $query->bindParam(':name', $param, PDO::PARAM_STR);
    $query->execute();
}

function CategoryExists($_name, $db)
{
    $param = $_name;
    $query = $db->prepare("SELECT COUNT(1) FROM categories WHERE name = :name");
    $query->bindParam(':name', $param, PDO::PARAM_STR);
    $query->execute();

    $results = $query->fetch();

    return ($results == '0') ? false : true;
}
于 2012-09-05T08:13:19.750 回答