HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

String to Array formatting

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
arrayformattingstring

Problem

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.

Solution

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!

Code Snippets

$filtersStr = 'id=1&name=alex';

parse_str($filtersStr, $filters);
parse_str(
    str_replace(
        array('%', '=', '&', '||', ':'),
        array('%26', '%3D', '%26', '&', '='),
        $filtersStr
    ),
    $filters
);
/arena?filter=id:1||content_name:alex&anotherParam=smth
/arena?filter[id]=1&filter[content_name]=alex&anotherParam=smth

Context

StackExchange Code Review Q#101944, answer score: 3

Revisions (0)

No revisions yet.