2013-07-22 67 views
0

所以我有3个表格,如下所示。LAST_INSERT_ID()没有返回所有标签

TOPICS  TOPIC_TAGS Tags 
topic_id tag_id  tag_id 
topic_data topic_id  tags 

现在我可以成功地插入到topic_data主题,标签被插入这样的...

tag_id tags 
1   this 
2   is 
3   a 
4   test 

但是,当我试图将tag_ids插入TOPIC_TAGS表,它只插入最后一个像这样

topic_id tag_id 
0   4 

而且它也不插入主题插入时的topic_id。

这是发布数据的表单。

<form method="post" action="add_topic.php"> 
<table> 
<tr> 
<td align="left"><b>Enter your Topic keywords. 
    <ul id="topic" name="tags[]"></ul> 

</td> 
</tr> 
<tr> 
<td colspan="3"><textarea name="topic_data" cols="50" rows="3" id="topic_data" placeholder="What Topic are you talking about?"></textarea></td> 
</tr> 
<tr> 
<td colspan="3" align="right">Invisipost: <input type="hidden" name="invisipost" value="0"><input type="checkbox" name="invisipost" value="1"> <input type="submit" name="Submit" value="Talk" /> <input type="reset" name="Submit2" value="Reset" /></td> 
</tr> 
</table> 
</form> 

这里是我的代码:

$tags = isset($_POST['tags']) ? $_POST['tags'] : null; 

if (is_array($tags)) { 
foreach ($tags as $t) { 
    // Checking duplicate 
    $sql_d = "SELECT * from tags where tags='$t'"; 
     $res=mysql_query($sql_d); 
     $res = mysql_num_rows($res); 
    if($res<1) 
    { 
    // escape the $t before inserting in DB 
    $sql = "INSERT INTO tags (tags) VALUES('$t')"; 
    mysql_query($sql); 
    } 
} 
} else { 
echo 'Invalid tag'; 
} 
$sql_s = "SELECT * from tags where tag_id='$tags'"; 
$tag_id = isset($_GET['tag_id']) ? $_GET['tag_id'] : null; 

if (is_array($tag_id)) { 
foreach ($tag_id as $tid) { 

    // escape the $t before inserting in DB 
    $sql = "INSERT INTO topic_tags (tag_id) VALUES('$tid')"; 
    mysql_query($sql); 
    } 
} 

$sql="INSERT INTO topic_tags (tag_id)VALUES(LAST_INSERT_ID())"; 
$result=mysql_query($sql); 


$topic_data= htmlentities($_POST['topic_data']); 
$posted_by = $_SESSION['user_id']; 
$posted = "date_add(now(),INTERVAL 2 HOUR)"; 
$invisipost = isset($_POST['invisipost']) ? $_POST['invisipost'] : 0 ; 

if (($topic_data=="")) 
echo "<h2>Opps...</h2><p>You did not fill out all the required fields.</p>"; 

else 
$sql="INSERT INTO topics(topic_data, posted_by, posted, invisipost)VALUES('$topic_data', '$posted_by', $posted, $invisipost)"; 
$result=mysql_query($sql); 

if($result){ 

$sql="INSERT INTO topic_tags (topic_id)VALUES(LAST_INSERT_ID()) WHERE topic_tags.tag_id='". $_GET['tags'] ."'"; 
$result=mysql_query($sql); 
+0

'mysql_query'等在php5中被弃用。您应该切换到使用面向对象的语句,或使用'mysqli'而不是'mysql'的过程语句。例如,'mysqli_query(“whatever”);' –

+0

一旦我得到了网站的全部功能,我也计划,你对我的原始文章中列出的问题有任何建议吗? – user2571547

+0

对于SQL注入式攻击,你是**开放的**,如果你还没有被攻击,你将被黑客攻击。使用准备/参数化查询完全避免此问题。 – Brad

回答

0

没有更多的支持mysql_*功能,它们是officially deprecated不再保持,将在未来removed。您应该使用PDOMySQLi来更新您的代码,以确保您的项目未来的功能。

由于您使用的是mysql_*,您应该使用mysql_real_escape_string来防止注射。


注:我的例子只涉及您在你的问题上提供的表信息,你必须将自己添加任何其他列。

使用MySQLi和预准备语句,您可以轻松防止使用预准备语句进行注入。

bind_param所以你有你的查询中的每个?你将它添加到bind_param与它的相应类型的字符串照顾你插入例如i数据类型的代表整数,sRead more about bind_param here.

我的测试形式:

<form method="post" action="add_topic.php"> 
<table> 
<tr> 
<td align="left"><b>Enter your Topic keywords.<br /> 
<input id="topic" name="tags"> 
</td> 
</tr> 
<tr> 
<td colspan="3"><textarea name="topic_data" cols="50" rows="3" id="topic_data" placeholder="What Topic are you talking about?"></textarea></td> 
</tr> 
<tr> 
<td colspan="3" align="right">Invisipost: <input type="hidden" name="invisipost" value="0"><input type="checkbox" name="invisipost" value="1"> <input type="submit" name="Submit" value="Talk" /> <input type="reset" name="Submit2" value="Reset" /></td> 
</tr> 
</table> 
</form> 

database.php中:

<?php 
// fill with your data 
$db_host = 'localhost'; 
$db_user = 'stackoverflow'; 
$db_pass = 'stackoverflow'; 
$db_name = 'stackoverflow'; 

$con = mysqli_connect($db_host,$db_user,$db_pass,$db_name); 
if($con->connect_error) 
    die('Connect Error (' . mysqli_connect_errno() . ') '. mysqli_connect_error()); 

add_topic.php:

<?php 
include_once "database.php"; 
$tags = $_POST['tags']; 
$topic_data = $_POST['topic_data']; 
$ids = array(); 

if (!isset($topic_data)) 
{ 
    die("<h2>Opps...</h2><p>You did not fill out the topic data field.</p>"); 
} 

if (!isset($tags)) 
{ 
    die("<h2>Opps...</h2><p>You did not fill out the tags field.</p>"); 
} 

foreach (explode(' ', $tags) as $tag) 
{ 
    if ($stmt = $con->prepare("SELECT tag_id FROM tags WHERE tags=?")) 
    { 
     $stmt->bind_param("s", $tag); 
     $stmt->execute(); 
     $stmt->bind_result($id); 
     $stmt->fetch(); 
     $stmt->close(); 
    } 

    if ($id == 0) 
    { 
     if ($stmt = $con->prepare("INSERT INTO tags (tags) VALUES(?)")) 
     { 
      $stmt->bind_param("s", $tag); 
      $stmt->execute(); 
      $stmt->bind_result($id); 
      $stmt->fetch(); 
      $ids[] = $stmt->insert_id; 
      $stmt->close(); 
     } 
    } 
    else 
     $ids[] = $id; 
} 

if ($stmt = $con->prepare("INSERT INTO topics(topic_data) VALUES(?)")) 
{ 
    $stmt->bind_param("s", $topic_data); 
    if ($stmt->execute()) 
    { 
     $topic_id = $stmt->insert_id; 
     $stmt->close(); 
     foreach ($ids as $id) 
     { 
      if ($stmt = $con->prepare("INSERT INTO topic_tags (topic_id, tag_id) VALUES(?, ?)")) 
      { 
       $stmt->bind_param("ii", $topic_id, $id); 
       $stmt->execute(); 
       $stmt->close(); 
      } 
     }  
    } 
    else 
     $stmt->close(); 
} 

echo "<h2>Topic successfully inserted</h2><p>The topic and tags have been inserted.</p>"; 
$con->close(); 

正如你可以在我的代码中看到,当我我正在检查标签,我也检索标签的ID它们已经存在并将它们全部存储到数组$ids中以便稍后重新用于表topic_tags

成功插入主题后,我检索主题ID,然后将所有标记ID与主题ID一起插入到topic_tags表中。

在我的测试形式,我使用的标签一个简单的输入但是如果你使用它作为一个数组,你也可以从改变:

if (!isset($tags)) 

要:

if (!isset($tags) || !is_array($tags)) 

而改变:

foreach (explode(' ', $tags) as $tag) 

要:

foreach ($tags as $tag) 
+0

谢谢你的想法,我正在尝试你的代码,并得到“Opps ... 你没有填写标签字段。”该字段是正确命名的,并且里面有数据,我在代码中看不到为什么会出现错误。 – user2571547

+0

@ user2571547你的HTML你的标签不是一个字段,它是HTML的一个列表元素。 '

    ','ul'不是字段。 – Prix

    +0

    您的示例将其更改为输入字段,然后我放弃并重试。 – user2571547