2015-02-06 68 views
1

我有一個PHP上傳類,它有各種函數用於檢查文件並確保它符合正確的規範。不過,我有一個功能,剝離文件的名稱,並給它一個新的名字,這是一個數字。在這個函數中,我包含了我的連接,包括開始與數據庫的連接。爲了防止給兩個文件相同的名稱,我有我的數據庫中的表,其中保存了當前計數,它引用了最後一個圖像編號。當我上傳圖片時,它會從數據庫中提取計數並添加一個,並將該數字作爲圖片的名稱進行存儲。然後,我再次通過查詢數據庫來更新新計數表。這工作正常但是當我查詢另一個函數中的數據庫輸入文件的路徑時,它告訴我我的連接變量沒有聲明。我已經發布了下面的連接代碼以及我所調用的兩個函數。我很好奇,如果我沒有在正確的地方開始連接。我已經嘗試釋放結果並在調用該函數後關閉連接,然後在另一個函數中再次打開連接以提交文件路徑,但似乎也不起作用。我知道他們是關於一次打開一個連接的規則,但我儘管可以在該連接內多次查詢數據庫。在一個類中的兩個不同函數中查詢MySQL數據庫兩次

連接包括

// Create a database connection 
$dbhost = "localhost"; 
$dbuser = "user"; 
$dbpass = "password"; 
$dbname = "new_db"; 
$connection = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname); 

// Test if connection occured. 
if(mysqli_connect_errno()) { 
    die("Database connection failed: " . 
     mysqli_connect_error() . 
     " (" . mysqli_connect_errno() . ")" 
    ); 
} 

第一功能

//replaces the filename with an incremented number 
public function trim_filename() { 
    require_once('includes/connection.php'); 
    $query = "SELECT * FROM image_count "; 
    $result = mysqli_query($connection, $query); 
    if (!$result) { 
     die("Database query failed. "); 
    } 
    $row = mysqli_fetch_assoc($result); 
    $count = 1 + $row["name"]; 
    mysqli_free_result($result); 
    $query = "UPDATE image_count SET name = '{$count}' WHERE count = 1"; 
    $result = mysqli_query($connection, $query); 
    if (!$result) { 
     die("Database query failed. "); 
    } 
    $file = $_FILES['image']['name']; 
    $file = explode(".", $file); 
    $file = end($file); 
    $file = $count . "." . $file; 
    $_FILES['image']['name'] = $file; 
    $this->final_check(); 
    mysqli_free_result($result); 
    mysqli_close($connection); 
} 

二級功能

public function database_query($in_path) { 
    $query = "INSERT INTO course ("; 
    $query .= " course_name "; 
    $query .= ") VALUES ("; 
    $query .= " '{$in_path}'"; 
    $query .= ")"; 
    $result = mysqli_query($connection, $query); 
    if (!$result) { 
     die("Database query failed. "); 
    } 
    mysqli_free_result($result); 
    mysqli_close($connection); 
} 

回答

0

這是一個常見的問題,面對特別是如果你有使用舊mysql_query() API之前的經驗,這依賴於從全球採集的連接資源州。您需要在適當的範圍內獲得$connection才能在您的功能中使用它。

處理這種情況最好的辦法是不做類中的require_once()在所有建立連接。相反,在類之外執行的動作,並將生成的$connection變量傳遞給類'__construct()方法。然後將它存儲在課程中的一個屬性中,您可以在其中使用它作爲$this->connection。這被稱爲依賴注入。現在

class ThisClass 
{ 
    // A public property for the connection 
    protected $connection; 

    // Modify your __construct() to accept the connection 
    public function __construct(/* existing params... , */ mysqli $connection) 
    { 
    // Whatever your constructor already does... 
    // Store the connection in a property 
    $this->connection = $connection; 
    } 

    // Then modify those two methods to use $this->connection 
    public function trim_filename() { 
    $query = "SELECT * FROM image_count "; 
    // Use $this->connection 
    $result = mysqli_query($this->connection, $query); 
    if (!$result) { 
     die("Database query failed. "); 
    } 
    // SNIP.... 
    // Don't free/close the connection! 
    } 
    // Then modify those two methods to use $this->connection 
    public function database_query($in_path) { 
    $query = "INSERT INTO course ("; 
    // SNIP... 
    // Use $this->connection 
    $result = mysqli_query($this->connection, $query); 
    if (!$result) { 
     die("Database query failed. "); 
    } 
    // Don't free/close the connection! 
    } 
} 

,使用你的類與連接相關性:

// Done outside the class, defines $connection 
require_once('includes/connection.php'); 
// Then when you use the class 
// give it the $connection as a parameter 
$object = new ThisClass($connection); 
$object->trim_filename(); 

沒有一個規則大約有隨時打開一個連接,但它是罕見的,有點異域風情需要不止一個。

非理想替代品:如果你真的不想存儲出於某種原因在類屬性的連接,你可以用來修改兩種方法來接受$connection作爲放慢參數一樣

// Add a param to the functions that need it. 
public function trim_filename($connection) { 
    // use $connection->query(...); 
} 
// Call outside the class as: 
$object->trim_filename($connection); 

你還在課外做require_once()。但是將它作爲依賴注入到構造函數中會更清晰,併爲您提供了一個簡單的路徑來擴展需要訪問數據庫連接的類中的更多方法。

訪問與需要它是最不理想的方法來使用,特別是如果你繼續建立它的內部的類函數之一global關鍵字內部方法$connection變量。按照面向對象的原則,建立數據庫連接不應該是班級的責任。相反,如果類需要一個,它應該從外部傳遞給對象。

+0

感謝您的回答,非常好的解釋! Michael Berkowski – Tyler 2015-02-08 18:48:15

+0

@Tyler很高興幫助,祝你好運。 – 2015-02-08 18:54:21

-1

您可以嘗試「全局連接」在database_query函數中?還你不應該關閉功能的連接

public function database_query($in_path) { 

    global $connection; 

    $query = "INSERT INTO course ("; 
    $query .= " course_name "; 
    $query .= ") VALUES ("; 
    $query .= " '{$in_path}'"; 
    $query .= ")"; 
    $result = mysqli_query($connection, $query); 
    if (!$result) { 
     die("Database query failed. "); 
    } 
    mysqli_free_result($result); 
    mysqli_close($connection); 
} 
-1

最好的辦法處理這些類型的情況 將所有你在一個文件中像(例如:function.php)函數,則包括您connection.php文件在function.php.Use全局變量的頂部,讓您連接對象中每個函數的

Connection.php文件

// Create a database connection 
$dbhost = "localhost"; 
$dbuser = "user"; 
$dbpass = "password"; 
$dbname = "new_db"; 
$connection = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname); 

// Test if connection occured. 
if(mysqli_connect_errno()) { 
    die("Database connection failed: " . 
    mysqli_connect_error() . 
    " (" . mysqli_connect_errno() . ")" 
); 
} 

function.php文件

//inculing connnection.php file 
require_once('includes/connection.php'); 

//first funtion 
public function trim_filename() { 
    globel $connection; 
    // code here 
} 

//second funtion 
public database_query($in_path) { 
    globel $connection; 
    // code here 
} 
相關問題