I'm tying to convert from this formatted string:
$filtersStr = "id:1||name:alex";
to:
['id' => 1,'name' => 'alex']
My solution for now:
foreach(explode('||', $filtersStr) as $filter){
list($k, $v) = explode(':', $filter);
$filters[ $k ] = $v;
}
I'm looking for a more elegant way.
3 Answers 3
You can use the amazing parse_str()
function. It does everything you need. But you are using different delimiters for key => value
pairs. If you change those to &
and =
, you can do like this:
$filtersStr = 'id=1&name=alex';
parse_str($filtersStr, $filters);
And $filters
will have what you want. But that's not the case, so, one could do this:
parse_str(
str_replace(
array('%', '=', '&', '||', ':'),
array('%26', '%3D', '%26', '&', '='),
$filtersStr
),
$filters
);
The characters %
, =
and &
will have a special meaning. They have to be replaced with their URL-codes. parse_str()
works on URL-encoded strings and leaving those characters unchanged would cause all sorts of bugs. The order of the elements in the array is VERY important.
Here's how it works:
- Replace
%
by%26
It must be the first of you will be replacing%
everywhere and break it - Replace
=
by%3D
This guarantees that no meaningful=
will be replaced - Replace
&
by%26
- Replace
||
by&
- Replace
:
by=
At this point, your'id:1||name:alex'
will be'id=1&name=alex'
- Hand it over to
parse_str()
And done! I prefer the first method instead of this kludge. Use this second one with extreme care!
In a comment, it was explained that it's usage was like this:
/arena?filter=id:1||content_name:alex&anotherParam=smth
If you can change the URL, throw this whole code away and do like this:
/arena?filter[id]=1&filter[content_name]=alex&anotherParam=smth
This will have the exact structure you wish. Simply use $_GET['filter']
to access all values. And done! An alternative with 0 lines of code!
-
\$\begingroup\$ this have to be one parameter in url like /arena?filter=id:1||content_name:alex&anotherParam=smth \$\endgroup\$Alex Kneller– Alex Kneller2015年08月26日 09:28:19 +00:00Commented Aug 26, 2015 at 9:28
If you're writing the structure on string formatting, then I'd suggest considering JSON as a better alternative.
It's a better alternative than reinventing-the-wheel, because, its support is inbuilt into many languages, including PHP with the json_encode
and json_decode
functions.
Consider this:
$object = ['id' => 1,'name' => 'alex'];
$JSON = json_encode($object);
$DAL->do_whatever($JSON);
or:
$JSON = $DAL->retrieve_whatever();
$object = json_decode($JSON);
buildProfile($object);
Alternatives are good because we find the solution handy, which are well described by @Quill and @Ismael,
If you have decided to go with the current format of your string, here is the alternative i wrote,
foreach(explode('||', $filtersStr) as $val)
{
$filters[strtok($val, ':')] = trim(strstr($val, ':'), ':');
} unset($val);
Here strtok($val, ':')
will stop at first :
it encounters, in our case it will be id
and name
, so no :
will be in final array keys.
strtok($val, ':')
will get the whole string after first :
it encounters and trim
will clear suffixed :
s.
The benefit is that when it encounters values like,
$filtersStr = 'id:1||name:alex:mercer';
It outputs as is,
Array
(
[id] => 1
[name] => alex:mercer
)
Other results are same.