URI.js
URI.js copied to clipboard
.query() Array-Parameters won't fill PHP's $_GET as intended
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'
)
);
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.
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.
..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 ♥
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 :)
Here's a first shot at URI.hooks. Just checkout the php-querystring branch and give it a go.
You never got back to me with any feedback regarding the implementation. Have you had the chance to test this?
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.
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.