Reputation: 124
I have data being posted from another service as a string:
heading="firstname","lastname"&user_1382926="Mike",Smith"&user_1383059="Sonny","Williams"&user_1303EM000014="Mike","Jones"
I'm lost in parsing this and because the user_* could be anything, it's not consistant.
I tried:
$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);
}
But it just gives me:
"firstname","lastname""Mike",Smith""Sonny","Williams""Mike","Jones"
I want to be able to post it to:
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$stmt = $mysqli->prepare("INSERT INTO usertest (firstname,lastname) VALUES (?,?)");
$stmt->bind_param('ss', $firstname, $lastname);
$stmt->execute();
How do I parse this in order to then properly post?
Upvotes: 4
Views: 92
Reputation: 413
First your string seems to be missing a quote. See
&user_1382926="Mike",Smith"
Second, using explode seems like a bad idea as you will explode & and = inside of the quoted fields.
The way that I would normally approach this is a state machine. Using a regex (see PHP - split String in Key/Value pairs) is much simpler.
The language you are trying to match appears to be:
The regex to get the key value pairing is:
$regex = '/&?([^=]+)=([^&]+)/';
preg_match_all($regex, $header, $r);
$result = array_combine($r[1], $r[2]);
The first entry in $result will contain the key 'header' and the value '"firstname","lastname"'.
Now we just need to convert the values in result from a string to a list of strings.
foreach ($result as $key => $value) {
$regex = '("[^"]+")';
preg_match_all($regex, $value, $r);
$result[$key] = $r;
}
This is missing some edge cases such as escaped quotes inside of the values but should work for most cases.
In your example it produces:
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"
)
)
Upvotes: 0
Reputation: 3800
Since the author wrote: "Yes, I want to post it to an external URL." and "Unfortunately I do not have control over it. That's part of the problem. " I guess your problem can be solved like this.
Warning: This isn't the best solution, it may work, but it will cause a overhead. Please try to explain better what exactly you want to archieve.
$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);
Upvotes: 0
Reputation: 479
I hate answers like these, but do you have any control over the post to you? That data is a mess and doesn't conform to the standards at all.
It should look like this... as you know:
firstname=bob&lastname=smith&user=123654&heading=someheading&...
Now, even if you have multiple people coming in one post, thats ok too - as long as they are in order. That would look like...
firstname=bob&lastname=smith&firstname=william&lastname=jones
When you get data like that, you can parse it like:
foreach($_POST['firstname'] as $k => $v){
echo "Key: ".$k;
echo " Value: ".$v;
}
would print Key: firstname Value:bob Key: firstname Value: william
Upvotes: 0
Reputation: 16828
Very rough, but this is the outcome that I arrived at:
$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();
}
Note: I added a double quote before Smith ("Mike","Smith"
) in your original string, as I was hoping it was just missing from the OP.
Upvotes: 1