0

我有一个表格,每行都有一个编辑链接和一个删除按钮。删除按钮工作正常,但编辑链接我不知道我做错了什么!

单击特定行的编辑链接会导致带有表单的编辑页面,但未填写数据。没有错误消息...我可以在 URL 字段中看到它是所选电影的正确 ID。

我错过了什么?我是否还需要在编辑页面上写任何查询等?我确实尝试将其设置为需要页面,因此当单击编辑按钮时,编辑表单会在索引页面上弹出。但我无法做到这一点。

我知道我使用的是过时的 mysql 函数,但我还没有添加 SQL 保护。

该数据库称为moviedata,有2 个表。

  • 表一称为:电影
    • 字段/列 (5): id (primary key, AI), ****title** , release_year ,** ****genre_id**, **director****
  • 表2称为:类别
    • 字段/列(2):genre_id(主键,AI),genre

在genre_id(主键,表2)和genre_id(表1)之间存在关系(外键)。

index.php 代码

<!DOCTYPE html>

<html>

<head>

<title>My movie library</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="mall.css" />

</head>

<body>
<?php 

    require 'connect.inc.php';

    if (isset($_POST['delete']) && isset($_POST['id'])) {
        $id = $_POST['id'];
        $query = "DELETE FROM movies WHERE id=".$id." LIMIT 1";

        if (!mysql_query($query, $sql))
            echo "DELETE failed: $query<br>".
            mysql_error() . "<br><br>";
    }

    $query = "SELECT * FROM movies m INNER JOIN categories c ON m.genre_id = c.genre_id";
    $result = mysql_query($query);

    if (!$result) die ("Database access failed:" .mysql_error()) ;
    $rows = mysql_num_rows($result);

    echo '<table><tr><th>Title</th><th>Release year</th><th>Genre</th><th>Director</th><th>Update</th><th>Delete</th></tr>';

    while ($row = mysql_fetch_assoc($result)) {
    echo '<tr><td>' .$row["title"] . '</td>' ;
    echo '<td>' .$row["release_year"] . '</td>' ;
    echo '<td>' .$row["genre_id"] . '</td>' ;
    echo '<td>' .$row["director"] . '</td>' ;
    echo '<td>'."<a href='edit_movie.php?edit=" . $row["id"] . "'>Edit</a>".'</td>';
    echo '<td><form action="index.php" method="POST">
                <input type="hidden" name="delete" value="yes" />
                <input type="hidden" name="id" value="'. $row["id"] .'" /> 
                <input type="submit" value="Delete" /></form>
                </td></tr>' ;
    }
    echo '</table>'; 

?>

</body>

</html>

这是edit_movie.php页面上的代码。带有表单的编辑页面:

<!DOCTYPE html>

<html>

<head>

<title>My movie library</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="mall.css" />

</head>

<body>

<?php

require 'connect.inc.php';


//close MySQL
mysql_close($sql);

?>

<p>Edit movie</p>
<div id="form_column">
<form action="edit_movie.php" method="post">
<input type="hidden" name="id" value="<?php if (isset($row["id"])) ?>" /> <br>
Title:<br> <input type="text" name="title" value="<?php if (isset($row["title"])) { echo $row["title"];} ?>" /> <br>
Release Year:<br> <input type="text" name="release_year" value="<?php if (isset($row["release_year"])) { echo $row["release_year"];} ?>" /> <br>
Director:<br> <input type="text" name="director" value="<?php if (isset($row["director"])) { echo $row["director"];} ?>" /> <br><br>
Select genre:
<br>
<br> <input type="radio" name="genre_id" value="1" checked />Action<br>
<br> <input type="radio" name="genre_id" value="2" />Comedy<br>
<br> <input type="radio" name="genre_id" value="3" />Drama<br>
<br> <input type="radio" name="genre_id" value="4" />Horror<br>
<br> <input type="radio" name="genre_id" value="5" />Romance<br>
<br> <input type="radio" name="genre_id" value="6" />Thriller<br><br>
<input type="submit" />
</form>
</div>



</body>

</html>

数据库连接位于单独的 connect.inc.php 文件中,这些文件的顶部需要该文件。您可以在下面看到 connect.inc.php 文件中的代码:

<?php


//connect to MySQL
$servername = "localhost";
$username = "root";
$password = "";
$sql = mysql_connect($servername,$username,$password);
mysql_connect($servername,$username,$password);
//select database
mysql_select_db("moviedata");

?>
4

1 回答 1

1

好吧,你的代码有点乱,因为它甚至不是程序性的你在给自己制造麻烦。真的。

在使用 PHP 开发应用程序时,您必须记住以下几点:

从不打印/回显 html 标签

. 尽量避免这种情况,因为这会使您的代码难以维护和阅读。请改用替代语法。


也就是说,PHP 本身应该用作模板引擎,而不是“生成”模板引擎。


职责分离。清楚而明智地

连接到数据库的函数不应在演示文稿中使用(在本例中为 HTML)。您将创建一个负责数据库的文件,另一个负责数据操作(例如 DELETE、CREATE、UPDATE 操作)等的文件。



不要忘记 SQL 注入和 XSS

永远不要相信您从超全局变量(如$_GET$_POST和. 至少,应该用于您要处理的每个动态输入。$_COOKIE$_REQUESTmysql_real_escape_string()

一般来说,XSS允许通过上述超全局变量执行任何 JavaScript 代码,以及在通用标记中注入另一个 html 代码。为了防止这种情况,这里基本上htmlentities()就够了。


把东西包装成一个函数

因此,与其这样做,

if (isset($_POST['delete']) && isset($_POST['id'])) {
    $id = $_POST['id'];
    $query = "DELETE FROM movies WHERE id=".$id." LIMIT 1";

你应该像这样重写它:

function delete_movie_by_id($id){
   return mysql_unbuffered_query(sprintf("DELETE FROM `movies` WHERE id='%s' LIMIT 1", mysql_real_escape_string($id)));
}

if ( isset($_POST['delete'], $_POST['id']) ){

   delete_movie_by_id($_POST['id']); // it's safe & readable now
}


了解 OOP 并切换到 PDO

好吧,当您开发这样的东西时,程序代码不是要走的路。下次你要写东西的时候,你真的会开始同时使用 PDO 进行数据库访问和 OOP。


我可以继续,但最好现在停下来,转回你原来的问题。

好吧,你没有说你到底得到了哪个错误。例如,您是否知道如果mysql_select()返回 FALSE(=== 数据库选择失败),这不会终止脚本!?根据您发布的代码,您不会以任何方式“跟踪它”。

第一的

所以,connect.inc.php 应该是这样的:

error_reporting(E_ALL); // <-- Important!

$servername = "localhost";
$username = "root";
$password = "";

if ( ! mysql_connect($servername,$username,$password) ){
   die(sprintf('Cannot connect to MySQL server because of "%s"', mysql_error()));
}

//select database
if ( ! mysql_select_db("moviedata") ){
  die(sprintf('Cannot select a database, because of "%s"', mysql_error()))
}

第二

在edit_movie.php 页面中,此代码块根本不需要。当脚本终止时,连接将自动关闭。

所以只需删除这个:

<?php

require 'connect.inc.php';

//close MySQL
mysql_close($sql);

第三

在那edit_movie.php,你清楚地问:if ( isset($row['some_column']) )...但它到底是怎么回事?本身在哪里$row?它没有在任何地方定义,所以你不会得到你所期望的。这里:

<input type="hidden" name="id" value="<?php if (isset($row["id"])) ?>" /> <br>
Title:<br> <input type="text" name="title" value="<?php if (isset($row["title"])) { echo $row["title"];} ?>" /> <br>
Release Year:<br> <input type="text" name="release_year" value="<?php if (isset($row["release_year"])) { echo $row["release_year"];} ?>" /> <br>
Director:<br> <input type="text" name="director" value="<?php if (isset($row["director"])) { echo $row["director"];} ?>" /> <br><br>

好的,这就够了。

考虑一下,像这样重写您的应用程序:

文件:movie.inc.php

require_once('connect.inc.php');

/**
 * Fetch all movies from a table
 * @return array on success, FALSE on failure
 */
function get_all_movies(){

   $query = "SELECT * FROM movies m INNER JOIN categories c ON m.genre_id = c.genre_id";

   $result = mysql_query($query);

   if ( ! $result ){ 
     return false;
   } else {
     $return = array();

     while ($row = mysql_fetch_assoc($result)){

        $return[] = array('director' => $row['director'], 'genre_id' => $row['genre_id'], 'release_year' => $row['release_year'], 'title' => $row['title'], 'id' => $row['id']); 
     }
       return $return;
   }
}

function delete_movie_by_id($id){
  // I already wrote this, see above
}

文件index.php

<?php

require('movie.inc.php');

if ( isset($_GET['delete']) && isset($_GET['id']) ){
   if ( delete_movie_by_id($_POST['id']) ){ //it's 100% safe
       die('Movie has been removed. Refresh the page now'); // or the like
   } else {
      // could not - handle here
   }
}

?>
<!DOCTYPE html>
<html>
<head>

<title>My movie library</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="mall.css" />

</head>
<body>

<table>
 <tr>
  <th>Title</th>
  <th>Release year</th>
  <th>Genre</th><th>Director</th>
  <th>Update</th>
  <th>Delete</th>
 </tr>

  <?php  foreach (get_all_movies() as $index => $row) : ?>
   <tr>
     <td><?php echo $row['title'];?></td>
     <td><?php echo $row['release_year']; ?></td>
     <td><?php echo $row['genre_id'];?></td>
     <td><?php echo $row['director'];?></td>
     <td><a href='<?php printf('edit_movie.php?edit=%s', $row['id']);?>>Edit</a></td>
     <td>
      <form action="index.php" method="GET">
              <input type="hidden" name="delete" value="yes" />
              <input type="hidden" name="id" value="<?php echo $row['id'];?>" /> 
              <input type="submit" value="Delete" />
      </form>
      </td>
    </tr>
    <?php endforeach; ?>
    </table>

</body>
</html>

我现在累了,希望你能从这个答案中得到核心思想。


更新

制作电影“可编辑”的基本步骤:

1)您获取要编辑的数据(从表中)
2)您将编辑后的数据发送回服务器(php 脚本)
3)您验证输入
4)您运行UPDATE查询

就这样。

所以它会类似于这个(文件:edit_movie.php):

<?php

require_once('movie.inc.php');


/**
 * Grabs the movie data by its id
 * 
 * @param $id A movie id 
 * @return array on succes, FALSE if $id is wrong
 */
function get_movie_by_id($id){

   $query = sprintf("SELECT * FROM `enter_movie_table_name_here` WHERE `id` = '%s' LIMIT 1", mysql_real_escape_string($id));

   $result = mysql_query($query);

   if ( ! $result ){
       return false;
   } else {
       return $result;
   }
}


function update_movie_by_id($id, array $data){

    $query = sprintf("UPDATE `the_movie_table` 
              SET `director` ='%s',
                  `genre_id` = '%s',
                  `relase_year` ='%s',
                  `title` = '%s' WHERE `id` = '%s' LIMIT 1"),

                   mysql_real_escape_string($data['director']),
                   mysql_real_escape_string($data['genre_id']),
                   mysql_real_escape_string($data['relase_year']),
                   mysql_real_escape_string($data['title']),
                   mysql_real_escape_string($id) );

    // not mysql_query() !!! but this
    return mysql_unbuffered_query($query); 
}


// Next thing is to get an id by query string,
// So if it was /movide_edit.php?id=1
// then id we have is 1

// So we need to handle that right now


if ( isset($_GET['id']) ){

   $movie = get_movie_by_id($_GET['id']);

   if ( ! $movie ){ // <- make sure that id isn't fake
      die(sprintf('Invalid movie id "%s"', $_GET['id']));
   }

} else {

   die('Please supply an id you want to edit'); // <- this makes sence
}


// Ok, we'll reserve this block for an update

if ( !empty($_POST) ){ // This will run when user clicked on Save button

      if ( update_movie_by_id($_POST['id'], array(

              'director' => $_POST['director'],
              'genre_id' => $_POST['genre_id'],
              'relase_year' => $_POST['relase_year'],
              'title'       => $_POST['title']

         )) ){

             die('Movie has been updated');
         } else {

          die('Could not update a movie for some wicked reason..');
         }

}


// That's all. Now it can:

//1) Fetch the data
//2) Edit accordingly 

?>
<!DOCTYPE html>
<html>

<!--

This is kinda quick and dirty form
You need to fix this later

-->

<body>

  <form method="POST">

     <label for="title">Title</label>
     <input type="text" name="title" value="<?php echo $movie['title']; " />

     <!--
           Add another elements this way..
      -->

    <button type="submit">Save</button>  

  </form>
</body>
</html>
于 2013-03-09T04:55:54.280 回答