这里我的目标是使用我在文本框中设置的标题更新图书的信息。但是在我的代码中,当我运行时,我收到错误$query2
在$query2['status']=="Available"
中未定义。有人可以纠正我的错误吗?
<?php
$user="root";
$server="localhost";
$password="";
$db="library book";
$query=mysql_connect($server,$user,$password);
$dbRes = mysql_select_db($db,$query);
if(isset($_GET['book_id']))
{
$bookid = $_GET['book_id'];
$str="select * from books where bookid=$bookid";
$query1=mysql_query($str);
//echo $query1;
$query2=mysql_fetch_array($query1);
//print_r ($query2);
}
if(isset($_POST['Update']))
{
$title=mysql_real_escape_string($_POST['title']);
$author=mysql_real_escape_string($_POST['author']);
$publisher=mysql_real_escape_string($_POST['publisher']);
$numcopies=mysql_real_escape_string($_POST['numcopies']);
$shelfno=mysql_real_escape_string($_POST['shelfno']);
$status=mysql_real_escape_string($_POST['status']);
$str1="update books set title=$title where bookid=$bookid";
$query3=mysql_query($str1);
echo $query3;
$query4=mysql_query("select * from books");
$row=mysql_fetch_array($query3);
echo "<table>";
echo "<tr><th>BookID</th><th>Title</th><th>Author</th><th>Publisher</th><th>numcopies</th><th>shelfno</th><th>status</th><th>Action</th></tr>";
echo "<tr>";
echo "<td>".$row['bookid']."</td>";
echo "<td>".$row['title']."</td>";
echo "<td>".$row['author']."</td>";
echo "<td>".$row['publisher']."</td>";
echo "<td>".$row['numcopies']."</td>";
echo "<td>".$row['shelfno']."</td>";
echo "<td>".$row['status']."</td>";
echo "</tr>";
echo "</table>";
if ($query2['status']=="Available")
echo "selected";
if ($query2['status']=="Unavailable")
echo "selected";
}
?>
<html>
<head><title>Editing the fields</title>
<style>
body {
background-color: rgb(255,0,255);
}
</style>
</head>
<body>
<form action="edit1.php" action="post">
EnterTitle:<input type="text" name="title" value="<?php echo $query2['title'];?>">
<br/>
EnterAuthor:<input type="text" name="author" value="<?php echo $query2['author'];?>" >
<br/>
EnterPublisher:<input type="text" name="publisher" value="<?php echo $query2['publisher'];?>">
<br/>
EnterNumCopies:<input type="text" name="numcopies" value="<?php echo $query2['numcopies'];?>">
<br/>
EnterShelfNo:<input type="text" name="shelfno" value="<?php echo $query2['shelfno'];?>">
<br/>
<input type="hidden" name="bookid" value=<?php if(isset($bookid)) echo $bookid; ?>>
<select>
<option value="available" <?php if ($query2['status']=="Available") echo "selected";?>>Available</option>
<option value="unavailable" <?php if ($query2['status']=="Unavailable") echo "selected";?>>Unavailable</option>
</select>
<br>
<input type="submit" name="submit" value="Update">
</form>
</body>
</html>
答案 0 :(得分:1)
我想不幸的是,你在这里发生的是"spaghetti code"综合症的开始,所以你会想要投资学习PHP framework。您将面临更少的安全问题,您的脚本将从一开始就更清洁,更容易维护等。
对于此特定代码段,除其他外,您有sql injection个问题,您可以bookid
和$_GET
设置$_POST
,但很难确定哪个最好用,您的html发生在<html>
标记之上,但您遇到的主要问题是您拥有在if
范围内定义但在if
范围之外引用的变量因此,如果不满足if
条件,则会创建错误(See this example以供参考)。
除了修复范围问题之外的一些建议:
PDO
或mysqli_
参数绑定。我的示例使用PDO $query
,$query1
,$query2
等都会让人感到困惑。我已经使用过函数,但最好将bookid
内部传递给所有方法。book_id
或bookid
,而不是两者。我的示例使用bookid
。这可能存在一些缺陷,但希望它能为您提供一些有用的想法,正如我之前所说的,这将作为一个类(实际上是几个类)实现更有用,但使用函数可能是一个很好的开端来帮助清理你的脚本。
重要说明:我没有对此进行过测试(尽管应该没有语法错误),但您应该能够通过将版本与此版本并行来了解正在发生的事情以及所需的内容。如果你不理解它,请先阅读它,不要盲目复制和粘贴,否则你会遇到更多麻烦。正如他们所说,使用风险自负。
<强> /functions/getBooks.php 强>
# Create a general function to fetch all books.
function getBooks($con)
{
$result = array();
$query = $con->prepare("SELECT * FROM books");
$query->execute();
while($row = $query->fetch(PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $result;
}
<强> /functions/getBookById.php 强>
# Create a function to fetch a specific book by id
function getBookById($id,$con)
{
$query = $con->prepare("SELECT * FROM books WHERE bookid = :id");
$query->execute(array(":id"=>$id));
$row = $query->fetch(PDO::FETCH_ASSOC);
return (!empty($row))? $row : array();
}
<强> /functions/getBook.php 强>
# This should fetch from a global request, that way you can tell if
# a book is currently being accessed
function getBook($con)
{
autoload(array('getBookById','getId'));
$id = getId('req');
if(empty($id))
return false;
return getBookById($id,$con);
}
<强> /functions/updateBookById.php 强>
# Create an update function that can be accessed at anytime. Use binding
# so you don't need to mess with any sort of escaping
function updateBookById($id,$values,$con)
{
foreach($values as $keys => $vals) {
$bKey = ":{$keys}";
$bind[$bKey] = $vals;
$sql[] = '`'.$key.'` = '.$bKey;
}
$bind[":id"] = $id;
$query = $con->prepare("UPDATE books SET ".implode(', ',$sql)." WHERE bookid = :id");
$query->execute($bind);
}
<强> /functions/updateBookTitle.php 强>
# This is is just a specific function to focus on title. Not sure you need
# it since the update book by id function would do the same thing
function updateBookTitle($id,$title,$con)
{
$bind[":id"] = $id;
$bind[":title"] = $title;
$query = $con->prepare("UPDATE books SET title = :title WHERE bookid = :id");
$query->execute($bind);
}
<强> /functions/getId.php 强>
# This will fetch the id value from a global
function getId($type = false)
{
switch($type) {
case('post'):
return (isset($_POST['bookid']))? $_POST['bookid'] : false;
case('req'):
return (isset($_REQUEST['bookid']))? $_REQUEST['bookid'] : false;
default:
return (isset($_GET['bookid']))? $_GET['bookid'] : false;
}
}
<强> /functions/bookObserver.php 强>
# This will sit and just wait for the right globals activate it
function bookObserver($con,&$curr)
{
autoload('getId');
if(getId('req')) {
autoload('getBookById');
$books = getBookById(getId('req'),$con);
if(!empty($books))
$curr = $books;
if(isset($_POST['Update'])) {
$values = array(
'title' => $_POST['title'],
'author' => $_POST['author'],
'publisher' => $_POST['publisher'],
'numcopies' => $_POST['numcopies'],
'shelfno' => $_POST['shelfno'],
'status' => $_POST['status']
);
autoload('updateBookById');
updateBookById(getId('req'),$values,$con);
}
}
}
<强> /functions/bookListObserver.php 强>
# This sits and waits for the update to write the table to the page
function bookListObserver($current,$con)
{
if(isset($_POST['Update'])) {
autoload('bookList');
echo bookList(((!empty($current['status']))? $current['status'] : false),$con);
}
}
<强> /functions/getValue.php 强>
# This will just check if a value is set. Saves on scripting
function getValue($array,$key,$def = false)
{
return (!empty($array[$key]))? $array[$key] : $def;
}
<强> /functions/bookList.php 强>
# Displays your book list. Currently you are only showing the last book,
# which doesn't appear correct. No point in getting all books but only showing
# the last one
function bookList($selected = false,$con)
{
autoload('getBooks');
$books = getBooks($con);
ob_start();
?>
<table>
<tr>
<th>BookID</th>
<th>Title</th>
<th>Author</th>
<th>Publisher</th>
<th>numcopies</th>
<th>shelfno</th>
<th>status</th>
<th>Action</th>
</tr>
<?php foreach($books as $row) { ?>
<tr>
<td><?php echo $row['title'] ?></td>
<td><?php echo $row['author'] ?></td>
<td><?php echo $row['publisher'] ?></td>
<td><?php echo $row['numcopies'] ?></td>
<td><?php echo $row['shelfno'] ?></td>
<td><?php echo $row['status'] ?></td>
</tr>
<?php } ?>
</table>
<?php
if($selected == "Available")
echo "selected";
elseif($selected == "Unavailable")
echo "selected";
$data = ob_get_contents();
ob_end_clean();
return $data;
}
<强> /functions/connect.php 强>
# This is your mysql connection, it requires attention to build out
# It's not as useful as it could be, so you will want to research it
function connect()
{
return new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME,DB_USER,DB_PASS);
}
<强> /functions/autoload.php 强>
# This is just a handy function to autoload functions when you want
# to use them. If you used classes, you would make an spl_autoload_register()
# function or install something like Composer to autoload
function autoload($name,$run = false)
{
if(is_array($name)) {
foreach($name as $func) {
autoload($func);
}
return;
}
if(!function_exists($name)) {
if(is_file($file = FUNCTIONS.DS.$name.'.php'))
include_once($file);
}
if($run) {
if(function_exists($name))
return $name();
}
}
<强> /config.php 强>
# Make sure errors are on in testing
ini_set('display_errors',1);
error_reporting(E_ALL);
# Creating commonly-used defines will help your scripts be
# more reliable and consistent
define('DS',DIRECTORY_SEPARATOR);
define('ROOT_DIR',__DIR__);
define('FUNCTIONS',ROOT_DIR.DS.'functions');
define('DB_HOST','localhost');
define('DB_NAME','library book');
define('DB_USER','root');
define('DB_PASS','');
# Start session by default
session_start();
require_once(FUNCTIONS.DS.'autoload.php');
# Autoload the connect function and assign it
$con = autoload('connect',true);
<强>的index.php 强>
<?php
# Add config
include(__DIR__.DIRECTORY_SEPARATOR.'config.php');
# Include all our starting page functions
autoload(array('bookObserver','bookListObserver','getBook', 'getValue'));
# Set default array for current selection
$current = array();
# Start observer, pass connection
bookObserver($con,$current);
?>
<html>
<head><title>Editing the fields</title>
<style>
body {
background-color: rgb(255,0,255);
}
</style>
</head>
<body>
<?php
# This writes the table if update is set
# You should not put this html above the <html> tag
bookListObserver($current,$con);
# This gets the book from the page request
$book = getBook($con);
?>
<form action="edit1.php" action="post">
EnterTitle:<input type="text" name="title" value="<?php echo getValue($book,'title') ?>"><br/>
EnterAuthor:<input type="text" name="author" value="<?php echo getValue($book,'author') ?>" ><br/>
EnterPublisher:<input type="text" name="publisher" value="<?php echo getValue($book,'publisher') ?>"><br/>
EnterNumCopies:<input type="text" name="numcopies" value="<?php echo getValue($book,'numcopies') ?>"><br/>
EnterShelfNo:<input type="text" name="shelfno" value="<?php echo getValue($book,'shelfno') ?>"><br/>
<input type="hidden" name="bookid" value="<?php echo getValue($book,'bookid') ?>" />
<select>
<option value="available" <?php if(isset($current['status']) && $current['status'] == "Available") echo "selected";?>>Available</option>
<option value="unavailable" <?php if (isset($current['status']) && $current['status'] == "Unavailable") echo "selected";?>>Unavailable</option>
</select><br>
<input type="submit" name="submit" value="Update">
</form>
</body>
</html>