更新时未定义的变量

时间:2017-01-31 05:39:50

标签: php

这里我的目标是使用我在文本框中设置的标题更新图书的信息。但是在我的代码中,当我运行时,我收到错误$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>

1 个答案:

答案 0 :(得分:1)

我想不幸的是,你在这里发生的是"spaghetti code"综合症的开始,所以你会想要投资学习PHP framework。您将面临更少的安全问题,您的脚本将从一开始就更清洁,更容易维护等。

对于此特定代码段,除其他外,您有sql injection个问题,您可以bookid$_GET设置$_POST,但很难确定哪个最好用,您的html发生在<html>标记之上,但您遇到的主要问题是您拥有在if范围内定义但在if范围之外引用的变量因此,如果不满足if条件,则会创建错误(See this example以供参考)。

除了修复范围问题之外的一些建议:

  1. 使用PDOmysqli_参数绑定。我的示例使用PDO
  2. 在最终版面中使用functionsclass/method获取可用性和可读性(它看起来更复杂,如下所示,但只是因为它全部粘贴在一个页面上。每页应该是分开的)。所有这些$query$query1$query2等都会让人感到困惑。我已经使用过函数,但最好将bookid内部传递给所有方法。
  3. 标准化您的图书ID密钥名称,将其设为book_idbookid,而不是两者。我的示例使用bookid
  4. 这可能存在一些缺陷,但希望它能为您提供一些有用的想法,正如我之前所说的,这将作为一个类(实际上是几个类)实现更有用,但使用函数可能是一个很好的开端来帮助清理你的脚本。

    重要说明:我没有对此进行过测试(尽管应该没有语法错误),但您应该能够通过将版本与此版本并行来了解正在发生的事情以及所需的内容。如果你不理解它,请先阅读它,不要盲目复制和粘贴,否则你会遇到更多麻烦。正如他们所说,使用风险自负。

    <强> /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>