0

したがって、次のように3つのテーブルがあります。

TOPICS      TOPIC_TAGS    Tags
topic_id    tag_id        tag_id
topic_data  topic_id      tags

現在、topic_data を TOPICS に正常に挿入でき、TAGS は次のように挿入されています...

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);
4

1 に答える 1

0

関数のサポートはなくなりました。mysql_*関数は公式に非推奨になり、メンテナンスされなくなり、将来的に削除される予定です将来のプロジェクトの機能を確実にするために、PDOまたはMySQLiでコードを更新する必要があります。

を使用しているので、インジェクションを防ぐためにmysql_*使用する必要があります。mysql_real_escape_string


注:私の例は、質問の上部で提供したテーブル情報のみをカバーしています。他の列を自分で追加する必要があります。

MySQLi と準備済みステートメントを使用すると、準備済みステートメントを使用したインジェクションを簡単に防ぐことができます。

bind_paramたとえば、挿入するデータのタイプを処理する は、i整数、s文字列を表すため、クエリにあるそれぞれについて、それぞれのタイプで に?追加します。詳しくはこちらをご覧ください。bind_parambind_param

私のテストフォーム:

<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>

データベース.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に格納して、後で table に再利用しています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)
于 2013-07-22T04:40:11.867 に答える