如何将“添加”和“编辑”表单合并为1个“脚本”?

时间:2012-10-06 16:23:25

标签: php sql

我总是发现自己创建了两个单独的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>
';

?>

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

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

这两个可以以某种方式合并为一个文件/代码,这样如果我想添加/更改表单值,我不需要单独编辑两个文件,但只会更改一次表单吗?

4 个答案:

答案 0 :(得分:2)

你可以使用大致给你的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存在:插入一个新行就像INSERT一样。
  • 如果它是POST并且存在$ id:如果表中已存在$ id而不是更新行,否则它是INSERT。
  • 如果您只有$ id:显示包含现有数据的表单。
  • 如果它不是POST并且未填充$ id:显示空表单。

答案 1 :(得分:1)

我倾向于创建一个用于插入和更新数据的接口,该接口只有一种插入和更新方法。这项工作的关键点是提交的用户表单必须包含正在更新的行的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文件中的表单必须具有&lt; input type = hidden value = row.id name = DBID&gt;使用默认值(null,0,-1)或正在编辑的对象的有效ID填充。

基本上这意味着用户可以更新表中的任意行,但是授予他们自己进行身份验证,这应该不是问题。此外,通常知道id&gt; 0到INSERT,否则UPDATE。没有必要验证提交的id是否在数据库表中,因为在插入时不要设置id,而是让DB自动增加主键。

更新的 哇哇哇哇哇哇哇哇哇哇哇哇!我希望这是可读的

答案 2 :(得分:1)

您可以使用GETPOST参数的组合来实现您想要的效果。使用GET参数区分editadd,即/post?action=add/post?action=edit。根据{{​​1}}的值,您知道是否要将空表单呈现给$_GET['action']帖子,或者使用数据库中的数据填充表单。然后,您可以在表单中添加隐藏字段,并使用add的值填写该字段,这样您就可以在处理时知道是$_GET['action']还是INSERT提交后的表格。

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

答案 3 :(得分:0)

这里有一个关于它应该如何使用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我个人最喜欢的)。