php url query nested array with no index - php
I'm working with a third party API that receives several parameters which must be encoded like this:
text[]=Hello%20World&text[]=How%20are%20you?&html[]=<p>Just%20fine,%20thank%20you</p>
As you can see this API can accept multiple parameters for text, and also for HTML (not in the sample call).
I have used http_build_query to correctly build a query string for other APIs
$params['text'][] = 'Hello World';
$params['text'][] = 'How are you?';
$params['html'][] = '<p>Just fine, thank you</p>';
$http_query = http_build_query($params);
The problem with this approach is that it will build a query string with the numeric index:
text[0]=Hello%20World&text[1]=How%20are%20you?&html[0]=<p>Just%20fine,%20thank%20you</p>
unfortunately the API I'm working with doesn't like the numeric index and fails.
Is there any php function/class-method that can help me build a query like this quickly?
Thank you
I don't know a standard way to do it (I think there is no such way), but here's an ugly solution:
Since [] is encoded by http_build_query, you may generate string with indices and then replace them.
preg_replace('/(%5B)\d+(%5D=)/i', '$1$2', http_build_query($params));
I very much agree with the answer by RiaD, but you might run into some problems with this code (sorry I can't just make this a comment due to lack of rep).
First off, as far as I know http_build_query returns an urlencode()'d string, which means you won't have [ and ] but instead you'll have %5B and %5D.
Second, PHP's PCRE engine recognizes the '[' character as the beginning of a character class and not just as a simple '[' (PCRE Meta Characters). This may end up replacing ALL digits from your request with '[]'.
You'll more likely want something like this:
preg_replace('/\%5B\d+\%5D/', '%5B%5D', http_build_query($params));
In this case, you'll need to escape the % characters because those also have a special meaning. Provided you have a string with the actual brackets instead of the escapes, try this:
preg_replace('/\[\d+\]/', '[]', $http_query);
There doesn't seem to be a way to do this with http_build_query. Sorry. On the docs page though, someone has this:
function cr_post($a,$b=0,$c=0){
if (!is_array($a)) return false;
foreach ((array)$a as $k=>$v){
if ($c) $k=$b."[]"; elseif (is_int($k)) $k=$b.$k;
if (is_array($v)||is_object($v)) {
$r[]=cr_post($v,$k,1);continue;
}
$r[]=urlencode($k)."=" .urlencode($v);
}
return implode("&",$r);
}
$params['text'][] = 'Hello World';
$params['text'][] = 'How are you?';
$params['html'][] = '<p>Just fine, thank you</p>';
$str = cr_post($params);
echo $str;
I haven't tested it. If it doesn't work then you're going to have to roll your own. Maybe you can publish a github gist so other people can use it!
Try this:
$params['text'][] = 'Hello World';
$params['text'][] = 'How are you?';
$params['html'][] = '<p>Just fine, thank you</p>';
foreach ($params as $key => $value) {
foreach ($value as $key2 => $value2) {
$http_query.= $key . "[]=" . $value2 . "&";
}
}
$http_query = substr($http_query, 0, strlen($http_query)-1); // remove the last '&'
$http_query = str_replace(" ", "%20", $http_query); // manually encode spaces
echo $http_query;
Related
PHP Convert Unicode to text
I am receiving from a form the following urlencoded string %F0%9D%90%B4%F0%9D%91%99%F0%9D%91%92%F0%9D%91%97%F0%9D%91%8E%F0%9D%91%9B%F0%9D%91%91%F0%9D%91%9F%F0%9D%91%8E If I decode it I get the following formatted text: ๐ด๐๐๐๐๐๐๐๐ Is there any way with PHP to get the plain "Alejandra" text from the encoded or decoded string? I have tried without success several ways to do it with mb_convert_encoding($string, "UTF-16",mb_detect_encoding($string)) iconv('utf-16', 'utf-8', rawurldecode($string) and any other solution I could in stackoverflow. Edit: I tried the proposed solution $strAscii = iconv('UTF-8','ASCII//TRANSLIT',$str); but it deletes the special characters such as รกรฉรญรณรบรฑรง which we need to stay. Expected result input: ๐ด๐๐๐๐๐๐๐๐ output: Alejandra input: รlejandra output: รlejandra Thank you in advance.
urldecode or rawurldecode is sufficient. $string = "%F0%9D%90%B4%F0%9D%91%99%F0%9D%91%92%F0%9D%91%97%F0%9D%91%8E%F0%9D%91%9B%F0%9D%91%91%F0%9D%91%9F%F0%9D%91%8E"; $str = urldecode($string); var_dump($str); //string(36) "๐ด๐๐๐๐๐๐๐๐" Demo: https://3v4l.org/OMQ35 A special debugger gives me: string(36) UTF-8mb4. This means that there are also UTF-8 characters in the string that require 4 bytes. The character A is the Unicode character โ๐ดโ (U+1D434). Note: If the special UTF-8 characters cause problems, you can try to display the strings as ASCII characters with iconv. $strAscii = iconv('UTF-8','ASCII//TRANSLIT',$str); //string(9) "Alejandra"
What you are getting is called a "psuedo-alphabet", you can see a list of them here: https://qaz.wtf/u/convert.cgi. The one that you appear to be getting can be seen here: https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols Basically what you need to do is take the string, split it and use a lookup table to convert it back to regular characters. This implementation is terribly efficient but that's because I grabbed the alphabets from the above Wikipedia page and was too lazy to reorganise it. function math_symbols_to_plain_text($input, $alphabet) { $alphabets = [ ['a','๐','๐','๐','๐บ','๐ฎ','๐ข','๐','๐ถ','๐ช','๐','๐','๐','๐'], ['b','๐','๐','๐','๐ป','๐ฏ','๐ฃ','๐','๐ท','๐ซ','๐','๐','๐','๐'], ['c','๐','๐','๐','๐ผ','๐ฐ','๐ค','๐','๐ธ','๐ฌ','๐ ','๐','๐','๐'], ['d','๐','๐','๐ ','๐ฝ','๐ฑ','๐ฅ','๐','๐น','๐ญ','๐ก','๐','๐','๐'], ['e','๐','๐','๐','๐พ','๐ฒ','๐ฆ','๐','โฏ','๐ฎ','๐ข','๐','๐','๐'], ['f','๐','๐','๐','๐ฟ','๐ณ','๐ง','๐','๐ป','๐ฏ','๐ฃ','๐','๐','๐'], ['g','๐ ','๐','๐','๐','๐ด','๐จ','๐','โ','๐ฐ','๐ค','๐','๐','๐'], ['h','๐ก','โ','๐','๐','๐ต','๐ฉ','๐','๐ฝ','๐ฑ','๐ฅ','๐','๐','๐'], ['i','๐ข','๐','๐','๐','๐ถ','๐ช','๐','๐พ','๐ฒ','๐ฆ','๐','๐','๐'], ['j','๐ฃ','๐','๐','๐','๐ท','๐ซ','๐','๐ฟ','๐ณ','๐ง','๐','๐','๐'], ['k','๐ค','๐','๐','๐','๐ธ','๐ฌ','๐ ','๐','๐ด','๐จ','๐','๐','๐'], ['l','๐ฅ','๐','๐','๐ ','๐น','๐ญ','๐ก','๐','๐ต','๐ฉ','๐','๐','๐'], ['m','๐ฆ','๐','๐','๐','๐บ','๐ฎ','๐ข','๐','๐ถ','๐ช','๐','๐','๐'], ['n','๐ง','๐','๐','๐','๐ป','๐ฏ','๐ฃ','๐','๐ท','๐ซ','๐','๐','๐'], ['o','๐จ','๐','๐','๐','๐ผ','๐ฐ','๐ค','โด','๐ธ','๐ฌ','๐','๐','๐ '], ['p','๐ฉ','๐','๐','๐','๐ฝ','๐ฑ','๐ฅ','๐ ','๐น','๐ญ','๐','๐','๐ก'], ['q','๐ช','๐','๐','๐','๐พ','๐ฒ','๐ฆ','๐','๐บ','๐ฎ','๐','๐','๐ข'], ['r','๐ซ','๐','๐','๐','๐ฟ','๐ณ','๐ง','๐','๐ป','๐ฏ','๐','๐','๐ฃ'], ['s','๐ฌ','๐ ','๐','๐','๐','๐ด','๐จ','๐','๐ผ','๐ฐ','๐','๐','๐ค'], ['t','๐ญ','๐ก','๐','๐','๐','๐ต','๐ฉ','๐','๐ฝ','๐ฑ','๐','๐','๐ฅ'], ['u','๐ฎ','๐ข','๐','๐','๐','๐ถ','๐ช','๐','๐พ','๐ฒ','๐','๐','๐ฆ'], ['v','๐ฏ','๐ฃ','๐','๐','๐','๐ท','๐ซ','๐','๐ฟ','๐ณ','๐','๐','๐ง'], ['w','๐ฐ','๐ค','๐','๐','๐','๐ธ','๐ฌ','๐','๐','๐ด','๐','๐ ','๐จ'], ['x','๐ฑ','๐ฅ','๐','๐','๐ ','๐น','๐ญ','๐','๐','๐ต','๐','๐ก','๐ฉ'], ['y','๐ฒ','๐ฆ','๐','๐','๐','๐บ','๐ฎ','๐','๐','๐ถ','๐','๐ข','๐ช'], ['z','๐ณ','๐ง','๐','๐','๐','๐ป','๐ฏ','๐','๐','๐ท','๐','๐ฃ','๐ซ'], ['A','๐','๐ด','๐จ','๐ ','๐','๐','๐ผ','๐','๐','๐','๐ฌ','๐ฐ','๐ธ'], ['B','๐','๐ต','๐ฉ','๐ก','๐','๐','๐ฝ','โฌ','๐','๐ ','๐ญ','๐ฑ','๐น'], ['C','๐','๐ถ','๐ช','๐ข','๐','๐','๐พ','๐','๐','โญ','๐ฎ','๐ฒ','โ'], ['D','๐','๐ท','๐ซ','๐ฃ','๐','๐','๐ฟ','๐','๐','๐','๐ฏ','๐ณ','๐ป'], ['E','๐','๐ธ','๐ฌ','๐ค','๐','๐','๐','โฐ','๐','๐','๐ฐ','๐ด','๐ผ'], ['F','๐ ','๐น','๐ญ','๐ฅ','๐','๐','๐','โฑ','๐','๐','๐ฑ','๐ต','๐ฝ'], ['G','๐','๐บ','๐ฎ','๐ฆ','๐','๐','๐','๐ข','๐','๐','๐ฒ','๐ถ','๐พ'], ['H','๐','๐ป','๐ฏ','๐ง','๐','๐','๐','โ','๐','โ','๐ณ','๐ท','โ'], ['I','๐','๐ผ','๐ฐ','๐จ','๐','๐','๐','โ','๐','โ','๐ด','๐ธ','๐'], ['J','๐','๐ฝ','๐ฑ','๐ฉ','๐','๐','๐ ','๐ฅ','๐','๐','๐ต','๐น','๐'], ['K','๐','๐พ','๐ฒ','๐ช','๐','๐','๐','๐ฆ','๐','๐','๐ถ','๐บ','๐'], ['L','๐','๐ฟ','๐ณ','๐ซ','๐','๐','๐','โ','๐','๐','๐ท','๐ป','๐'], ['M','๐','๐','๐ด','๐ฌ','๐ ','๐','๐','โณ','๐','๐','๐ธ','๐ผ','๐'], ['N','๐','๐','๐ต','๐ญ','๐ก','๐','๐','๐ฉ','๐','๐','๐น','๐ฝ','โ'], ['O','๐','๐','๐ถ','๐ฎ','๐ข','๐','๐','๐ช','๐','๐','๐บ','๐พ','๐'], ['P','๐','๐','๐ท','๐ฏ','๐ฃ','๐','๐','๐ซ','๐','๐','๐ป','๐ฟ','โ'], ['Q','๐','๐','๐ธ','๐ฐ','๐ค','๐','๐','๐ฌ','๐ ','๐','๐ผ','๐','โ'], ['R','๐','๐ ','๐น','๐ฑ','๐ฅ','๐','๐','โ','๐ก','โ','๐ฝ','๐','โ'], ['S','๐','๐','๐บ','๐ฒ','๐ฆ','๐','๐','๐ฎ','๐ข','๐','๐พ','๐','๐'], ['T','๐','๐','๐ป','๐ณ','๐ง','๐','๐','๐ฏ','๐ฃ','๐','๐ฟ','๐','๐'], ['U','๐','๐','๐ผ','๐ด','๐จ','๐','๐','๐ฐ','๐ค','๐','๐','๐','๐'], ['V','๐','๐','๐ฝ','๐ต','๐ฉ','๐','๐','๐ฑ','๐ฅ','๐','๐','๐ ','๐'], ['W','๐','๐','๐พ','๐ถ','๐ช','๐','๐','๐ฒ','๐ฆ','๐','๐','๐','๐'], ['X','๐','๐','๐ฟ','๐ท','๐ซ','๐','๐','๐ณ','๐ง','๐','๐','๐','๐'], ['Y','๐','๐','๐','๐ธ','๐ฌ','๐ ','๐','๐ด','๐จ','๐','๐','๐','๐'], ['Z','๐','๐','๐','๐น','๐ญ','๐ก','๐','๐ต','๐ฉ','โจ','๐ ','๐','โค'] ]; $replace = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']; $lookup = [ 'serif-normal', 'serif-bold', 'serif-italic', 'serif-bolditalic', 'sans-normal', 'sans-bold', 'sans-italic', 'sans-bolditalic', 'script-normal', 'script-bold', 'franktur-normal', 'fraktur-bold', 'monospace', 'doublestruck' ]; $map_index = array_search($alphabet, $lookup); $split = mb_str_split($input); $output = ''; foreach ($split as $char) { foreach ($alphabets as $i => $letter) { if ($letter[$map_index] === $char) $output .= $replace[$i]; } } return $output; } $input = '๐ด๐๐๐๐๐๐๐๐'; $output = math_symbols_to_plain_text($input, 'serif-italic'); echo $input . PHP_EOL . $output . PHP_EOL; Yields: ๐ด๐๐๐๐๐๐๐๐ Alejandra
If I am not wrong, you are trying to decode URL then why you are not trying to use urldecode() follow this .PHP DOC
Trim a string until specific character appears
I want to trim a string and delete everything before a specific character, because I am using an API that gives me some unwanted data in its callback which I want to delete. The Callback looks like this: {"someVar":true,"anotherVar":false,"items":[ {"id":123456, [...] } And I only want the code after the [ , so how can I split a string like this? Thank you!
It is JSON, so you could just decode it: $data = json_decode($string); If you really want to trim up to a certain character then you can just find the character's position and then cut off everything before it: if (($i = strpos($string, '[')) !== false) { $string = substr($string, $i + 1); }
You can use various functions. For example: $someVar = explode('[',$string,2); $wantedData = $someVar[1]; Or if you want only data between [ and ] then use: $pattern = '~\[([^\]])\]~Ui'; if (preg_match($pattern,$inputString,$matches) { $wantedData = $matches[1]; } Edit: Thats what you use if you want extract some string from another. But as #Dagon noticed, it's json and you can use other function to parse it. I will leave above anyway, because it's more general to the question of extracting string from another.
Parse a PHP string with PHP parser
I wanted to ask whether I'm doomed to use eval() or there may be a work around. $str = 'Hello, $user.'; // $str is a string gotten from an external source // Many lines later $user = 'John Doe'; echo eval('return "'.$str.'";'); Not a big fan of eval, as probably many of you. Is there another way to parse a PHP string?
You can try with: $str = 'Hello, $user.'; $data = array( 'user' => 'John Doe' ); $output = preg_replace_callback('/\$(\w+)/', function($key) use ($data) { return isset($data[$key[1]]) ? $data[$key[1]] : $key[1]; }, $str); var_dump($output); Output: string 'Hello, John Doe.' (length=16)
You can try create_function. It doesn't execute just any piece of code, but wraps it in a function. Apart from that, it's not that different. But if your goal is to replace variables alone, you might want to have a look at the str_replace function. That will work fine for a fixed set of variables. If you want to be more flexible, you can use preg_replace or preg_replace_callback, but note that a 'flexible' function is probably a function that allows you to use any variable. That also allows people to exploit that feature to read variables that they are not supposed to read.
I need to get a value in PHP "preg_match_all" - Basic (I think)
I am trying to use a License PHP Systemโฆ I will like to show the status of their license to the users. The license Server gives me this: name=Service_Name;nextduedate=2013-02-25;status=Active I need to have separated the data like this: $name = โService_Nameโ; $nextduedate = โ2013-02-25โ; $status = โActiveโ; I have 2 days tring to resolve this problem with preg_match_all but i cant :(
This is basically a query string if you replace ; with &. You can try parse_str() like this: $string = 'name=Service_Name;nextduedate=2013-02-25;status=Active'; parse_str(str_replace(';', '&', $string)); echo $name; // Service_Name echo $nextduedate; // 2013-02-25 echo $status; // Active
This can rather simply be solved without regex. The use of explode() will help you. $str = "name=Service_Name;nextduedate=2013-02-25;status=Active"; $split = explode(";", $str); $structure = array(); foreach ($split as $element) { $element = explode("=", $element); $$element[0] = $element[1]; } var_dump($name); Though I urge you to use an array instead. Far more readable than inventing variables that didn't exist and are not explicitly declared.
It sounds like you just want to break the text down into separate lines along the semicolons, add a dollar sign at the front and then add spaces and quotes. I'm not sure you can do that in one step with a regular expression (or at least I don't want to think about what that regular expression would look like), but you can do it over multiple steps. Use preg_split() to split the string into an array along the semicolons. Loop over the array. Use str_replace to replace each '=' with ' = "'. Use string concatenation to add a $ to the front and a "; to the end of each string. That should work, assuming your data doesn't include quotes, equal signs, semicolons, etc. within the data. If it does, you'll have to figure out the parsing rules for that.
filter specific string in php
$var="UseCountry=1 UseCountryDefault=1 UseState=1 UseStateDefault=1 UseLocality=1 UseLocalityDefault=1 cantidad_productos=5 expireDays=5 apikey=ABQIAAAAFHktBEXrHnX108wOdzd3aBTupK1kJuoJNBHuh0laPBvYXhjzZxR0qkeXcGC_0Dxf4UMhkR7ZNb04dQ distancia=15 AutoCoord=1 user_add_locality=0 SaveContactForm=0 ShowVoteRating=0 Listlayout=0 WidthThumbs=100 HeightThumbs=75 WidthImage=640 HeightImage=480 ShowImagesSystem=1 ShowOrderBy=0 ShowOrderByDefault=0 ShowOrderDefault=DESC SimbolPrice=$ PositionPrice=0 FormatPrice=0 ShowLogoAgent=1 ShowReferenceInList=1 ShowCategoryInList=1 ShowTypeInList=1 ShowAddressInList=1 ShowContactLink=1 ShowMapLink=1 ShowAddShortListLink=1 ShowViewPropertiesAgentLink=1 ThumbsInAccordion=5 WidthThumbsAccordion=100 HeightThumbsAccordion=75 ShowFeaturesInList=1 ShowAllParentCategory=0 AmountPanel= AmountForRegistered=5 RegisteredAutoPublish=1 AmountForAuthor=5 AmountForEditor=5 AmountForPublisher=5 AmountForManager=5 AmountForAdministrator=5 AutoPublish=1 MailAdminPublish=1 DetailLayout=0 ActivarTabs=0 ActivarDescripcion=1 ActivarDetails=1 ActivarVideo=1 ActivarPanoramica=1 ActivarContactar=1 ContactMailFormat=1 ActivarReservas=1 ActivarMapa=1 ShowImagesSystemDetail=1 WidthThumbsDetail=120 HeightThumbsDetail=90 idCountryDefault=1 idStateDefault=1 ms_country=1 ms_state=1 ms_locality=1 ms_category=1 ms_Subcategory=1 ms_type=1 ms_price=1 ms_bedrooms=1 ms_bathrooms=1 ms_parking=1 ShowTextSearch=1 minprice= maxprice= ms_catradius=1 idcatradius1= idcatradius2= ShowTotalResult=1 md_country=1 md_state=1 md_locality=1 md_category=1 md_type=1 showComments=0 useComment2=0 useComment3=0 useComment4=0 useComment5=0 AmountMonthsCalendar=3 StartYearCalendar=2009 StartMonthCalendar=1 PeriodOnlyWeeks=0 PeriodAmount=3 PeriodStartDay=1 apikey=ABQIAAAAJ879Hg7OSEKVrRKc2YHjixSmyv5A3ewe40XW2YiIN-ybtu7KLRQiVUIEW3WsL8vOtIeTFIVUXDOAcQ "; in that string only i want "api==ABQIAAAAJ879Hg7OSEKVrRKc2YHjixSmyv5A3ewe40XW2YiIN-ybtu7KLRQiVUIEW3WsL8vOtIeTFIVUXDOAcQ"; plz guide me correctly;
EDIT As shamittomar pointed out, the parse_str will not work for this situation, posted the proper regex below. Given this seems to be a QUERY STRING, use the parse_str() function PHP provides. UPDATE If you want to do it with regex using preg_match() as powertieke pointed out: preg_match('/apikey=(.*)/', $var, $matches); echo $matches[1]; Should do the trick.
preg_match(); should be right up your alley
people are so fast to jump to preg match when this can be done with regular string functions thats faster. $string = ' expireDays=5 apikey=ABQIAAAAFHktBEXrHnX108wOdzd3aBTupK1kJuoJNBHuh0laPBvYXhjzZxR0qkeXcGC_0Dxf4UMhkR7ZNb04dQ distancia=15 AutoCoord=1'; //test to see what type of line break it is and explode by that. $parts = (strstr($string,"\r\n") ? explode("\r\n",$string) : explode("\n",$string)); $data = array(); foreach($parts as $part) { $sub = explode("=",trim($part)); if(!empty($sub[0]) || !empty($sub[1])) { $data[$sub[0]] = $sub[1]; } } and use $data['apikey'] for your api key, i would also advise you to wrpa in function. I can bet this is a better way to parse the string and much faster. function ParsemyString($string) { $parts = (strstr($string,"\r\n") ? explode("\r\n",$string) : explode("\n",$string)); $data = array(); foreach($parts as $part) { $sub = explode("=",trim($part)); if(!empty($sub[0]) || !empty($sub[1])) { $data[$sub[0]] = $sub[1]; } } return $data; } $data = ParsemyString($string);
First of all, you are not looking for api==ABQIAAAAJ879Hg7OSEKVrRKc2YHjixSmyv5A3ewe40XW2YiIN-ybtu7KLRQiVUIEW3WsL8vOtIeTFIVUXDOAcQ but you are looking for apikey=ABQIAAAAJ879Hg7OSEKVrRKc2YHjixSmyv5A3ewe40XW2YiIN-ybtu7KLRQiVUIEW3WsL8vOtIeTFIVUXDOAcQ It is important to know if the api-key property always occurs at the end and if the length of the api-key value is always the same. I this is the case you could use the PHP substr() function which would be easiest. If not you would most probably need a regular expression which you can feed to PHPs preg_match() function. Something along the lines of apikey==[a-zA-Z0-9\-] Which matches an api-key containing a-z in both lowercase and uppercase and also allows for dashes in the key. If you are using the preg_match() function you can retrieve the matches (and thus your api-key value).