2012-09-05 61 views
-1

當我使用mysql_*函數進行數據庫操作時,我曾經把連接數據庫和初始化代碼放在一個單獨的文件中,並將它包含在其他頁面上,並且它運行良好。用PDO抽象

我最近學會了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> 

但是,當我輸入一些東西,提交,它拋出,即使我已經包括了必要的文件,這個錯誤。

enter image description here

有人能告訴我,我做錯了什麼嗎?我真的很感激它。 或者是否有更簡單/高效/正確的方法來完成此任務?

謝謝。

回答

3

您的幫助函數正嘗試訪問全局變量$db,這不在範圍內。這個錯誤可以在每個函數頂部的global $db;修復。

這種方法在你學習的時候是很自然的一步,但從工程的角度來看,這是非常不可取的,因爲你的函數依賴於全局狀態。在將來,您應該研究如何創建一個擴展PDO(或聚合PDO實例)的類,並讓這些函數成爲該類的方法。如果你這樣做,那麼$db變量將成爲班級中的「部分」或encapsulated,這是一個有價值的目標。

+0

+1的OOP方法的建議! – Havelock

0

這裏的問題是variable scope。您需要將您的$ 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; 
} 
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(); 
    } 
}