解析一个字符串然后发布


Parsing a string to then post

我有数据从另一个服务作为字符串发布: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"
        )
  )