2014-11-06 35 views
0

基本上,我試圖在我的PHP類之一中實現一個函數,該函數爲many to many關係創建一個結點表。問題使用mysql_query()執行INSERT語句PHP

這是這裏的方法:

public function setTags($value, $id){ 
    global $db; 
    $tags = $value; 
    $query .= "DELETE FROM directorycolumntags 
       WHERE directorycolumn_id = $id; "; 
    foreach($tags as $tag){ 
    $query .= "INSERT INTO directorycolumntags (directorycolumn_id, tag_id) 
       VALUES (".$id.",".$tag.");"; 
    } 
    mysql_query($query); 
} 

SQL是生產優良工程,爲我呼應,並通過phpMyAdmin手動執行它。但是,如果我如上所述離開它,數據永遠不會被插入。有誰知道爲什麼會發生這種情況?

這是sql這是發生在我在手動鍵入它的正常工作:

DELETE FROM directorycolumntags WHERE directorycolumn_id = 178; 
INSERT INTO directorycolumntags (directorycolumn_id, tag_id) VALUES (178,29); 
INSERT INTO directorycolumntags (directorycolumn_id, tag_id) VALUES (178,30); 
INSERT INTO directorycolumntags (directorycolumn_id, tag_id) VALUES (178,32); 
+2

'mysql_query'只做一次一個語句,它也被棄用 – Musa 2014-11-06 12:00:00

+0

nope,你可以只是連接語句,然後執行它們,它不支持該API,並停止使用它。 – Ghost 2014-11-06 12:01:05

+0

停止使用whaT? – Javacadabra 2014-11-06 12:01:30

回答

1

舊的,不安全的,不推薦使用mysql_*擴展從未支持多查詢。你可能,可以想象使用mysql替換擴展:mysqli_*,它有the mysqli_multi_query function
個人而言,我不會使用這種方法。我會做什麼最開發者會做:用事先準備好的聲明中交易安全地執行每個查詢,並提交成功的結果,或回滾失敗:

$db = new PDO(
    'mysql:host=127.0.0.1;dbname=db;charset=utf8', 
    'user', 
    'pass', 
    array(
     PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 
    ) 
); 
try 
{ 
    $db->beginTransaction(); 
    $stmt = $db->prepare('DELETE FROM tbl WHERE field = :id'); 
    $stmt->execute(array(':id' => $id)); 
    $stmt = $db->prepare('INSERT INTO tbl (field1, field2) VALUES (:field1, :field2)'); 
    foreach ($tags as $tag) 
    { 
     $stmt->execute(
      array(
       ':field1' => $id, 
       ':field2' => $tag 
      ) 
     ); 
     $stmt->closeCursor();//<-- optional for MySQL 
    } 
    $db->commit(); 
} 
catch (PDOException $e) 
{ 
    $db->rollBack(); 
    echo 'Something went wrong: ', $e->getMessage(); 
} 

稍微去題外話:你真的應該考慮使用類型提示。從你的代碼中,很明顯$values有望成爲一個數組。類型提示可以確保傳遞的值實際上是一個數組。你也應該擺脫那個醜陋的global $db;,而不是傳遞連接作爲參數。這就是爲什麼我強烈建議你改變你的函數的簽名來自:

public function setTags($value, $id){ 

要:

public function setTags(PDO $db, array $value, $id) 
{ 
} 

這樣,調試變得輕鬆了不少:

$instance->setTags(123, 123);//in your current code will not fail immediately 
$instance->setTags($db, [123], 123);//in my suggestion works but... 
$instance->setTags([123], null, '');// fails with a message saying argument 1 instance of PDO expected 
+0

輝煌的答案,會做,非常感謝你的建議。 – Javacadabra 2014-11-06 12:23:47

+1

@Javacadabra:不客氣,只要你知道:如果你決定重構代碼,切換到'PDO'或'mysqli',你可以發佈你的第一次嘗試[here](http:// codereview。 stackexchange.com/)來獲得一些代碼審查。這樣,你就會知道你是否正確地做事 – 2014-11-06 12:31:04

+0

哦酷,這是一個很棒的網站,我沒有意識到它的存在,會做,非常感謝。 – Javacadabra 2014-11-06 12:33:33

1

http://docs.php.net/mysql_query說:

mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier 

如果你可以使用的mysqli或許你這個興趣:mysqli.multi-query

Executes one or multiple queries which are concatenated by a semicolon. 
0

你不能運行multipl需要使用mysql_query,試着像這樣修改你的函數。它會更好,如果你使用的mysqli或PDO MySQL的,而不是因爲它很快就會過時,它不會對PHP的新版本工作

public function setTags($value, $id){ 
    global $db; 
    $tags = $value; 
    mysql_query("DELETE FROM directorycolumntags WHERE directorycolumn_id = $id"); 
    foreach($tags as $tag){ 
     mysql_query("INSERT into directorycolumntags (directorycolumn_id, tag_id) VALUES (".$id.",".$tag.")"); 
    } 
}