Welcome Guest, Not a member yet? Register   Sign In
URI class doesn’t recognize #anchors

The URI class doesn't properly recognize/handle anchors in URIs in certain situations.

Here's an illustration using a custom route from an old address, mission.html, to an anchor in CI-powered page, /page/info#mission.

$route['mission.html'] = 'page/info#mission';

Here's the URI::ruri_string() function:

function ruri_string()
    return '/'.implode('/', $this->rsegment_array()).'/';

The ruri_string() function will return "/page/info#mission/", corrupting the anchor reference. Looking at the internal URI::$rsegments array, shows segment 2 being "info#mission".

(One workaround is to precede the hash by a slash, page/info/#mission, but then segment 3 would become "#mission", which is technically incorrect.)

I propose that the URI class parse out the anchor reference to a separate variable, and reapply it as needed. Discussion?

In my investigation so far, I've narrowed this issue down to Line 260 of the Router::_parse_routes() function:

$this->_set_request(explode('/', $this->routes[$uri]));

This line executes when there's a literal match to a custom route. It assumes the custom route only contains segments, and ignores the possible existence of anchors.

My current solution involves intercepting the call to Router::_set_request() with the following:

function _set_request($segments = array()) {
    if ($seg = array_pop($segments)) {
        $i = strpos($seg, '#');
        if ($i !== FALSE) {
            list($seg, $this->uri->anchor) = explode('#', $seg);
        if ($seg) {
            $segments[] = $seg;
    return parent::_set_request($segments);

Basically, it checks to see if "#" exists in the last segment, extracts the anchor name into $this->uri->anchor, restores the last segment without the anchor, and then passes control on to the stock _set_request() function to continue processing.

The code gracefully handles routes with and without a trailing slash:

The URI class would need to be adjusted to utilize the $this->uri->anchor property.

Theme © iAndrew 2016 - Forum software by © MyBB