-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 に答える