2016-01-19 50 views
0

我已經將PHP代碼插入到前一頁的HTML表單數據到數據庫中,並在同一個SQL語句中從插入的數據返回PostID。 PostID列是AUTO_INCREMENTING。我現在一直在研究這個問題一兩個星期,但沒有找到重要的解決方案。爲什麼INSERT INTO後跟SELECT LAST_INSERT_ID()不輸出任何內容?

<?php 
include("dbconnect.php"); 
mysql_select_db("astral_database", $con); 
session_start(); 

$username = $_SESSION['username']; 
$forumtext = $_POST["forumtext"]; 
$forumsubject = $_POST["forumsubject"]; 

$postquery = 'INSERT INTO Forums (Creator, Subject, Content) VALUES ("$username", "$forumsubject", "$forumtext"); SELECT LAST_INSERT_ID()'; 
$result = mysql_query($postquery, $con); 

if (!$con) { 
    echo "<b>If you are seeing this, please send the information below to [email protected]</b><br>Error (331: dbconnect experienced fatal errors while attempting to connect)"; 
    die(); 
} 

if ($username == null) { 
    echo "<b>If you are seeing this, please send the information below to [email protected]</b><br>Error (332: Username was not specified while attempting to send request)"; 
    die(); 
} 

if ($result != null) { 
    echo "last id: " . $result; 

    $fhandle = fopen("recentposts.txt", "r+"); 
    $contents = file_get_contents("recentposts.txt"); 
    fwrite($fhandle, json_encode(array("postid" => $result, "creator" => $username, "subject" => $forumsubject, "activity" => time())) . "\n" . $contents); 
    fclose($fhandle); 
    mysql_close($con); 
    header("location: http://astraldevgroup.com/forums"); 
    die(); 
} else { 
    die("<b>If you are seeing this, please send the information below to [email protected]</b><br>Error (330: Unhandled exception occured while posting forum to website.)<br>"); 
    echo mysql_error(); 
} 

mysql_close($con); 
?> 

首先,mysql_query不會從SELECT語句返回任何內容。我還沒有找到任何能在同一個查詢中正確運行SELECT語句和INSERT語句的東西。如果我嘗試在兩個不同的語句中運行它們,它仍然不會返回任何內容。我試着在SQL控制檯中運行下面的語句,它運行得很好,沒有錯誤。

INSERT INTO Forums (Creator, Subject, Content) VALUES ("Admin", "Test forum 15", "This is a forum that should give me the post id."); SELECT LAST_INSERT_ID(); 
+1

首先,您必須避免在查詢中使用mysql_,因爲它被聲明爲不安全。 – ameenulla0007

+3

[您的腳本存在SQL注入攻擊風險。](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) –

+3

請[停止使用'mysql_ * '函數](http://stackoverflow.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php)。 [這些擴展](http://php.net/manual/en/migration70.removed-exts-sapis.php)已在PHP 7中刪除。瞭解[編寫]​​(http://en.wikipedia.org/ wiki/Prepared_statement)語句[PDO](http://php.net/manual/en/pdo.prepared-statements.php)和[MySQLi](http://php.net/manual/en/mysqli.quickstart .prepared-statements.php)並考慮使用PDO,[這真的很簡單](http://jayblanchard.net/demystifying_php_pdo.html)。 –

回答

3

mysql_query功能確實運行多個語句

參考:http://php.net/manual/en/function.mysql-query.php

mysql_query()發送一個唯一的查詢(多個查詢不支持),以當前活動數據庫服務器...

這是您致電mysql_query時未返回結果集的原因之一。

最明顯的解決方法是不要嘗試在同一查詢中運行SELECT。您可以改用mysql_insert_id的電話。

參考:PHP: mysql_insert_id http://php.net/manual/en/function.mysql-insert-id.php


解答一些問題,你沒有問:

  • 是的,你的示例代碼很容易受到SQL注入
  • 是的,mysql_界面長期以來一直是deprecated
  • 是的,您應該使用PDOmysqli接口而不是已棄用的mysql_函數。

隨訪

重新訪問我的答案,在這個問題再次尋找和示例代碼。

我之前指出該代碼易受SQL注入攻擊,因爲SQL文本中可能包含不安全的值。這就是快速審查時的樣子。

但是再看一遍,這並非嚴格正確,因爲變量替換並未真正發生,因爲字符串文字被包含在單引號中。考慮一下從輸出:

$foo = "bar"; 
    echo '$foo'; 
    echo '"$foo"'; 

然後考慮是什麼這行代碼分配給$postquery

$postquery = 'INSERT ... VALUES ("$username", "$forumsubject", "$forumtext")'; 

修復那些使$username被認爲是一個變量的引用,而不是文字字符(以獲取分配給$username變量納入SQL文本),這將引入SQL注入漏洞。

帶有綁定佔位符的準備語句確實是不是那麼難

0

$result永遠不會是null。它可以是結果句柄,也可以是布爾值false。由於您正在測試錯誤的值,因此您永遠不會看到mysql_query()返回的錯誤消息,告訴您查詢失敗。

正如其他人指出的那樣,您不能在單個調用中發出多個查詢 - 這對於PHP mysql驅動程序中的一種SQL注入攻擊形式來說是一種廉價的基本防禦措施。然而,你的代碼的其餘部分很容易受到其他形式的注入攻擊,所以......最好開始閱讀:http://bobby-tables.com

此外,邏輯端,你爲什麼要爲空的用戶名測試你嘗試插入那個數據庫的用戶名非常相同?您應該測試/驗證這些值之前您運行查詢

+0

+1。供參考經典的xkcd/327。並回答OP沒有提出的其他問題。 – spencer7593