Parsing a string for publication

I have data that is sent from another service in the form of a string: heading="firstname","lastname"&user_1382926="Mike",Smith"&user_1383059="Sonny","Williams"&user_1303EM000014="Mike","Jones"

I get lost in parsing this and because user_ * can be anything, it is not consistent.

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 send it:

 $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 send a message correctly?

+4
source share
4 answers

Very rude, but this is the result I came to:

 $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 quotation mark in front of Smith ( "Mike","Smith" ) in the source line, as I was hoping that it was simply not in the OP.

+1
source

At first, your line seems to skip the quote. Cm.

  &user_1382926="Mike",Smith" 

Secondly, using an explosion seems like a bad idea, as you will explode and = inside the specified fields.

The way I usually approach this is a state machine. Using a regular expression (see PHP - breaking lines in Key / Value pairs ) is much simpler.

The language you are trying to match is as follows:

  • Keys can consist of 1 or more alphanumeric characters or underscores.
  • Values ​​are a list of quoted strings separated by commas.
  • Keys and values ​​are separated by an equal sign
  • A pair of key values ​​is separated by &

A regular expression to get the value of a key value:

 $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 ​​of the result from a string to a list of strings.

 foreach ($result as $key => $value) { $regex = '("[^"]+")'; preg_match_all($regex, $value, $r); $result[$key] = $r; } 

In this case, some boundary cases are missing, such as escaped quotation marks inside values, but they should work in most cases.

In your example, this 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" ) ) 
0
source

I hate such answers, but do you have any control over this record? This data is erratic and does not meet 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 several people coming to one post, this is also normal - as long as they are in order. It will look like ...

 firstname=bob&lastname=smith&firstname=william&lastname=jones 

When you receive the data, you can analyze it like this:

 foreach($_POST['firstname'] as $k => $v){ echo "Key: ".$k; echo " Value: ".$v; } 

will print Key: firstname Value: bob Key: firstname Value: william

0
source

As the author wrote: "Yes, I want to publish it to an external URL." and "Unfortunately, I do not control it. This is part of the problem." I think your problem can be solved that way.

A warning. This is not the best solution, it may work, but it will cause overhead. Try to explain what exactly you want to archive.

 $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); 
0
source

Source: https://habr.com/ru/post/1484313/


All Articles