Skip to content

.query() Array-Parameters won't fill PHP's $_GET as intended #28

Open
Abromeit opened this Issue Jun 8, 2012 · 8 comments

3 participants

@Abromeit
Abromeit commented Jun 8, 2012

Current Version

This Code:

.query({ foo: "bar", hello: ["world", "mars"] });

Leads to this:

// -> http://example.com/bar/foo.xml?foo=bar&hello=world&hello=mars

I think that's kinda senseless. Cause this is what we see on the Server-Side:

$_GET = array(
  'foo' => 'bar',
  'hello' => 'mars'
);

I.e. "hello=world" is missing and no one can work with it.

Improved Version

Better:

// -> http://example.com/bar/foo.xml?foo=bar&hello[]=world&hello[]=mars

Results in this:

$_GET = array(
  'foo' => 'bar',
  'hello' => array(
    0 => 'world',
    1 => 'mars'
  )
);
@rodneyrehm
Medialize member

The docs contain some demo code. The last lines are

// CAUTION: beware of arrays, the following are not quite the same
// If you're dealing with PHP, you probably want the latter…
uri.search("?foo=bar&bar=baz");
uri.search("?foo=bar[]&bar[]=baz");

you get that through

uri.search({ foo: "bar", "hello[]" : ["world", "mars"] });

I cannot make URI.js inject those [] for you, as PHP is one of the few languages using this scheme. most other languages deal with this quite differently.

@rodneyrehm
Medialize member

That said, we could look into an optional "serialization callback" for query strings. Something that could convert {foo: ['bar', 'baz']} to foo[]=bar&foo[]=baz. Maybe even allow it to accept objects like {foo: {bar: 1, baz: 2}} and turn it into foo[bar]=1&foo[baz]=2.

@Abromeit
Abromeit commented Jun 8, 2012

..which would be cool if we talk about a ..hm.. 'static' callback, that users have to provide only once, if they like to.

Just to let you know - I really love what you did there. Your project could reduce my node.js codebase by at least 15% or so. I'm not that bad with Regex, but there's a lot of messy stuff out there and URL-canonicalization etc. is a pain when you have to do all that stuff over and over again. Thank you so much ♥

@rodneyrehm
Medialize member

I'll look into the callbacks. It'll take me a couple of days though… heavy work load :(

To make things worse: we would also have to consider a callback for parseQuery() - something that is able to reverse whatever we plugged into buildQuery().

Thanks, for the kind words. I'm happy you like it :)

@rodneyrehm
Medialize member

Here's a first shot at URI.hooks. Just checkout the php-querystring branch and give it a go.

@rodneyrehm
Medialize member

You never got back to me with any feedback regarding the implementation. Have you had the chance to test this?

@rodneyrehm rodneyrehm added this to the v2.0.0 milestone Mar 11, 2015
@alex94puchades

Mapping from javascript-like objects to url parameters is a solved problem. It's not only PHP who relies on it (see this). Please, could you consider making use of qs for building the query string? It is standard, well-tested (used by express),... If that's not an option, you could borrow its query parsing code.

If anything else, at least provide a sane behaviour (and I'd go for the more standard-widespread one) for URI(...).query({ foo: { bar: 'whatever' }}) . Currently, it gives "?foo=%5Bobject+Object%5D", which is no good.

@rodneyrehm
Medialize member

We will find a solution that works for everyone in URI.js v2. Until then you're stuck working with qs yourself. Alternatively you can make URI.js use qs by overwriting the following functions:

var qs = require('qs');
URI.parseQuery = function(string) { return qs.parse(string); };
URI.buildQuery = function(data) { return qs.stringify(data); };

Simply popping qs into URI.js will make 39 tests fail, but most of those seem to be standard behavior that you don't want anyway, considering you explicitly asked for qs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.