我有数据从另一个服务作为字符串发布:heading="firstname","lastname"&user_1382926="Mike",Smith"&user_1383059="Sonny","Williams"&user_1303EM000014="Mike","Jones"
我在解析这个时迷失了,因为user_*可以是任何东西,所以它不一致。
我试着:
$query = explode('&', 'heading="firstname","lastname"&user_1382926="Mike",Smith"&user_1383059="Sonny","Williams"&user_1303EM000014="Mike","Jones"');
$params = array();
foreach( $query as $param ){
list($name, $value) = explode('=', $param);
echo $params[urldecode($name)][] = urldecode($value);
}
但是它给了我:
"firstname","lastname""Mike",Smith""Sonny","Williams""Mike","Jones"
我想把它发布到:
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$stmt = $mysqli->prepare("INSERT INTO usertest (firstname,lastname) VALUES (?,?)");
$stmt->bind_param('ss', $firstname, $lastname);
$stmt->execute();
我如何解析这个以便然后正确发布?
非常粗糙,但这是我得出的结果:
$names = array();
$string = 'heading="firstname","lastname"&user_1382926="Mike","Smith"&user_1383059="Sonny","Williams"&user_1303EM000014="Mike","Jones"';
$arr = explode("&",$string);
foreach($arr as $key_values){
if(substr($key_values,0,5) == 'user_'){
$piecies = explode("=",$key_values);
foreach($piecies as $key=>$val){
if($key%2==0){
continue;
}
preg_match_all('/"(.*?)","(.*?)"/',$val,$first_last_name);
$names[] = array('firstname'=>$first_last_name[1],'lastname'=>$first_last_name[2]);
}
}
}
echo '<pre>',print_r($names),'</pre>';
foreach($names as $name){
$firstname = $name['firstname'];
$lastname = $name['lastname'];
$stmt = $mysqli->prepare("INSERT INTO usertest (firstname,lastname) VALUES (?,?)");
$stmt->bind_param('ss', $firstname, $lastname);
$stmt->execute();
}
注意:我在您的原始字符串中添加了Smith ("Mike","Smith"
)之前的双引号,因为我希望它只是从op中丢失。
我讨厌这样的回答,但是你对你的帖子有控制权吗?这些数据乱成一团,根本不符合标准。
应该是这样的…如你所知:
firstname=bob&lastname=smith&user=123654&heading=someheading&...
现在,即使你有很多人来一个帖子,这也没关系-只要他们是有序的。这看起来像…
firstname=bob&lastname=smith&firstname=william&lastname=jones
当你得到这样的数据时,你可以这样解析它:
foreach($_POST['firstname'] as $k => $v){
echo "Key: ".$k;
echo " Value: ".$v;
}
打印键值:firstname值:bob键值:firstname值:william
既然作者写了:"是的,我想把它发布到一个外部URL。"和"不幸的是我无法控制它。这是问题的一部分。" 我想你的问题可以这样解决。
警告:这不是最好的解决方案,它可能工作,但它会导致开销。请尽量解释清楚你要存档的具体内容。
$url = 'user_1382926="Mike","Smith"&user_1383059="Sonny","Williams"&user_1303EM000014="Mike","Jones"';
$query = explode('&', str_replace('"', '', urldecode($url)));
$params = array();
foreach( $query as $param )
{
list($name, $value) = explode('=', $param);
$q = explode(',', $value);
$params[$name] = 'firstname=' . $q[0] . '&lastname=' . $q[1];
}
$url = 'http://domain.com/post.php';
$ch = curl_init();
foreach ( $params as $current )
{
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, 2);
curl_setopt($ch,CURLOPT_POSTFIELDS, $current);
$result = curl_exec($ch);
}
curl_close($ch);
首先,您的字符串似乎缺少引号。看到
&user_1382926="Mike",Smith"
第二,使用explosion似乎是个坏主意,因为你会爆炸&
我通常使用的方法是状态机。使用正则表达式(参见PHP -在键/值对中拆分字符串)要简单得多。
您尝试匹配的语言似乎是:
- 键可以由1个或多个字母、数字或下划线字符组成。
- 值是逗号分隔的引号字符串列表
- 键和值用等号分隔
- 键值对由& 分隔
获取键值配对的正则表达式为:
$regex = '/&?([^=]+)=([^&]+)/';
preg_match_all($regex, $header, $r);
$result = array_combine($r[1], $r[2]);
$result中的第一个条目将包含键'header'和值' firstname ', ' lastname '。
现在我们只需要将result中的值从字符串转换为字符串列表。
foreach ($result as $key => $value) {
$regex = '("[^"]+")';
preg_match_all($regex, $value, $r);
$result[$key] = $r;
}
这遗漏了一些边缘情况,例如值内部的转义引号,但应该适用于大多数情况。
在你的例子中,它产生:
Array
(
[heading] => Array
(
[0] => "firstname"
[1] => "lastname"
)
[user_1382926] => Array
(
[0] => "Mike"
[1] => "Smith"
)
[user_1383059] => Array
(
[0] => "Sonny"
[1] => "Williams"
)
[user_1303EM000014] => Array
(
[0] => "Mike"
[1] => "Jones"
)
)