问题描述
我有一个 HTML 格式的输入表单,用于使用 PHP 将用户数据导入数据库 (MysqL)。
输入中的信息必须是这样的:
[account]
user = {user1}
pwd = {password1}
expdate = 2028-01-01
[account]
user = {user2}
pwd = {password2}
expdate = 2028-01-01
[account]
user = {user3}
pwd = {password3}
expdate = 2028-01-01
现在,PHP 代码应该解析用户数和每个用户信息并分别保存每个用户信息。
$users = $_POST["users"];
$users = explode(chr(10) . chr(10),$users);
for ($i = 0; $i < count($users); $i++) {
$users[$i] = explode(" ",$users[$i]);
$username = $users[$i][2];
$pwd = $users[$i][5];
$exp = $users[$i][8];
if (strtotime($exp) === false) {
// ...code
} else {
$expiredate = date("Y-m-d",strtotime($exp));
}
}
当输入是单个用户时:
[account]
user = {user1}
pwd = {password1}
expdate = 2028-01-01
我的输出被破坏了(这里是 var_export()
输出):
array (
'username' => '{user1}
pwd','pwd' => '=','exp' => '2028-01-01'
)
问题在于爆炸——pwd
键附加到 username
值,pwd
值 =
,它有时会给出错误的格式防止被保存的日期。
作为一种解决方法,在每个输入的用户名和密码后放置空格后,所有数据都解析成功。
此外,当我在输入表单中输入多个用户时:
[account]
user = {user1}
pwd = {password1}
expdate = 2028-01-01
[account]
user = {user2}
pwd = {password2}
expdate = 2028-01-01
PHP 代码只读取第一个用户并只保存第一个用户的信息,我希望它们都被保存。
所以:
尝试编辑我的代码并搜索了很多,很不走运,不知道PHP代码有什么问题。
解决方法
您的输入看起来像一个 .ini
文件。
使用 explode()
将输入字符串拆分为由 [account]
分隔的片段,然后使用 parse_ini_string()
解析每个片段并获取数组中的数据:
$users = <<< END
[account]
user = {user1}
pwd = {password1}
expdate = 2028-01-01
[account]
user = {user2}
pwd = {password2}
expdate = 2028-01-01
[account]
user = {user3}
pwd = {password3}
expdate = 2028-01-01
END;
// Use $users = $_POST['users'] in the real code
// Parse the input data
$data = array_map(
function($entry) { return parse_ini_string($entry); },array_filter( // remove the empty entries (before the first '[account]',between two consecutive appearances of '[account]'
explode('[account]',$users),function($entry) { return strlen(trim($entry)); }
)
);
print_r($data);
输出为:
Array
(
[1] => Array
(
[user] => {user1}
[pwd] => {password1}
[expdate] => 2028-01-01
)
[2] => Array
(
[user] => {user2}
[pwd] => {password2}
[expdate] => 2028-01-01
)
[3] => Array
(
[user] => {user3}
[pwd] => {password3}
[expdate] => 2028-01-01
)
)
接下来,处理解析的信息很简单:
foreach ($data as $account) {
// do something with $account['user'],$account['pwd'],$account['expdate']
// Use the DateTime class and its friends to validate and handle $account['expdate']
}
parse_ini_string()
能够在一次调用中解析整个字符串并正确处理这些部分,如果它的第二个参数是 true
。但是,因为所有部分都被命名为 account
,所以它合并了值;输入中稍后出现的键值对会覆盖之前的值。
这就是为什么我们首先将输入分成几部分,然后一次输入 parse_ini_string()
一个部分的原因。
你可以试试这个
PHP - HTML :
<div class="all_forms">
<?php for ($z = 0; $z < 5; $z++) { ?>
<form method="POST" id="passenger-<?= $z ?>-details">
<input type="text" class="form-control" name="username" placeholder="Username">
<input type="password" class="form-control" name="password" placeholder="Password">
<input type="date" class="form-control" name="date" placeholder="date">
</form>
<?php } ?>
</div>
JavaScript - JQuery
var passenger_details_array = [];
$('.all_forms').find("form").map(function(idx,form) {
var str = $('#' + form.id).serialize();
passenger_details_array.push(str);
});
var data = {
token: 'SOME_SECURITY_TOKEN',passenger_details: passenger_details_array
};
$.post('http://domain/path/file.php',data,function(response) {
console.log(response);
});
PHP - Saving Info
$passenger_details = $_POST['passenger_details'];
foreach ($passenger_details as $value) {
parse_str($value,$tmp);
//here you have $tmp and in this you will find all proper details like (one by one)
// ['username' => 'U1','password' => 'user1_pass','date' => 'whatever']
}
//$passenger_details has data like
[
['username' => 'U1','date' => 'whatever'],['username' => 'U2','password' => 'user2_pass',['username' => 'U3','password' => 'user3_pass','date' => 'whatever']
]
,
在 [account]
行上拆分,带有可选的前导换行符序列和强制性的尾随换行符序列。不允许在爆炸中产生空元素。
\R
匹配与平台无关的换行序列,因此不必担心 \r\n
与 \n
问题。
^
(字符串锚点的开头)由 m
模式修饰符修改,使其与每一行的开头匹配。
?
表示零或之前的任何内容之一。这使得尾随的 \R
成为可选的。
如果您的真实文本在用户详细信息之间有一个空行,您只需在前导 {2}
后添加 \R
以使用额外的换行符序列。
对每个生成的元素调用 parse_ini_string()
。清洁和完成;不需要额外的过滤或修整。爆炸过程不再麻烦。
代码:(Demo)
$data = <<<NOT_INI
[account]
user = {user1}
pwd = {password1}
expdate = 2028-01-01
[account]
user = {user2}
pwd = {password2}
expdate = 2028-01-01
[account]
user = {user3}
pwd = {password3}
expdate = 2028-01-01
NOT_INI;
var_export(
array_map(
'parse_ini_string',preg_split(
'~\R?^\[account]\R~m',$data,null,PREG_SPLIT_NO_EMPTY
)
)
);
输出:
array (
0 =>
array (
'user' => '{user1}','pwd' => '{password1}','expdate' => '2028-01-01',),1 =>
array (
'user' => '{user2}','pwd' => '{password2}',2 =>
array (
'user' => '{user3}','pwd' => '{password3}',)