I have a small application in which i have 9 different forms, and every form have a least 40+ fields where the user must enter some data.
我有一个小应用程序,其中有9个不同的表单,每个表单至少有40多个字段,用户必须在其中输入一些数据。
I have written each form in a single php file and made a master PHP file where i only add the form in the middle of the page.
我已经在一个php文件中编写了每个表单,并创建了一个主php文件,在这个文件中我只在页面的中间添加表单。
My question is:
我的问题是:
I don't want to write 9 different function for each form coz it would be too long and i don't think it's the best practice, so is there a way or idea that can help me make a general function in which i can pass some variables to and add the data to the db.
我不想写9个不同的函数形式,因为它太长,我不认为这是最好的练习,所以有一种方式或想法可以帮我做一个通用函数,我可以通过一些变量,将数据添加到数据库。
Can i like iterate through the $_POST array and extarct the data and reformat it somehow? but then again every field have a different name and i seems like this is impossible to do.
我可以遍历$_POST数组并extarct数据并以某种方式重新格式化它吗?但是每个领域都有不同的名字,我觉得这是不可能的。
6 个解决方案
#1
2
Try this way:
试试这种方法:
<?php
abstract class FormData
{
const BOOLEAN = 'bool';
const INTEGER = 'int';
const FLOAT = 'float';
const STRING = 'string';
protected $_types = array();
public static function create($data)
{
$action = isset($data['action']) ? $data['action'] : '';
switch ($action)
{
case 'form1': return new MyForm1($data);
default: return null;
}
return null;
}
protected function loadPostVars($data)
{
foreach ($data AS $var=>$value)
{
$value = $this->convertVar($var, $value);
if (!is_null($value) && property_exists($this, $var))
{
$this->$var = $value;
}
}
}
protected function convertVar($var, $value)
{
if (array_key_exists($var, $this->_types))
{
$type = $this->_types[$var];
switch ($type)
{
case FormData::BOOLEAN: return (bool)(int)$value;
case FormData::INTEGER: return (int)$value;
case FormData::FLOAT: return (float)$value;
case FormData::STRING: // drop down
default:
return myEscapeString($value);
}
}
return null;
}
}
class MyForm1 extends FormData
{
public $fld1;
public $fld2;
public $fld3;
// etc...
public function __construct($data)
{
$this->_types = array(
'fld1' => FormData::INTEGER,
'fld2' => FormData::STRING,
'fld3' => FormData::BOOLEAN,
);
$this->loadPostVars($data);
}
}
// And finally process your form data
// You should add hidden input 'action' to each form to identify the form
if ($form = FormData::create($_POST))
{
echo $form->fld1, $form->fld2, $form->fld3;
}
else
{
exit('error: unknown action provided');
}
?>
This solution has to be improved - I've written it very fast. But I hope you'll catch the main idea. Hope this will help. Sure, in each form class you can add specific methods to process the request etc.
这个解决方案需要改进——我写得很快。但我希望你能抓住主要的想法。希望这将帮助。当然,在每个表单类中都可以添加特定的方法来处理请求等等。
#3
1
I've used something similar in one of my projects. Basically, I define all the fields, including how to display them, what data type they have (number, date, etc), as well as what to do with them once posted back. Then you pass that information to one function which generates a HTML form. When that form is submitted, you pass the same information to a different function which performs the necessary tasks.
我曾在一个项目中使用过类似的东西。基本上,我定义了所有的字段,包括如何显示它们,它们具有什么数据类型(数字、日期等),以及一旦发布回来该如何处理它们。然后将这些信息传递给生成HTML表单的函数。当提交表单时,您将相同的信息传递给执行必要任务的另一个函数。
In my specific case, it was just used to create search forms, so the processing involved creating a SELECT sql statement. Here's a sample of one of the field definitions:
在我的具体示例中,它只是用于创建搜索表单,因此处理涉及创建SELECT sql语句。以下是其中一个字段定义的示例:
$criteria = array(
array("label" => "Search clients",
"type" => "radio",
"values"=> array("1" => "Just " . $client->getName(),
"2" => "All clients"),
"where" => array("1" => "c.`clientId` = " . $client->getId(),
"2" => "1"), // always true
"default" => "1"),
array("label" => "Last Name",
"type" => "text",
"where" => "s.`lastName` LIKE '%s'"),
array("label" => "First Name",
"type" => "text",
"where" => "s.`firstName` LIKE '%s'")
// etc...
#4
0
Just 2 small thoughts..
2小的想法. .
1) Do you show all 9 forms in one page? If yes - I reeeally don't think it's a good idea.
2) Why don't you divide your forms to different pages and give same names to fields on your forms where it is possible?
你把所有的9张表格都显示在一页里吗?如果是的话——我真的不认为这是个好主意。你为什么不把你的表单分成不同的页面,给表单上可能的字段起相同的名字呢?
#5
0
You can iterate on the $_POST array with a foreach.
可以使用foreach迭代$_POST数组。
foreach($_POST as $name => $value) {
echo $name, ' ', $value, '<br />';
}
#6
0
As SleepyCod said, your breast bet is operating a foreach
, but the answer needs to be expanded upon:
正如SleepyCod所言,你的乳房赌注是为每个人设定的,但答案需要扩展:
- Are the form fields equivalent to the table?
- 表单字段是否等价于表?
- Is each form being used to
UPDATE
orINSERT
into more than table? - 是否每个表单都被用于更新或插入到多个表中?
The reason I ask is because this is something that I've done for my webpage. I created a dynamic form structure where the table is queried in question, the schema is retrieved and a foreach
+ switch()
is used to determine WHAT the field is to be used.
我之所以问这个问题,是因为这是我为我的网页所做的。我创建了一个动态表单结构,在其中查询表,检索模式,并使用foreach + switch()确定要使用的字段。
But that's not what you're asking.
但这不是你想要的。
So, instead, I give you:
所以,相反,我给你:
// Assuming one table:one form, and each input-name = column name. //strip array $_POST into its key and value. foreach($_POST as $key => $val) { $vals .= "'$val', "; $keys .= "`$key`, "; } // Lest we want to generate errors, shave off the trailing comma and whitespace. $keys_strip = substr($keys, 0, -2); $vals_strip = substr($vals, 0, -2); $sql = mysql_query("INSERT INTO t1 ($keys_strip) VALUES ($vals_strip)");
For multiple tables, it got a bit trickier. I'd opt for using a quick identify at the beginning of each form, so we can do the following:
对于多个表,这有点棘手。我选择在每个表格的开头使用一个快速识别,这样我们可以做以下的事情:
// Assuming two+ table:one form, for each input, name='t1:column_name'; assume tables are defined in an array per form for easy reference. //strip array $_POST into key and value, then separate the key into two separate fields. This will ONLY work for t1:column-name set up; an if statement can be put in to deal with the remaining information. foreach ($_POST as $key as val) { // This will result in keys_t1 = key and vals_t1 = val. if (preg_match('/^(\w.+):(\w.+)$/', $key, $t_key)) { ${"keys_".$t_key[1]} = "$t_key[2], "; ${"vals_".$t_key[1]} = "$var, "; } } // Assume $tables array, containing tables for THIS insert. foreach ($tables AS $table) { $keys_strip = substr(${"keys_".$table}, 0, -2); $vals_strip = substr(${"vals_".$table}, 0, -2); $sql = mysql_query("INSERT INTO table ($keys_strip) VALUES ($vals_strip)"); }
Some tooling might be required to get this to work right, but it should get you to where you need to go. Mind the fact that this will only INSERT
form-based information. If there's anything you need... well... I strongly recommend using a hidden input type.
可能需要一些工具来让它正常工作,但是它应该能让您到达需要的地方。注意,这只会插入基于表单的信息。如果你需要什么……嗯…我强烈建议使用隐藏的输入类型。
#1
2
Try this way:
试试这种方法:
<?php
abstract class FormData
{
const BOOLEAN = 'bool';
const INTEGER = 'int';
const FLOAT = 'float';
const STRING = 'string';
protected $_types = array();
public static function create($data)
{
$action = isset($data['action']) ? $data['action'] : '';
switch ($action)
{
case 'form1': return new MyForm1($data);
default: return null;
}
return null;
}
protected function loadPostVars($data)
{
foreach ($data AS $var=>$value)
{
$value = $this->convertVar($var, $value);
if (!is_null($value) && property_exists($this, $var))
{
$this->$var = $value;
}
}
}
protected function convertVar($var, $value)
{
if (array_key_exists($var, $this->_types))
{
$type = $this->_types[$var];
switch ($type)
{
case FormData::BOOLEAN: return (bool)(int)$value;
case FormData::INTEGER: return (int)$value;
case FormData::FLOAT: return (float)$value;
case FormData::STRING: // drop down
default:
return myEscapeString($value);
}
}
return null;
}
}
class MyForm1 extends FormData
{
public $fld1;
public $fld2;
public $fld3;
// etc...
public function __construct($data)
{
$this->_types = array(
'fld1' => FormData::INTEGER,
'fld2' => FormData::STRING,
'fld3' => FormData::BOOLEAN,
);
$this->loadPostVars($data);
}
}
// And finally process your form data
// You should add hidden input 'action' to each form to identify the form
if ($form = FormData::create($_POST))
{
echo $form->fld1, $form->fld2, $form->fld3;
}
else
{
exit('error: unknown action provided');
}
?>
This solution has to be improved - I've written it very fast. But I hope you'll catch the main idea. Hope this will help. Sure, in each form class you can add specific methods to process the request etc.
这个解决方案需要改进——我写得很快。但我希望你能抓住主要的想法。希望这将帮助。当然,在每个表单类中都可以添加特定的方法来处理请求等等。
#2
#3
1
I've used something similar in one of my projects. Basically, I define all the fields, including how to display them, what data type they have (number, date, etc), as well as what to do with them once posted back. Then you pass that information to one function which generates a HTML form. When that form is submitted, you pass the same information to a different function which performs the necessary tasks.
我曾在一个项目中使用过类似的东西。基本上,我定义了所有的字段,包括如何显示它们,它们具有什么数据类型(数字、日期等),以及一旦发布回来该如何处理它们。然后将这些信息传递给生成HTML表单的函数。当提交表单时,您将相同的信息传递给执行必要任务的另一个函数。
In my specific case, it was just used to create search forms, so the processing involved creating a SELECT sql statement. Here's a sample of one of the field definitions:
在我的具体示例中,它只是用于创建搜索表单,因此处理涉及创建SELECT sql语句。以下是其中一个字段定义的示例:
$criteria = array(
array("label" => "Search clients",
"type" => "radio",
"values"=> array("1" => "Just " . $client->getName(),
"2" => "All clients"),
"where" => array("1" => "c.`clientId` = " . $client->getId(),
"2" => "1"), // always true
"default" => "1"),
array("label" => "Last Name",
"type" => "text",
"where" => "s.`lastName` LIKE '%s'"),
array("label" => "First Name",
"type" => "text",
"where" => "s.`firstName` LIKE '%s'")
// etc...
#4
0
Just 2 small thoughts..
2小的想法. .
1) Do you show all 9 forms in one page? If yes - I reeeally don't think it's a good idea.
2) Why don't you divide your forms to different pages and give same names to fields on your forms where it is possible?
你把所有的9张表格都显示在一页里吗?如果是的话——我真的不认为这是个好主意。你为什么不把你的表单分成不同的页面,给表单上可能的字段起相同的名字呢?
#5
0
You can iterate on the $_POST array with a foreach.
可以使用foreach迭代$_POST数组。
foreach($_POST as $name => $value) {
echo $name, ' ', $value, '<br />';
}
#6
0
As SleepyCod said, your breast bet is operating a foreach
, but the answer needs to be expanded upon:
正如SleepyCod所言,你的乳房赌注是为每个人设定的,但答案需要扩展:
- Are the form fields equivalent to the table?
- 表单字段是否等价于表?
- Is each form being used to
UPDATE
orINSERT
into more than table? - 是否每个表单都被用于更新或插入到多个表中?
The reason I ask is because this is something that I've done for my webpage. I created a dynamic form structure where the table is queried in question, the schema is retrieved and a foreach
+ switch()
is used to determine WHAT the field is to be used.
我之所以问这个问题,是因为这是我为我的网页所做的。我创建了一个动态表单结构,在其中查询表,检索模式,并使用foreach + switch()确定要使用的字段。
But that's not what you're asking.
但这不是你想要的。
So, instead, I give you:
所以,相反,我给你:
// Assuming one table:one form, and each input-name = column name. //strip array $_POST into its key and value. foreach($_POST as $key => $val) { $vals .= "'$val', "; $keys .= "`$key`, "; } // Lest we want to generate errors, shave off the trailing comma and whitespace. $keys_strip = substr($keys, 0, -2); $vals_strip = substr($vals, 0, -2); $sql = mysql_query("INSERT INTO t1 ($keys_strip) VALUES ($vals_strip)");
For multiple tables, it got a bit trickier. I'd opt for using a quick identify at the beginning of each form, so we can do the following:
对于多个表,这有点棘手。我选择在每个表格的开头使用一个快速识别,这样我们可以做以下的事情:
// Assuming two+ table:one form, for each input, name='t1:column_name'; assume tables are defined in an array per form for easy reference. //strip array $_POST into key and value, then separate the key into two separate fields. This will ONLY work for t1:column-name set up; an if statement can be put in to deal with the remaining information. foreach ($_POST as $key as val) { // This will result in keys_t1 = key and vals_t1 = val. if (preg_match('/^(\w.+):(\w.+)$/', $key, $t_key)) { ${"keys_".$t_key[1]} = "$t_key[2], "; ${"vals_".$t_key[1]} = "$var, "; } } // Assume $tables array, containing tables for THIS insert. foreach ($tables AS $table) { $keys_strip = substr(${"keys_".$table}, 0, -2); $vals_strip = substr(${"vals_".$table}, 0, -2); $sql = mysql_query("INSERT INTO table ($keys_strip) VALUES ($vals_strip)"); }
Some tooling might be required to get this to work right, but it should get you to where you need to go. Mind the fact that this will only INSERT
form-based information. If there's anything you need... well... I strongly recommend using a hidden input type.
可能需要一些工具来让它正常工作,但是它应该能让您到达需要的地方。注意,这只会插入基于表单的信息。如果你需要什么……嗯…我强烈建议使用隐藏的输入类型。