TIP: Use Markdown or, <pre> for multi line code blocks / <code> for inline code.
These forums are read-only and for archival purposes only!
Please join our new forums at discourse.kohanaframework.org
Kohana URI class
  • There was an idea to create a URI class for Kohana, with the ability to parse URI strings, modify its parts and render it to string implicitly. Possibly to even make some Kohana parts using it sometime in the future. See #3980 for details.

    I'm opening this discussion in attempt to involve more community members willing to contribute to the problem.

    Here's what I've come up with so far: https://github.com/czukowski/kohana-uri

    It's a module with a URI class, that has said functionality. It's not complete yet and hasn't been benchmarked yet.

    Simple usage:

    $uri = URI::factory('http://example.com/kohana/test.html')->set('port', '8080');
    echo $uri;
    // prints: 'http://example.com:8080/kohana/test.html'
    
    $uri->is_absolute();
    // returns TRUE
    
    echo $uri->to_relative();
    // prints: 'test.html' (assuming, Kohana::$base_url = '/kohana/' and Kohana::$index_file = FALSE)
    

    The same goes for getting/setting/erasing of any other part, such as 'scheme', 'user', 'pass', 'host', 'port', 'path', 'query' and 'fragment'.

    I'll post some things, that concern me at the moment:

    • Lines 32-37: Constructor accepts Route instance as a parameter to create URI from it. After some consideration, I think it should be removed. There shouldn't be any problem calling new URI($route->uri( ... )). (decided to get rid of it for now)
    • Lines 75, 104, 130 (the same thing for all 3): Should getter/setter/eraser methods care about correct usage, specifically, check if part names are valid and throw exception otherwise?
    • Line 189: URI parser uses Regex right now, but parse_url() might be a better choice. (parse_url() turned out unreliable)
    • Line 223: URI renderer is now quite a mess of string joins. It could be nicer to use http_build_url(), but it belongs to PECL, I'm not sure about its availability on hosting servers. It wasn't active on my localhost (XAMPP).
    • Line 225: I've built query string using http_build_query(), but it HTML-encodes & character. I think it's not a good idea, this kind of escaping is the job for a View. I've reverted that by str_replacing it back to &, but I don't like the look of it. (resolved)

    Any comments, ideas, patches, forks and spoons are appreciated.

  • I've built query string using http_build_query(), but it HTML-encodes & character

    You can control how & appears by using the 3rd parameter:

    arg_separator.output is used to separate arguments, unless this parameter is specified, and is then used.

    For example:

    $string = http_build_query($parts, NULL, '&');
    
  • @shadowhand

    Thanks, I was looking at that in the docs, but for some reason, assumed that was something else...

  • I've made a few changes to the class and added some parsing benchmarks.

    I wanted to compare regex performance to PHP parse_url() function. regex turned out to be about 10% slower, but parse_url() fails at the URI, that looks like this: /kohana/index.php/my/site/page:5' (got it from here), where it returns FALSE, so I guess, regex has to be the way to go here...

    Other thoughts:

    • The class might benefit from functions like to_absolute() and to_relative(), which would prepend and remove the Kohana::$base_path to the 'path' URI part. (done)
    • Implement clone() method for convenience. (named it copy() since clone() was not a valid method name)
  • You could identify relative urls and add a scheme and host before parsing the url.

    $relative = (bool)filter_var($uri,FILTER_VALIDATE_URL); 
    
    if($relative){ $uri = 'http://host.com'.$uri; }
    
    $parts = parse_url($uri);
    
    if($relative){ unset($parts['scheme'],$parts['host']); }
    
  • I've decided to dump parse_url() for the reasons posted above, so there's now only one URI::parse() method.

    I've also implemented to_absolute() and to_relative() methods. They currently just modify the current 'path' and not returning new URI object.

    There's also new is_absolute() method, that detects and caches the value and is_relative() (for completeness sake).

    Going to try to extend some Request methods to use this class and see if it's any good performance-wise. I guess there could be some potential using that in URL class methods, too.

  • @czukowski just to say I'm watching with interest. I plan to refactor a lot of Request, Response and URI in Kohana 3.3.

  • I've made Request::uri() and Request::url() methods to return new URI instances. The URL class could've been modified to be "URI-aware", but since you're planning to do a lot of refactoring, I'm a little hesitant to do that right now, as well as more deep integration with Request/Response.

    I've also modified some tests, that made use of the methods I've mentioned, so that they don't fail when they see URI instance instead of strings. While doing that, I've noticed, that most Requests created by tests don't inject sample routes, while assuming specific output, which made them fail in my testing application (that did not have the default route). I can understand, that the tests are probably supposed to run on a clean Kohana install, but since that wasn't much trouble, I've modified them to inject the default route to some requests, where it was relevant.

    Here's the link to the tests file: https://github.com/czukowski/kohana-uri/blob/38ef32341a6f132ec91b25129dbe5c14874eaa2f/tests/kohana/RequestTestURI.php

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion