【问题标题】:How to combine "add" and "edit" forms into 1 "script"?如何将“添加”和“编辑”表单合并为 1 个“脚本”?
【发布时间】:2012-10-06 16:23:24
【问题描述】:

我总是发现自己创建了两个单独的 php 文件/脚本来添加特定数据和编辑这些数据。这些文件并没有太大的不同,所以我想应该有一种方法可以将它们变成一个文件。

这里我将举一个非常简单的例子来说明我的观点:

add.php:

<?php

$title = $_POST['title']; // ignore the unescaped data, this is a simple example
$text = $_POST['text'];
mysqli_query($connection,
   "INSERT INTO `articles` (`title`, `text`) VALUES ('$title', '$text')");

echo'
<form>
   <input type="text" name="title" value="'.$_POST['title'].'" />
   <input type="text" name="text" value="'.$_POST['text'].'" />
   <input type="submit" value="Add" />
</form>
';

?>

edit.php:

<?php

$id = $_GET['id'];
$title = $_POST['title']; // ignore the unescaped data, this is a simple example
$text = $_POST['text'];
// save data
mysqli_query($connection,
   "UPDATE `articles` SET `title` = '$title', `text` = '$text'
    WHERE `id` = $id");

// get current data
$q = mysqli_query($connection,"SELECT * FROM `articles` WHERE `id` = $id");
$d = mysqli_fetch_array($q);
$title = $d['title'];
$text = $d['text'];

echo'
<form>
   <input type="text" name="title" value="'.$title.'" />
   <input type="text" name="text" value="'.$text.'" />
   <input type="submit" value="Add" />
</form>
';

?>

如您所见,添加和编辑表单/代码非常相似,除了:

  • add 插入数据,而 edit 更新它
  • add 将$_POST 值插入到表单中(如果有错误,使提交的数据保留在表单中,而edit 将当前数据库值插入到表单中(保存完成并刷新页面后,以便表单具有当前的 db 值)

这两个是否可以以某种方式合并到一个文件/代码中,这样如果我想添加/更改表单值,我不需要分别编辑两个文件,而只需更改一次表单?

【问题讨论】:

  • 您需要在您正在构建的表单上做一些htmlspecialchars() 工作。如果 $title 或 $text 包含 ",您将“破坏”您的表单。

标签: php sql


【解决方案1】:

您可以使用大致给您的INSERT ON DUPLICATE KEY UPDATE

<?php
$id = $_GET['id'];
$title = $text = '';

if ($_POST)
{
    $title = $_POST['title'];
    $text = $_POST['text'];
    // save data
    $query = "INSERT INTO `articles` (`id`, `title`, `text`)
              VALUES ('$id', '$title', '$text')
              ON DUPLICATE KEYS UPDATE title = title, text = text"
    mysqli_query($connection, $query);

}
else if ($id)
{
    // get current data
    $q = mysqli_query($connection, "SELECT * FROM `articles` WHERE `id` = $id");
    $d = mysqli_fetch_array($q);
    $title = $d['title'];
    $text = $d['text'];
}

echo '
<form>
   <input type="text" name="title" value="'.$title.'" />
   <input type="text" name="text" value="'.$text.'" />
   <input type="submit" value="Add" />
</form>';
  • 如果是 POST 并且没有 $id 存在:插入新行,就像插入一样。
  • 如果它是 POST 并且存在 $id:如果 $id 已经存在于表中,则更新该行,否则它是一个 INSERT。
  • 如果您只有一个 $id :显示包含现有数据的表单。
  • 如果不是 POST 且 $id 未填充:显示一个空表单。

【讨论】:

    【解决方案2】:

    您可以使用GETPOST 参数的组合来实现您想要的。使用GET参数区分editadd,即/post?action=add/post?action=edit。根据$_GET['action'] 的值,您会知道是将空表单呈现给add 帖子还是使用数据库中的数据填充表单。然后你可以在你的表单中有一个隐藏的字段,你可以用$_GET['action']的值填写它,这样你就可以在提交表单后处理表单时知道是INSERT还是UPDATE

    开始使用一些 框架 可能是值得的,例如 CakePHP、CodeIgniter、Zend 框架等。

    【讨论】:

    • 使用框架绝对是个好建议。几个月前我遇到了 Symfony,并且在构建 CRUD 网页时对它只有积极的体验。
    • 我在他们的网站(Blog tutorial)上发现 Cake 的教程也很有帮助。
    【解决方案3】:

    我倾向于制作一个插入和更新数据的接口,它只有一种插入和更新方法。关键是要提交的用户表单必须包含要更新的行的 id。

    public method save( Object obj )
        if obj.id is in database
            query = "update table set attrA = obj.a, attrB = obj.b where id=obj.id" 
        else if obj.id < 1 
            query = "insert into table  (a,b,c) values (obj.a,obj.b,obj.c)"
    

    这意味着当您创建要提交的新对象时,它的 id 必须初始化为 0 或 -1(1 是具有 int 主键的表的第一个键行)。同样,html 文件中的表单必须具有 填充默认值(null、0、-1)或正在编辑的对象的有效 id .

    从本质上讲,这意味着用户可以更新表中的任意行,但如果他们已经进行了身份验证,这应该不是问题。此外,通常知道 id > 0 到 INSERT 和 UPDATE 否则就足够了。不需要验证提交的id是否在数据库表中,因为插入时不需要设置id,而是让数据库自动增加主键。

    更新 只喝了 3 杯啤酒,就出现了这么多愚蠢的错别字。我希望这是可读的

    【讨论】:

      【解决方案4】:

      这是一个使用 OOP 的想法(在我看来)。

      假设您有一个类表示表单元素,称为FormElement

      那么你有一些通用的形式应该支持什么?让我们假设 MVC:

      • 自我展示
      • 添加元素
      • 设置默认值
      • 解析请求值
      • 获取价值
      • 验证值

      所以你会为自己构建一个类似的界面

      interface IForm {
          public function Display();
          public function AddElement( FormElement $element);
          public function SetValues( array);
          public function FetchPostValues();
          public function GetValues();
          public function Validate();
      }
      

      那么,这两种形式的共同点是什么(假设您要禁止更改email)?除了FetchPostValues()

      因此,您将使用 pure virtual method 构建一个类,该类将执行类似的所有操作:

      abstract class FormArticle implements IForm {
          // All methods implemented except FetchPostValues
          abstract public function FetchPostValues();
      }
      

      然后只需构建两个小类,它们将定义如何获取发布数据:

      class FormArticleEdit extends FormArticle {
          public function FetchPostValues(){
              if( isset( $_POST['email'])){
                  throw new Exception('What are you trying to achieve?');
              }
              // ...
          }
      }
      

      还有一个提示(实际上是两个):

      • 实现像FormAbstract 这样的抽象类,它将提供像AddElement()Display() 这样的所有泛型方法。这将节省您每次复制这些通用方法的时间,但仍会为您提供从头开始的能力(当直接使用数据库或直接缓存项目时)。
      • 宁愿使用已有模型重用表单的框架(Zend我个人最喜欢的)。

      【讨论】:

        猜你喜欢
        • 2020-02-21
        • 2016-12-27
        • 1970-01-01
        • 2011-06-15
        • 1970-01-01
        • 2023-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多