2014-11-06 111 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.")"); 
    } 
}