【问题标题】:Best practice: Use same form for creation and update最佳实践:使用相同的表单进行创建和更新
【发布时间】:2010-08-13 07:36:33
【问题描述】:

我只是好奇,想知道如果你想使用相同的 html 表单和尽可能相同的 php 代码来创建和更新项目,你们如何处理它。

示例:
在一个页面上,您可以创建一个包含姓名、电子邮件地址和年龄的数据库条目。
在不同的 (?) 页面上,您会看到填充了您的数据的表单字段,您可以对其进行编辑和保存。

我有办法使用几乎相同的代码来完成此任务 - 但我希望在这里学到一些东西。那么你将如何处理这个任务呢?

谢谢,干杯,扭伤

【问题讨论】:

    标签: php html forms


    【解决方案1】:

    很容易 - 如果在查询字符串中提供了现有项目(用户有权编辑)的 ID,那么它就是一个编辑操作。

    如果查询字符串中没有提供 ID,则为创建操作。

    如果是编辑操作,则根据数据库中的现有值预填充字段,如果是创建操作,则根据默认值或空字符串预填充字段。

    【讨论】:

    • 不可能不填充字段值,因为我们使用的是相同的表单:)
    • 当然可以... 可能不是最好的方法,但它确实有效。如果表单用于新条目,则值为空,否则显示数据库中的条目。
    • 哦,不。你从来没有调试过你的应用程序,或者你从来没有提到过。
    • 为了澄清,预填充无论如何都会发生。如果没有现有记录,该表单会预先填充合理的默认值(如果适用,或者如果您愿意,可以只填充空值),如果存在,它会预先填充记录的当前列值。
    【解决方案2】:

    我的看法是,在创建/编辑之间为表单重用相同的标记在某些情况下有效,但并非对所有情况都有效。我发现表单——尽管它们可能映射到同一个数据库表——实际上是由它们的上下文定义的。例如,如果您有一个“用户”表,您可能有一个包含用户名、电子邮件、密码的“创建”表单,但在该用户存在后,您希望他们在其网站上保留其身份,因此用户名字段不会出现在“编辑”上下文中。我是典型的 PHP 开发人员,但我开始欣赏 Django 采用的方法,您可以在其中创建一个模型(表),为每个字段定义基本验证,并且您可以创建尽可能多的表单,或修改/扩展该定义。如果您是从头开始编写,您可能会发现使您的验证方法非常可移植和/或找到使您的表单字段与上下文相关的方法是很实用的。

    【讨论】:

    • 当然。插入和更新之间经常存在业务差异,可能有些字段一旦插入就不可编辑,也许有些字段只有在第一次插入时才能编辑,并且可能在一个页面上插入,在更多页面上编辑。也就是说,只要有可能,我就会重复使用相同的表单。
    【解决方案3】:

    这就是我现在一直这样做的方式。你在使用 MVC 系统吗?我使用一个控制器来执行两种不同的操作(urls = person/new + person/edit/xxxx_id)。

    代码是这样的:

    function new()
        errors = []
        if (get)
            data = blank_record()
        elseif (post)
            data = posted_data
            if (create(data))
                redirect_to_listing()
            else
                errors = describe_errors
        show_form(data, errors)
    
    function edit()
        errors = []
    
        if (get)
            data = get_from_db(id)
        elseif (post)
            data = posted_data
            if (save())
                redirect_to_listing()
            else
                errors = describe_errors
        show_form(data, errors)
    

    请注意,一旦它到达表单,总会有一个名为 data 的对象可以呈现,它可能是空白的,来自 db 或已发布的数据。无论哪种方式,它都应该始终是相同的格式。

    我将 new 和 edit 分开的原因是,我经常发现它们的行为以及加载和保存步骤实际上是完全不同的。

    【讨论】:

      【解决方案4】:

      我想这不是正确的答案,但无论如何它可能对你来说很有趣。

      有一个 orm 项目叫做教义: http://www.doctrine-project.org/projects/orm/1.2/docs/en

      // User Id might be an existing id, an wrong id, or even empty:
      $user_id = 4;
      $user_id = null;
      
      // Fetch the user from the database if possible
      $user = Doctrine::getTable('Model_User')->find($user_id);
      
      // If there was no record create a new one
      if ( $user === false )
          $user = new Model_User();
      
      // Change some data
      $user->title = $newValue;
      
      // Perform an update or an insert:
      $user->save();
      

      如您所见,您不必关心 sql。 Doctrine 会为您做到这一点,并且您的代码变得更易于阅读和调试。

      【讨论】:

      • ......而且很难离开常见的任务:)
      • 我还没有达到这一点。你能告诉我这些任务的样子吗?
      • @Ghommey - “请你给我一个关于这些任务的样子” -> 非常简单:当你最终不得不将来自 2 个或多个表的数据合并到一个复杂的连接中时,它没有- 简单的选择标准,在模型中表示它的需求同样不同。
      • @unity100 - 主题是“最佳实践:使用相同的表单进行创建和更新”。我想创建具有如此复杂连接的数据集的代码是不合适的;)
      【解决方案5】:

      是的,这是唯一可接受的解决方案。

      这是一个将输入表单存储在模板中的 CRUD 应用程序的小示例:

      <?  
      mysql_connect(); 
      mysql_select_db("new"); 
      $table = "test"; 
      if($_SERVER['REQUEST_METHOD']=='POST') { //form handler part: 
        $name = mysql_real_escape_string($_POST['name']); 
        if ($id = intval($_POST['id'])) { 
          $query="UPDATE $table SET name='$name' WHERE id=$id"; 
        } else { 
          $query="INSERT INTO $table SET name='$name'"; 
        } 
        mysql_query($query) or trigger_error(mysql_error()." in ".$query); 
        header("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);  
        exit;  
      }  
      if (!isset($_GET['id'])) { //listing part: 
        $LIST=array(); 
        $query="SELECT * FROM $table";  
        $res=mysql_query($query); 
        while($row=mysql_fetch_assoc($res)) $LIST[]=$row; 
        include 'list.php'; 
      } else { // form displaying part: 
        if ($id=intval($_GET['id'])) { 
          $query="SELECT * FROM $table WHERE id=$id";  
          $res=mysql_query($query); 
          $row=mysql_fetch_assoc($res); 
          foreach ($row as $k => $v) $row[$k]=htmlspecialchars($v); 
        } else { 
          $row['name']=''; 
          $row['id']=0; 
        } 
        include 'form.php'; 
      }  
      ?>
      
      form.php
      <form method="POST">
      <input type="text" name="name" value="<?=$row['name']?>"><br>
      <input type="hidden" name="id" value="<?=$row['id']?>">
      <input type="submit"><br>
      <a href="?">Return to the list</a>
      </form>
      
      list.php
      <a href="?id=0">Add item</a>
      <? foreach ($LIST as $row): ?>
      <li><a href="?id=<?=$row['id']?>"><?=$row['name']?></a>
      <? endforeach ?>
      

      当然,可以使用一些花哨的表单构造函数,比如 HTML_QuickForm2 来代替普通的 HTML 模板——你知道它的程序员一直渴望不重复自己,即使在命名 HTML 字段、字段值和错误键时:)
      但我个人更喜欢纯 HTML。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-06
        • 1970-01-01
        • 2012-03-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多