簡體   English   中英

如何在 MySQL 語句中包含 PHP 變量

[英]How to include a PHP variable inside a MySQL statement

我正在嘗試在內容表中插入值。 如果我在 VALUES 中沒有 PHP 變量,它工作正常。 當我將變量$type放在VALUES中時,這不起作用。 我究竟做錯了什么?

$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) 
     VALUES($type, 'john', 'whatever')");

在任何 MySQL 語句中添加 PHP 變量的規則很簡單:

  1. 任何表示SQL 數據文字的變量,(或者,簡單地說 - SQL 字符串或數字)都必須通過准備好的語句添加。 沒有例外。
  2. 任何其他查詢部分,例如 SQL 關鍵字、表或字段名稱或運算符 - 都必須通過白名單進行過濾。

因此,由於您的示例僅涉及數據文字,因此必須通過占位符(也稱為參數)添加所有變量。 為此:

  • 在您的 SQL 語句中,將所有變量替換為占位符
  • 准備結果查詢
  • 將變量綁定到占位符
  • 執行查詢

以下是如何使用所有流行的 PHP 數據庫驅動程序:

使用 mysql ext 添加數據文字

不存在這樣的驅動程序。

使用mysqli添加數據文字

$type = 'testing';
$reporter = "John O'Hara";
$query = "INSERT INTO contents (type, reporter, description) 
             VALUES(?, ?, 'whatever')";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("ss", $type, $reporter);
$stmt->execute();

代碼有點復雜,但所有這些運算符的詳細解釋可以在我的文章中找到,如何使用 Mysqli 運行 INSERT 查詢,以及顯着簡化該過程的解決方案。

對於 SELECT 查詢,您只需要添加對get_result()方法的調用即可獲得熟悉的mysqli_result ,您可以通過通常的方式從中獲取數據:

$reporter = "John O'Hara";
$stmt = $mysqli->prepare("SELECT * FROM users WHERE name=?");
$stmt->bind_param("s", $reporter);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc(); // or while (...)

使用 PDO 添加數據文字

$type = 'testing';
$reporter = "John O'Hara";
$query = "INSERT INTO contents (type, reporter, description) 
             VALUES(?, ?, 'whatever')";
$stmt = $pdo->prepare($query);
$stmt->execute([$type, $reporter]);

在 PDO 中,我們可以將 bind 和 execute 部分結合起來,非常方便。 PDO 還支持命名占位符,有些人覺得這非常方便。

添加關鍵字或標識符

有時我們必須添加一個表示查詢的另一部分的變量,例如關鍵字或標識符(數據庫、表或字段名稱)。 這是一種罕見的情況,但最好做好准備。

在這種情況下,必須根據腳本中明確寫入的值列表檢查您的變量。 這在我的另一篇文章中進行了解釋,根據用戶的選擇在 ORDER BY 子句中添加字段名稱

不幸的是,PDO 沒有標識符(表和字段名)的占位符,因此開發人員必須手動過濾掉它們。 這樣的過濾器通常稱為“白名單”(我們只列出允許的值),而不是列出不允許的值的“黑名單”。

因此,我們必須明確列出 PHP 代碼中所有可能的變體,然后從中進行選擇。

這是一個例子:

$orderby = $_GET['orderby'] ?: "name"; // set the default value
$allowed = ["name","price","qty"]; // the white list of allowed field names
$key = array_search($orderby, $allowed, true); // see if we have such a name
if ($key === false) { 
    throw new InvalidArgumentException("Invalid field name"); 
}

方向應該使用完全相同的方法,

$direction = $_GET['direction'] ?: "ASC";
$allowed = ["ASC","DESC"];
$key = array_search($direction, $allowed, true);
if ($key === false) { 
    throw new InvalidArgumentException("Invalid ORDER BY direction"); 
}

在這樣的代碼之后, $direction$orderby變量都可以安全地放入 SQL 查詢中,因為它們要么等於允許的變體之一,要么會引發錯誤。

關於標識符的最后一件事是,它們還必須根據特定的數據庫語法進行格式化。 對於 MySQL,它應該是標識符周圍的backtick字符。 因此,我們的示例訂單的最終查詢字符串將是

$query = "SELECT * FROM `table` ORDER BY `$orderby` $direction";

為避免 SQL 注入,插入語句與 be

$type = 'testing';
$name = 'john';
$description = 'whatever';

$con = new mysqli($user, $pass, $db);
$stmt = $con->prepare("INSERT INTO contents (type, reporter, description) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $type , $name, $description);
$stmt->execute();

只要是字符串-您必須將其放在引號中

$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')");

而且,是的,正如Dani所建議的那樣:您應該使用mysql_real_escape_string()清理查詢中輸入的每個字符串。

最好的選擇是准備好的陳述。 開始使用引號和轉義符是一項更難的工作,也難以維護。 遲早你會不小心忘記引用某些內容,或者兩次轉義相同的字符串,或者搞砸類似的事情。 可能需要幾年時間才能找到這些類型的錯誤。

http://php.net/manual/en/pdo.prepared-statements.php

嘗試這個:

$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')");

您需要輸入'$type'而不僅僅是$ type

$type 中的文本直接替換為插入字符串,因此 MySQL 得到:

... VALUES(testing, 'john', 'whatever')

請注意,測試周圍沒有引號,您需要像這樣輸入:

$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')");

我還建議您閱讀SQL injection ,因為如果您不清理正在使用的數據,這種參數傳遞很容易遭到黑客攻擊:

這是簡單的答案:

$query="SELECT * FROM CountryInfo WHERE Name = '".$name."'";

並且您可以根據需要定義$name
另一種方式,復雜的方式,是這樣的:

$query = " SELECT '" . $GLOBALS['Name'] . "' .* " .
         " FROM CountryInfo " .
         " INNER JOIN District " .
         " ON District.CountryInfoId = CountryInfo.CountryInfoId " .
         " INNER JOIN City " .
         " ON City.DistrictId = District.DistrictId " .
         " INNER JOIN '" . $GLOBALS['Name'] . "' " .
         " ON '" . $GLOBALS['Name'] . "'.CityId = City.CityId " .
         " WHERE CountryInfo.Name = '" . $GLOBALS['CountryName'] .
         "'";
Try This simply 
$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) 
 VALUES('$type', 'john', 'whatever')");

如果變量包含用戶輸入或您不信任的其他數據,請確保對數據進行轉義。 像這樣:

$query = sprintf("INSERT INTO contents (type) VALUES ('%s')", mysql_real_escape_string($type));
$result = mysql_query($query);

我知道這個問題有一些答案,但是我想我要補充一點,如果您遵循以下語法,則我再也不會遇到該錯誤的問題。 毫無疑問,您正在使用哪個表以及要追加哪些列。

$query    = "INSERT INTO contents (type, reporter, description) 
         VALUES('".$type."', '".$reporter."', '"$whatever."')";

您必須在單引號或雙引號中寫入變量,然后在括號中加上變量名稱(例如:$ abc)。

例:

SELECT * FROM log WHERE id = '{$id}';

我正在嘗試在內容表中插入值。 如果我在VALUES內沒有PHP變量,則效果很好。 當我將變量$type放入VALUES此操作將無效。 我究竟做錯了什么?

$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) 
     VALUES($type, 'john', 'whatever')");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM