如何解析类似于.ini文件的格式化文本?
我有一个 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 代码应该解析用户数和每个用户信息并分别保存每个用户信息。
我的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值,pwdvalue =,它有时会为日期提供错误的格式,从而阻止保存。
作为一种解决方法,在每个输入的用户名和密码后放置空格后,所有数据都会成功解析。
另外,当我在输入表单中输入多个用户时:
[account]
user = {user1}
pwd = {password1}
expdate = 2028-01-01
[account]
user = {user2}
pwd = {password2}
expdate = 2028-01-01
PHP 代码只读取第一个用户并只保存第一个用户的信息,我希望它们都被保存。
所以:
- 我希望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
)
)
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
)
)
上网查一下。
接下来,处理解析的信息很简单:
parse_ini_string()能够在一次调用中解析整个字符串并正确处理这些部分,如果其第二个参数是true. 但是,因为所有部分都被命名,account所以它合并了值;输入中稍后出现的键值对会覆盖之前的值。
这就是为什么我们首先将输入分成几部分然后一次输入parse_ini_string()一个部分的原因。