我正在尝试使用单个文本框的页面,用户在该文本框中输入用户编号并单击下一步。触发脚本。该脚本使用输入的数字并查找与该数字相关联的任何名称,然后显示它们。
显示的名称也可用作继续脚本第二部分的链接。每个链接都引用这些名称在数据库中具有的ID。当我们移动到另一个表时,单击一个使我们使用activeID
。
到目前为止,这是我正在使用的内容。我还没有设置表单条目。
//Form for single box entry of an ID for user to enter. $uID
//Find the localID from the entered uID in accounts table
$stmt = mysqli_prepare(@mysqli, "SELECT `ID` FROM `accounts` WHERE userID = $uID;");
//Do I need to scrub input if using prepare?
mysqli_bind_result($stmt, $localID);
mysqli_stmt_execute($stmt);
mysqli_stmt_fetch($stmt);
//Get the character from the accounts id
SELECT * FROM `character` WHERE AccountID=$localID
//I don't know how to loop buffered data now, I need to get and display all names associated with that ID
//They can click one of the results to continue, setting $activeID to the ID that that name corresponded with
$activeID = ID of clicked result
SELECT * FROM `stats` WHERE Character=$activeID
//Display Stat name and value for all returned lists
答案 0 :(得分:1)
我不确定究竟是什么问题,但我在代码中提到了一些问题,实际上是代码。
调用mysqli函数的顺序应为:
mysqli_prepare
(将声明交给mysql)mysqli_stmt_bind_param
(填补数据空白)mysqli_stmt_execute
(使用数据执行查询)mysqli_stmt_bind_result
(命名结果应该具有的变量)mysqli_stmt_fetch
(将数据行加载到您在步骤4中命名的变量)mysqli_stmt_close
(关闭声明。否则会出现不同步错误)如果你使用准备好的语句,这是非常好的,因为防止sql注入,你应该不准备一个像
这样的字符串$stmt = mysqli_prepare(@mysqli, "...userID = $uID;");
这样就会失去准备好的陈述的安全性。更好地做到这一点:
$stmt = mysqli_prepare('...userId = ?;');
mysqli_stmt_bind_param($stmt, 'i', $uID);
你可以使用while循环遍历行:
mysqli_stmt_bind_result($stmt, $col1, $col2, ...);
while(mysqli_stmt_fetch($stmt))
{
echo $col1;
echo $col2;
// do something else
}
注意: mysqli_get_result
并非总是有效。要使用它,您需要安装mysql本机驱动程序。首先检查您的php_info()
。
$stmt = mysqli_prepare('SELECT col1, col2 FROM table WHERE col_x = ? AND col_y = ?');
mysqli_bind_param($stmt,'is',$anInteger, $aString);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $col1, $col2);
while(mysqli_stmt_fetch($stmt))
{
echo $col1;
echo $col2;
// do something else
}
mysqli_stmt_close($stmt);
答案 1 :(得分:1)
正如我在你对你的问题的评论中所说,你真的没有一个问题,所以我只是向你展示一些MySQLi的例子,我认为是你的#39;重新开始;)
这些示例将向您展示如何使用MySQLi的参数化输入来正确执行写入(即INSERT,UPDATE,DELETE)和读取(即SELECT)语句。
<?php namespace Common;
define("DATABASE_HOST", "mysql.mywebsite.com");
define("DATABASE_USER", "my_database_username");
define("DATABASE_PASS", "gP#&hz]l>1Xg}UPFT+eZ@2qDEnVuD"); // Be careful if you use backslashes. -- if you use them, type them escaped, like "\\"
define("DATABASE_NAME", "my_database_name");
define("ERROR_LOG_FILE", $_SERVER["DOCUMENT_ROOT"]."/logs/errors.txt"); // Requires you to run CHMOD 777 via your FTP client on this directory and file
function DbConnect()
{
// Create database object and try to connect to database server.
$Conn = new \mysqli(DATABASE_HOST, DATABASE_USER, DATABASE_PASS);
if(mysqli_connect_errno())
LogAndDie("Failed to connect to DB in function ".(__FUNCTION__).", error: ".mysqli_connect_error());
// Try to select database.
if(!$Conn->select_db(DATABASE_NAME))
LogAndDie("Failed to select DB in function ".(__FUNCTION__).", error: ".$Conn->error);
// Return connected object.
return($Conn);
}
function LogAndDie($LogMessageText)
{
$timeNow = time();
$h = fopen(ERROR_LOG_FILE, 'ab');
fwrite($h, "TIMESTAMP ".($timeNow)." (".date('Y-m-d h:i A', $timeNow)."): ".$LogMessageText."\n");
fclose($h);
die("Sorry, there has been an error and the action could not be completed. The technical details of this error has been logged at time index ".$timeNow.". If this error persists, contact the website administrator and provide this time index to help fix the problem.");
}
function MyExampleWrite($myInteger, $myDouble, $myString)
{
$Conn = \Common\DbConnect();
$Stmnt =
(
'INSERT INTO _mytable '.
'(_myintcol, _mydoublecol _mystringcol) '.
'VALUES '.
'(?, ?, ?)'
);
if(!$PreparedStmnt = $Conn->prepare($Stmnt))
\Common\LogAndDie("Failed to prepare SQL statement in function ".(__FUNCTION__).", error: ".$Conn->error); // OR, you could return from this function, but don't forget to do "$Conn->close()"
$PreparedStmnt->bind_param
(
'ids', // i for Integer, d for Double, s for String
$myInteger,
$myDouble,
$myString
);
if(!$PreparedStmnt->execute())
\Common\LogAndDie("Failed to execute insert statement in function ".(__FUNCTION__).", error: ".$Conn->error); // OR, you could return from this function, but don't forget to do "$PreparedStmnt->close()" and "$Conn->close()"
// Optional. With INSERT statements, you can find the id of new row you inserted.
$insertedId = $PreparedStmnt->insert_id;
// Optional. With UPDATE and DELETE statements, you can find out the total number of rows changed, deleted, or inserted.
$numRowsAffected = $PreparedStmnt->affected_rows;
$PreparedStmnt->close();
$Conn->close();
}
function MyExampleRead($userEmail)
{
$Conn = \Common\DbConnect();
$Stmnt = "SELECT _userId FROM _usersTable WHERE _userEmail = ? LIMIT 1";
if(!$PreparedStmnt = $Conn->prepare($Stmnt))
\Common\LogAndDie("Failed to prepare SQL statement in function ".(__FUNCTION__).", error: ".$Conn->error); // OR, you could return from this function, but don't forget to do "$Conn->close()"
$PreparedStmnt->bind_param('s', $userEmail); // s for String
if(!$PreparedStmnt->execute())
\Common\LogAndDie("Failed to execute insert statement in function ".(__FUNCTION__).", error: ".$Conn->error); // OR, you could return from this function, but don't forget to do "$PreparedStmnt->close()" and "$Conn->close()"
$PreparedStmnt->bind_result($Result_UserId);
$FetchCount = 0;
while($PreparedStmnt->fetch())
{
// The binded result variable(s) should now be set.
echo("Result number ".$FetchCount." is: ".$Result_UserId);
$FetchCount++;
// Due to the LIMIT 1, There should only be one row returned, so this loop will exit after the first iteration.
}
$PreparedStmnt->close();
$Conn->close();
// Do something with your result
if($FetchCount <= 0 || $Result_UserId <= 0)
{
// No results retrieved by the query.
return 0;
}
// Return the retrieved userid.
return $Result_UserId;
}
插入和更新BLOB(例如图像,加密数据,压缩数据等)通常需要使用名为send_long_data()的特殊MySQLi方法。
function MyExampleWriteBlob($myImage)
{
$Conn = \Common\DbConnect();
$Stmnt =
(
'INSERT INTO _mytable '.
'(_myblobcol) '.
'VALUES '.
'(?)'
);
if(!$PreparedStmnt = $Conn->prepare($Stmnt))
\Common\LogAndDie("Failed to prepare SQL statement in function ".(__FUNCTION__).", error: ".$Conn->error); // OR, you could return from this function, but don't forget to do "$Conn->close()"
$Dummy = null; // The way MySQLi works, to insert binary data, we need to bind NULL into the prepared statement, and then follow it up with a send_long_data() function to insert the actual binary data
$PreparedStmnt->bind_param('b', $Dummy); // b for BLOB
$PreparedStmnt->send_long_data(0, $myImage); // 0 because it's the 1st parameter in our prepared stmnt (zero-based)
if(!$PreparedStmnt->execute())
\Common\LogAndDie("Failed to execute insert statement in function ".(__FUNCTION__).", error: ".$Conn->error); // OR, you could return from this function, but don't forget to do "$PreparedStmnt->close()" and "$Conn->close()"
$PreparedStmnt->close();
$Conn->close();
}
检索BLOB没什么特别的。只是选择字符串或int或double完全相同。小代码片段如下:
$Conn = \Common\DbConnect();
$Stmnt = "SELECT _myImage FROM _imageTable WHERE id = 1 LIMIT 1";
$PreparedStmnt = $Conn->prepare($Stmnt)
$PreparedStmnt->execute();
$PreparedStmnt->bind_result($myImage);
$PreparedStmnt->fetch()
$PreparedStmnt->close();
$Conn->close();
header("Content-Type: image/jpeg");
echo $myImage;