【发布时间】:2010-08-13 07:36:33
【问题描述】:
我只是好奇,想知道如果你想使用相同的 html 表单和尽可能相同的 php 代码来创建和更新项目,你们如何处理它。
示例:
在一个页面上,您可以创建一个包含姓名、电子邮件地址和年龄的数据库条目。
在不同的 (?) 页面上,您会看到填充了您的数据的表单字段,您可以对其进行编辑和保存。
我有办法使用几乎相同的代码来完成此任务 - 但我希望在这里学到一些东西。那么你将如何处理这个任务呢?
谢谢,干杯,扭伤
【问题讨论】:
我只是好奇,想知道如果你想使用相同的 html 表单和尽可能相同的 php 代码来创建和更新项目,你们如何处理它。
示例:
在一个页面上,您可以创建一个包含姓名、电子邮件地址和年龄的数据库条目。
在不同的 (?) 页面上,您会看到填充了您的数据的表单字段,您可以对其进行编辑和保存。
我有办法使用几乎相同的代码来完成此任务 - 但我希望在这里学到一些东西。那么你将如何处理这个任务呢?
谢谢,干杯,扭伤
【问题讨论】:
很容易 - 如果在查询字符串中提供了现有项目(用户有权编辑)的 ID,那么它就是一个编辑操作。
如果查询字符串中没有提供 ID,则为创建操作。
如果是编辑操作,则根据数据库中的现有值预填充字段,如果是创建操作,则根据默认值或空字符串预填充字段。
【讨论】:
我的看法是,在创建/编辑之间为表单重用相同的标记在某些情况下有效,但并非对所有情况都有效。我发现表单——尽管它们可能映射到同一个数据库表——实际上是由它们的上下文定义的。例如,如果您有一个“用户”表,您可能有一个包含用户名、电子邮件、密码的“创建”表单,但在该用户存在后,您希望他们在其网站上保留其身份,因此用户名字段不会出现在“编辑”上下文中。我是典型的 PHP 开发人员,但我开始欣赏 Django 采用的方法,您可以在其中创建一个模型(表),为每个字段定义基本验证,并且您可以创建尽可能多的表单,或修改/扩展该定义。如果您是从头开始编写,您可能会发现使您的验证方法非常可移植和/或找到使您的表单字段与上下文相关的方法是很实用的。
【讨论】:
这就是我现在一直这样做的方式。你在使用 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 分开的原因是,我经常发现它们的行为以及加载和保存步骤实际上是完全不同的。
【讨论】:
我想这不是正确的答案,但无论如何它可能对你来说很有趣。
有一个 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 会为您做到这一点,并且您的代码变得更易于阅读和调试。
【讨论】:
是的,这是唯一可接受的解决方案。
这是一个将输入表单存储在模板中的 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。
【讨论】: