建立測試存儲過程
DELIMITER //
CREATE PROCEDURE pro_reg(
IN nc VARCHAR(50), IN pwd VARCHAR(50),
IN email VARCHAR(50), IN address VARCHAR(50)
)
BEGIN
INSERT INTO tb_reg (name, pwd, email, address) VALUES (nc, pwd, email, address);
END //
DELIMITER ;
方法一:mysqli 物件導向(推薦)
<?php
$mysqli = new mysqli('localhost', 'root', '12345', 'test');
if ($mysqli->connect_errno) die('Connect failed: ' . $mysqli->connect_error);
$nc = 'user1'; $pwd = 'pass'; $email = 'a@b.com'; $address = 'Taipei';
// 使用預處理防止注入
$stmt = $mysqli->prepare("CALL pro_reg(?, ?, ?, ?)");
$stmt->bind_param('ssss', $nc, $pwd, $email, $address);
if ($stmt->execute()) {
echo "";
} else {
echo "";
}
$stmt->close();
$mysqli->close();
?>
方法二:mysqli 多結果集處理(有 SELECT 回傳)
$link = mysqli_connect('localhost', 'root', '12345', 'test');
$query_id = mysqli_query($link, 'CALL my_select()');
do {
if ($result = mysqli_store_result($link)) {
while ($row = mysqli_fetch_assoc($result)) {
echo $row['a'] . '
';
}
mysqli_free_result($result);
}
} while (mysqli_next_result($link)); // 關鍵:推進到下一個結果集
mysqli_close($link);
方法三:舊 mysql 擴充(已棄用,僅供維護舊專案參考)
$host = 'localhost'; $user = 'root'; $pwd = '11212'; $db = 'samp_db';
$dblink = mysql_connect($host, $user, $pwd) or die("can't connect");
mysql_select_db($db, $dblink) or die("can't select db");
// IN/INOUT 參數:先設定用戶變數
mysql_query("SET @a = '$pwd'", $dblink);
// 呼叫過程
mysql_query("CALL aa(@a)", $dblink);
// 取得 OUT 參數
$res = mysql_query("SELECT @a", $dblink);
$row = mysql_fetch_row($res);
echo $row[0];
mysql_close($dblink);
關鍵要點總結
- 預處理 + 參數綁定:防 SQL 注入、型別安全。
- 多結果集:
mysqli_next_result() 迴圈處理存儲過程可能返回的多個 SELECT。
- OUT/INOUT 參數:MySQL 使用用戶變數
@var 傳遞,呼叫後 SELECT @var 取值。
- 錯誤處理:檢查
$stmt->errno / $mysqli->errno,記錄日誌而非直接輸出。
- 棄用 mysql_*:PHP 7.0+ 已移除,務必遷移至 mysqli 或 PDO。
PDO 版本(現代標準)
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '12345');
$stmt = $pdo->prepare('CALL pro_reg(?, ?, ?, ?)');
$stmt->execute([$nc, $pwd, $email, $address]);