PHP Conference Japan 2024

mysqli::prepare

mysqli_prepare

(PHP 5, PHP 7, PHP 8)

mysqli::prepare -- mysqli_prepare準備要執行的 SQL 陳述式

說明

物件導向風格

public mysqli::prepare(字串 $query): mysqli_stmt|false

程序風格

mysqli_prepare(mysqli $mysql, 字串 $query): mysqli_stmt|false

準備 SQL 查詢,並返回一個語句控制代碼,用於對該語句進行後續操作。查詢必須只包含單個 SQL 語句。

語句模板可以包含零個或多個問號 (?) 參數標記,也稱為佔位符。在執行語句之前,必須使用 mysqli_stmt_bind_param() 將參數標記綁定到應用程式變數。

參數

mysql

僅限程序式風格:由 mysqli_connect()mysqli_init() 返回的 mysqli 物件

query

查詢,以字串形式表示。它必須只包含單個 SQL 語句。

SQL 語句可以在適當的位置包含零個或多個由問號 (?) 字元表示的參數標記。

注意事項:

標記僅在 SQL 語句中的特定位置合法。例如,它們允許在 INSERT 語句的 VALUES() 列表中(用於指定行的欄位值),或在 WHERE 子句中與欄位進行比較以指定比較值。但是,它們不允許用於識別符號(例如表格或欄位名稱)。

返回值

mysqli_prepare() 返回一個語句物件,如果發生錯誤則返回 false

錯誤/例外

如果啟用了 mysqli 錯誤報告 (MYSQLI_REPORT_ERROR) 且請求的操作失敗,則會產生警告。此外,如果模式設定為 MYSQLI_REPORT_STRICT,則會改為拋出 mysqli_sql_exception

範例

範例 #1 mysqli::prepare() 範例

物件導向風格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

$city = "Amersfoort";

// 建立一個預備語句
$stmt
= $mysqli->prepare("SELECT District FROM City WHERE Name=?");

// 綁定參數
$stmt
->bind_param("s", $city);

// 執行查詢
$stmt
->execute();

// 綁定結果變數
$stmt
->bind_result($district);

// 取得值
$stmt
->fetch();

printf("%s 位於 %s 區\n", $city, $district);

程序風格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

$city = "Amersfoort";

/* 建立一個預備語句 */
$stmt = mysqli_prepare($link, "SELECT District FROM City WHERE Name=?");

/* 綁定標記的參數 */
mysqli_stmt_bind_param($stmt, "s", $city);

/* 執行查詢 */
mysqli_stmt_execute($stmt);

/* 綁定結果變數 */
mysqli_stmt_bind_result($stmt, $district);

/* 取得值 */
mysqli_stmt_fetch($stmt);

printf("%s 位於 %s 區\n", $city, $district);

以上範例將輸出

Amersfoort is in district Utrecht

另請參閱

新增註解

使用者貢獻的註解 20 則註解

210
timchampion dot NOSPAM at gmail dot com
12 年前
只是想確保大家都知道 get_result。

在程式碼範例中,在 execute() 之後,執行 get_result() 如下

<?php

// ... 文件的範例程式碼:

/* 綁定標記參數 */
$stmt->bind_param("s", $city);

/* 執行查詢 */
$stmt->execute();

/* 取代 bind_result: */
$result = $stmt->get_result();

/* 現在您可以將結果擷取到陣列中 - 真棒 */
while ($myrow = $result->fetch_assoc()) {

// 像使用任何其他擷取方式一樣使用您的 $myrow 陣列
printf("%s 位於 %s 區\n", $city, $myrow['district']);

}
?>

當您的查詢返回十幾個或更多欄位時,這樣做會更好。希望這有幫助。
61
Darren
12 年前
我編寫這個函式供個人使用,並想分享它。我不確定這是否是合適的論壇,但我希望我在偶然發現 mysqli::prepare 時能有這個。這個函式是我之前發布的函式的更新版本。先前的函式無法處理多個查詢。

對於查詢
單個查詢的結果以陣列 [列號][關聯資料陣列] 的形式給出
多個查詢的結果以陣列 [查詢號][列號][關聯資料陣列] 的形式給出

對於返回受影響列數的查詢,返回受影響的列數而不是 (陣列 [列號][關聯資料陣列])

程式碼和範例如下

<?php
function mysqli_prepared_query($link,$sql,$typeDef = FALSE,$params = FALSE){
if(
$stmt = mysqli_prepare($link,$sql)){
if(
count($params) == count($params,1)){
$params = array($params);
$multiQuery = FALSE;
} else {
$multiQuery = TRUE;
}

if(
$typeDef){
$bindParams = array();
$bindParamsReferences = array();
$bindParams = array_pad($bindParams,(count($params,1)-count($params))/count($params),"");
foreach(
$bindParams as $key => $value){
$bindParamsReferences[$key] = &$bindParams[$key];
}
array_unshift($bindParamsReferences,$typeDef);
$bindParamsMethod = new ReflectionMethod('mysqli_stmt', 'bind_param');
$bindParamsMethod->invokeArgs($stmt,$bindParamsReferences);
}

$result = array();
foreach(
$params as $queryKey => $query){
foreach(
$bindParams as $paramKey => $value){
$bindParams[$paramKey] = $query[$paramKey];
}
$queryResult = array();
if(
mysqli_stmt_execute($stmt)){
$resultMetaData = mysqli_stmt_result_metadata($stmt);
if(
$resultMetaData){
$stmtRow = array();
$rowReferences = array();
while (
$field = mysqli_fetch_field($resultMetaData)) {
$rowReferences[] = &$stmtRow[$field->name];
}
mysqli_free_result($resultMetaData);
$bindResultMethod = new ReflectionMethod('mysqli_stmt', 'bind_result');
$bindResultMethod->invokeArgs($stmt, $rowReferences);
while(
mysqli_stmt_fetch($stmt)){
$row = array();
foreach(
$stmtRow as $key => $value){
$row[$key] = $value;
}
$queryResult[] = $row;
}
mysqli_stmt_free_result($stmt);
} else {
$queryResult[] = mysqli_stmt_affected_rows($stmt);
}
} else {
$queryResult[] = FALSE;
}
$result[$queryKey] = $queryResult;
}
mysqli_stmt_close($stmt);
} else {
$result = FALSE;
}

if(
$multiQuery){
return
$result;
} else {
return
$result[0];
}
}
?>

範例
對於 firstName 和 lastName 的表格
John Smith
Mark Smith
Jack Johnson
Bob Johnson

<?php
//單一查詢,單一結果
$query = "SELECT * FROM names WHERE firstName=? AND lastName=?";
$params = array("Bob","Johnson");

mysqli_prepared_query($link,$query,"ss",$params)
/*
回傳陣列(
0=> array('firstName' => 'Bob', 'lastName' => 'Johnson')
)
*/

//單一查詢,多重結果
$query = "SELECT * FROM names WHERE lastName=?";
$params = array("Smith");

mysqli_prepared_query($link,$query,"s",$params)
/*
回傳陣列(
0=> array('firstName' => 'John', 'lastName' => 'Smith')
1=> array('firstName' => 'Mark', 'lastName' => 'Smith')
)
*/

//多重查詢,多重結果
$query = "SELECT * FROM names WHERE lastName=?";
$params = array(array("Smith"),array("Johnson"));

mysqli_prepared_query($link,$query,"s",$params)
/*
回傳陣列(
0=>
array(
0=> array('firstName' => 'John', 'lastName' => 'Smith')
1=> array('firstName' => 'Mark', 'lastName' => 'Smith')
)
1=>
array(
0=> array('firstName' => 'Jack', 'lastName' => 'Johnson')
1=> array('firstName' => 'Bob', 'lastName' => 'Johnson')
)
)
*/
?>

希望有幫助 =)
2
urso at email dot cz
2 年前
很遺憾,使用 "/* 綁定 結果 變數 */ $stmt->bind_result($district);" 已經過時且不被建議。

<?php
$mysqli
= new mysqli("localhost", "test", "test", "test");
if (
$mysqli->character_set_name()!="utf8mb4") { $mysqli->set_charset("utf8mb4"); }
$secondname = "Ma%";
$types = "s";
$parameters = array($secondname);
$myquery = "select * from users where secondname like ?";
if (
$stmt = $mysqli->prepare($myquery)) {
$stmt->bind_param($types, ...$parameters);
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
$numrows = $result->num_rows;
while(
$row = $result->fetch_assoc()) {
echo
$row['firstname']." ".$row['secondname']."<br />";
}
}
$mysqli->close();
?>

此外,不要使用 '$stmt->bind_param("s", $city);',請使用 "$stmt->bind_param($types, ...$parameters);" 搭配陣列。這裡使用陣列 ($parameters) 的優點已經很明顯了,它使用一個包含 5 個元素的陣列,而不是 5 個變數。

<?php
$mysqli
= new mysqli("localhost", "test", "test", "test");
if (
$mysqli->character_set_name()!="utf8mb4") { $mysqli->set_charset("utf8mb4"); }
$uid = intval($_POST['uid']);
$length=15; $account = mb_substr(trim($_POST['account']),0,$length,"utf-8"); $account=strip_tags($account);
$length=50; $password = mb_substr(trim($_POST['password']),0,$length,"utf-8"); $password = password_hash($password, PASSWORD_DEFAULT);
$length=25; $prijmeni = mb_substr(trim($_POST['prijmeni']),0,$length,"utf-8"); $prijmeni=strip_tags($prijmeni);
$length=25; $firstname = mb_substr(trim($_POST['firstname']),0,$length,"utf-8"); $firstname=strip_tags($firstname); $firstname = str_replace(array(">","<",'"'), array("","",""), $firstname);
$dotaz = "UPDATE users SET account = ?, password = ?, secname = ?, firstname = ? WHERE uid = ?";
$types = "ssssi";
$parameters = array($account,$password,$prijmeni,$firstname,$uid);
if (
$stmt = $mysqli->prepare($dotaz)) {
$stmt->bind_param($types, ...$parameters);
$stmt->execute();
echo
$stmt->affected_rows;
$stmt->close();
}
$mysqli->close();
?>
7
kritz at hrz dot tu-chemnitz dot de
7 年前
我無法完整測試以下程式碼,因為我目前工作的伺服器缺少允許我在 mysqli_stmt 上呼叫 get_result 的 PHP 模組,但也許這對某些人會有幫助

<?php

/**
* Custom {@link \mysqli} class with additional functions.
*/
class CustomMysqli extends \mysqli
{
/**
* Creates a prepared query, binds the given parameters and returns the result of the executed
* {@link \mysqli_stmt}.
* @param string $query
* @param array $args
* @return bool|\mysqli_result
*/
public function queryPrepared($query, array $args)
{
$stmt = $this->prepare($query);
$params = [];
$types = array_reduce($args, function ($string, &$arg) use (&$params) {
$params[] = &$arg;
if (
is_float($arg)) $string .= 'd';
elseif (
is_integer($arg)) $string .= 'i';
elseif (
is_string($arg)) $string .= 's';
else
$string .= 'b';
return
$string;
},
'');
array_unshift($params, $types);

call_user_func_array([$stmt, 'bind_param'], $params);

$result = $stmt->execute() ? $stmt->get_result() : false;

$stmt->close();

return
$result;
}
}

$db = new CustomMysqli('host', 'user', 'password', 'database', 3306);
$result = $db->queryPrepared(
'SELECT * FROM table WHERE something = ? AND someotherthing = ? AND elsewhat = ?',
[
'dunno',
1,
'dontcare'
]
);

if (isset(
$result) && $result instanceof \mysqli_result) {
while (
null !== ($row = $result->fetch_assoc())) {
echo
'<pre>'.var_debug($row, true).'</pre>';
}
}

?>

注意:如果您想在 5.4 以下的 PHP 版本中使用它,您必須使用舊的 array() 語法來表示陣列,而不是簡短的 [] 語法。
10
admin at xorath dot com
17 年前
效能注意事項:我執行了一個測試,首先插入大約 30,000 個帶有一個主鍵 id 和一個 varchar(20) 的文章,其中 varchar 資料是目前迭代器值的 md5 雜湊,只是為了填充一些資料。

該測試是在一台專用的 Ubuntu 7.04 伺服器上執行的,該伺服器配備了 Apache2/PHP5/MySQL5.0,運行在 Athlon 64 - 3000+ 處理器和 512MB 記憶體上。 查詢是使用 for 迴圈從 0 到 30000 進行測試的,首先使用

<?php
for ( $i = 0; $i <= 30000; ++$i )
{
$result = $mysqli->query("SELECT * FROM test WHERE id = $i");
$row = $result->fetch_row();
echo
$row[0]; //印出 id
}
?>

這樣的寫法,頁面載入時間平均約為 3.3 秒,然後用以下迴圈

<?php
$stmt
= $mysqli->prepare("SELECT * FROM test WHERE id = ?");
for (
$i = 0; $i <= 30000; ++$i )
{
$stmt->bind_param("i", $i);
$stmt->execute();
$stmt->bind_result($id, $md5);
$stmt->fetch();
echo
$id;
}
$stmt->close();
?>

平均頁面載入時間降低了 1.3 秒,也就是平均約 2.0 秒!猜想在更複雜/更大的資料表和更複雜的 SQL 查詢中,效能差異可能會更大。
9
Codeguy
13 年前
在 SQL 中使用預備語句的真正目的是降低處理查詢的成本,而不是將資料與查詢分開。這是它現在在 PHP 中的使用方式,而不是它最初設計的使用方式。在 SQL 中,您可以透過使用預備語句來降低執行多個類似查詢的成本。這樣做可以省去解析、驗證,並且通常會預先產生查詢的執行計畫。這就是為什麼它們在迴圈中比直接查詢的執行速度更快的原因。不要因為有人以這種方式使用 PHP 和這個函式就認為這是唯一或正確的做法。雖然它比一般查詢更安全,但它們在功能上或更確切地說在執行方式上也更受限制。
7
cdtreeks at gmail dot com
9 年前
在執行預備好的 MySQL 語句時,如果發生錯誤,預設情況下 prepare() 呼叫只會回傳 FALSE。

要取得完整的 MySQL 錯誤訊息,請在準備查詢之前先建立一個語句物件,如下所示:

<?php
$mysqli
= new mysqli("localhost", "my_user", "my_password", "world");

/* 檢查連線 */
if (mysqli_connect_errno()) {
printf("連線失敗: %s\n", mysqli_connect_error());
exit();
}

$city = "Amersfoort";

/* 建立預備語句 */
$statement = $mysqli->stmt_init();
if (
$statement->prepare("SELECT District FROM City WHERE Name=?")) {

/* 綁定佔位符號的參數 */
$statement->bind_param("s", $city);

/* 執行查詢 */
if (!$statement->execute()) {
trigger_error('執行 MySQL 查詢時發生錯誤:' . $statement->error);
}

/* 綁定結果變數 */
$statement->bind_result($district);

/* 取得值 */
$statement->fetch();

printf("%s 位於 %s 區\n", $city, $district);

/* 關閉語句 */
$statement->close();
}

/* 關閉連線 */
$mysqli->close();
?>
6
omidbahrami1990 at gmail dot com
6 年前
這是使用 mysqli::prepare 的安全方法
--------------------------------------------------------
<?php
函式 secured_signup($username,$password)
{
$connection = new mysqli($dbhost,$dbusername,$dbpassword,$dbname);
如果 (
$connection->connect_error)
die(
"安全");

$prepared = $connection->prepare("INSERT INTO `users` ( `username` , `password` ) VALUES ( ? , ? ) ; ");
如果(
$prepared==false)
die(
"安全");

$result=$prepared->bind_param("ss",$username,$password);
如果(
$result==false)
die(
"安全");

$result=$prepared->execute();
如果(
$result==false)
die(
"安全");

$prepared->close();
$connection->close();
}
/*
$dbhost ---> 資料庫IP位址
$dbusername ---> 資料庫使用者名稱
$dbpassword ---> 資料庫密碼
$dbname ---> 資料庫名稱
*/
?>
5
David Kramer
18 年前
我認為這些不是好的範例,因為預備查詢的主要用途是在迴圈中呼叫相同的查詢,每次插入不同的值。例如,如果您正在產生報告,並且需要為每一行執行相同的查詢,調整 WHERE 子句中的值,或從另一個系統導入資料。
3
Darren
12 年前
對於第一次學習 mysqli::prepare 和 mysqli_stmt::bind_params 的人來說,這裡有一個帶註釋的程式碼區塊,它執行預備查詢並以類似於 mysqli_query 返回值的格式返回資料。我試圖盡量減少不必要的類別、物件或額外開銷,原因有二
1) 方便學習
2) 允許與 mysqli_query 相對互換使用

我的目標是降低任何開始使用這些函式的人的學習曲線。我絕不是一個專業的程式設計師/腳本撰寫者,所以我相信一定有改進的空間,也許還有一些錯誤,但我希望沒有 =)

<?php
/*
Function: mysqli_prepared_query()
Executes prepared querys given query syntax, and bind parameters
Returns data in array format

Arguments:
mysqli_link
mysqli_prepare query
mysqli_stmt_bind_param argmuent list in the form array($typeDefinitinonString, $var1 [, mixed $... ])

Return values:
When given SELECT, SHOW, DESCRIBE or EXPLAIN statements: returns table data in the form resultArray[row number][associated field name]
Returns number of rows affacted when given other queries
Returns FALSE on error
*/
function mysqli_prepared_query($link,$sql,$bindParams = FALSE){
if(
$stmt = mysqli_prepare($link,$sql)){
if (
$bindParams){
$bindParamsMethod = new ReflectionMethod('mysqli_stmt', 'bind_param'); //allows for call to mysqli_stmt->bind_param using variable argument list
$bindParamsReferences = array(); //will act as arguments list for mysqli_stmt->bind_param

$typeDefinitionString = array_shift($bindParams);
foreach(
$bindParams as $key => $value){
$bindParamsReferences[$key] = &$bindParams[$key];
}

array_unshift($bindParamsReferences,$typeDefinitionString); //returns typeDefinition as the first element of the string
$bindParamsMethod->invokeArgs($stmt,$bindParamsReferences); //calls mysqli_stmt->bind_param suing $bindParamsRereferences as the argument list
}
if(
mysqli_stmt_execute($stmt)){
$resultMetaData = mysqli_stmt_result_metadata($stmt);
if(
$resultMetaData){
$stmtRow = array(); //this will be a result row returned from mysqli_stmt_fetch($stmt)
$rowReferences = array(); //this will reference $stmtRow and be passed to mysqli_bind_results
while ($field = mysqli_fetch_field($resultMetaData)) {
$rowReferences[] = &$stmtRow[$field->name];
}
mysqli_free_result($resultMetaData);
$bindResultMethod = new ReflectionMethod('mysqli_stmt', 'bind_result');
$bindResultMethod->invokeArgs($stmt, $rowReferences); //calls mysqli_stmt_bind_result($stmt,[$rowReferences]) using object-oriented style
$result = array();
while(
mysqli_stmt_fetch($stmt)){
foreach(
$stmtRow as $key => $value){ //variables must be assigned by value, so $result[] = $stmtRow does not work (not really sure why, something with referencing in $stmtRow)
$row[$key] = $value;
}
$result[] = $row;
}
mysqli_stmt_free_result($stmt);
} else {
$result = mysqli_stmt_affected_rows($stmt);
}
mysqli_stmt_close($stmt);
} else {
$result = FALSE;
}
} else {
$result = FALSE;
}
return
$result;
}

?>

希望 PHP 之神不會懲罰我。
1
Bernie van&#39;t Hof
12 年前
預備語句一開始會讓人感到困惑..

mysqli->prepare() 返回一個所謂的語句物件,用於後續的操作,例如 execute、bind_param、store_result、bind_result、fetch 等。

語句物件具有私有屬性,這些屬性會隨著每個語句操作的執行而更新。我發現這些屬性對於理解編寫預備語句函式時發生的事情很有用

affected_rows(受影響的列數)
insert_id(插入的ID)
num_rows(列數)
param_count(參數計數)
field_count(欄位計數)
errno(錯誤號)
error(錯誤訊息)
sqlstate(SQL狀態)
id(ID)

但是我花了一點時間才弄懂如何存取它們

<?php
$stmt
= $mysqli->prepare($query);

// .. $stmt-> 操作 ..

var_dump($stmt); // 顯示 null 值

var_dump($stmt->errno); // 注意字面量,顯示值

// .. $stmt-> 操作 ..

// 為了保留副本 ..
// get_object_properties() 無法運作
// clone() 無法運作
$properties = array();
foreach (
$stmt as $name => $priv){
$properties[$name] = $stmt->$name; // 可以運作
// $properties[$name] = $priv; // 無法運作,foreach 無法訪問私有屬性
}

$stmt->close();
// var_dump($stmt->errno) // 無法運作,$stmt 已關閉
?>
3
REz
10 年前
沒有任何參考資料說明在再次呼叫 msqli 的 prepare 之前必須提取所有數據,唯一的幫助是在 6 年前的評論中!
您必須使用 myslqi_stmt::fetch() 提取數據,直到返回 NULL,才能再次呼叫 mysqli::prepare(),而不會在 mysqli::$errno 和 mysqli::$error 中出現 FALSE 且没有任何錯誤。
3
Adam
18 年前
預備語句的目的是不要在 SQL 語句中包含數據。將它們包含在 SQL 語句中並不安全。請務必使用預備語句。它們使用起來更簡潔(程式碼更易於閱讀),而且不易受到 SQL 注入的影響。

在某些地區設定中,對要在 SQL 語句中包含的字串進行跳脫處理的效果並不好,因此並不安全。
5
codeFiend <aeontech at gmail dot com>
18 年前
請注意,參數標記周圍的單引號 _會_ 阻止您的語句被正確地準備。
例如:

<?php
$stmt
= $mysqli->prepare("INSERT INTO City (District) VALUES ('?')");
echo
$stmt->param_count." parameters\n";
?>
將會印出 0 並且在您嘗試將變數綁定到它時失敗,並顯示「變數數量與預備語句中的參數數量不符」的警告。

但是:

<?php
$stmt
= $mysqli->prepare("INSERT INTO City (District) VALUES (?)");
echo
$stmt->param_count." parameters\n";
?>
將會印出 1 並且正常運作。

非常惱人,我花了一個小時才弄清楚這一點。
1
wapharshitsingh at gmail dot com
3 年前
只是想在這裡分享,我們如何有效地將預備語句與 ... 運算符結合使用。
<?php
class Database{
private function
getTypeofValues($string, $value){
if(
is_float($value)){
$string .= "d";
}elseif(
is_integer($value)){
$string .= "i";
}elseif(
is_string($value)){
$string .= "s";
}else{
$string .= "b";
}
return
$string;
}
public function
makeQuery($query, array $values){
$stmt = $this->connection->prepare($query);
$type = array_reduce($values, array($this, "getTypeOfValues"));
$stmt->bind_param($type, ...$values);
$stmt->execute();
$result = $stmt->get_result();
return
$result;
}
}
?>
-1
rafael at stiod dot com
16 年前
所有資料都必須在準備新的陳述式之前擷取完畢。
-2
@runspired
11 年前
我不認為這是個 bug,只是一個非預期的行為。在建構 API 時,我發現將整數 0 而不是字串 '0' 傳遞到準備好的陳述式中,導致我的腳本耗盡記憶體並在網頁上產生 500 錯誤。

以下是這個問題的簡化範例:($_DB 是 mysqli 連線的全域參考)

<?php
function getItem( $ID ) {

$_STATEMENT = $_DB->prepare("SELECT item_user, item_name, item_description FROM item WHERE item_id = ?;");

$_STATEMENT->bind_param( 'i' , $ID );

$_STATEMENT->execute();
$_STATEMENT->store_result();

$_STATEMENT->bind_result( $user , $name , $description);
$result = $_STATEMENT->fetch();

$_STATEMENT->free_result();
$_STATEMENT->close();

return
$result;
}

getItem(0); //失敗!
getItem('0'); //成功!

?>

我所能猜到的最好的情況是,整數 0 被轉換為布林值,如果確實如此,應該在上方文件說明,但我所有嘗試獲取錯誤訊息(透過 php 腳本)的努力都失敗了。
-2
sdepouw at NOSPAM dot com
15 年前
我不知道這對其他人來說有多明顯,但如果您嘗試為資料庫中不存在的表格準備查詢(或者如果您的查詢以其他方式無效,我想),則不會返回物件。我只是在深入挖掘後才注意到這一點,因為我一直收到一個致命錯誤,說我的語句變數沒有設定為物件的實例(它可能是空的)。

將 NOSPAM 替換為 nimblepros 即可發送電子郵件給我。
-4
Zeebuck
13 年前
我認為它最初構建的目的和人們今天使用它的目的已經不同了。但為什麼要糾結於最初的目的呢?顯然,今天已經在預備語句中投入了更多程式碼,使其可以用於防止 SQL 注入,因此它現在是設計目標的一部分,以及可重複語句的效能。
-4
marmstro at gmail dot com
11 年前
如果您的 IDE 在您使用傳統的 prepare 時無法辨識 $stmt 作為 mysqli_stmt 類型的物件

$stmt = mysqli_prepare($link, $query);

以下程式碼有效且對 IDE 友好

$stmt = new mysqli_stmt($link, $query);
To Top