Welcome Guest, Not a member yet? Register   Sign In
redirect() not passing last / (trailing slash)
#1

[eluser]wapatv[/eluser]
Hi!

I'm doing some tests with the redirect() function and noticed that it does not passes the last slash (/) in the URL.

Example:
Code:
function test() {
        redirect('/pagex/sectiony/');
    }

that will redirect to: /pagex/sectiony
without the last /

Is there a way that the redirect always redirect the same way I need it to?
#2

[eluser]wapatv[/eluser]
I just this this test:

Code:
function test() {
        redirect('/pagex/sectiony\/');
    }
Notice the \ before the last /

And that way it did redirect with the last /
/pagex/sectiony/

But is that a reliable/secure way to accomplish it?
#3

[eluser]pickupman[/eluser]
Slash or no slash the uri is still the same.
#4

[eluser]wapatv[/eluser]
Thanks pickupman,

Yes, I am aware of that. The reason I want it with the last slash is for Analytics uniformity.
Google Analytics, treads different these URLs:
/pagex/sectiony
/pagex/sectiony/

although they're the same uri. that's the reason for wanting the last slash... so I can track the same URL in Analytics, without having duplicated URLs.
#5

[eluser]pickupman[/eluser]
Ah, I see your point then. This is caused by the trim() on line 229 in system/core/Config.php. The redirect() function calls site_url() which is in system/core/Config.php. You will need to create your helpers for this to change the default behavior of both functions.

/application/helpers/MY_url_helper.php
Code:
/**
* Header Redirect
*
* Header redirect in two flavors
* For very fine grained control over headers, you could use the Output
* Library's set_header() function.
*
* @access    public
* @param    string    the URL
* @param    string    the method: location or redirect
* @param       bool    TRUE to strip trailing slash
* @return    string
*/
if ( ! function_exists('redirect'))
{
    function redirect($uri = '', $method = 'location', $http_response_code = 302, $strip = TRUE)
    {
        if ( ! preg_match('#^https?://#i', $uri))
        {
            $uri = site_url($uri, $strip);
        }

        switch($method)
        {
            case 'refresh'    : header("Refresh:0;url=".$uri);
                break;
            default            : header("Location: ".$uri, TRUE, $http_response_code);
                break;
        }
        exit;
    }
}
// ------------------------------------------------------------------------

/**
* Site URL
*
* Create a local URL based on your basepath. Segments can be passed via the
* first parameter either as a string or an array.
*
* @access    public
* @param    string
* @param       bool TRUE to strip trailing slash
* @return    string
*/
if ( ! function_exists('site_url'))
{
    function site_url($uri = '', $strip = TRUE)
    {
        $CI =& get_instance();
        return $CI->config->site_url($uri, $strip);
    }
}

// ------------------------------------------------------------------------

/application/core/MY_Config.php
Code:
/**
     * Site URL
     *
     * @access    public
     * @param    string    the URI string
         * @param       bool  TRUE to strip trailing slash
     * @return    string
     */
    function site_url($uri = '', $strip = TRUE)
    {
        if ($uri == '')
        {
            if ($this->item('base_url') == '')
            {
                return $this->item('index_page');
            }
            else
            {
                return $this->slash_item('base_url').$this->item('index_page');
            }
        }

        if ($this->item('enable_query_strings') == FALSE)
        {
            if (is_array($uri))
            {
                $uri = implode('/', $uri);
            }

            $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');
            return $this->slash_item('base_url').$this->slash_item('index_page').(($strip) ? trim($uri, '/') : '').$suffix;
        }
        else
        {
            if (is_array($uri))
            {
                $i = 0;
                $str = '';
                foreach ($uri as $key => $val)
                {
                    $prefix = ($i == 0) ? '' : '&';
                    $str .= $prefix.$key.'='.$val;
                    $i++;
                }

                $uri = $str;
            }

            if ($this->item('base_url') == '')
            {
                return $this->item('index_page').'?'.$uri;
            }
            else
            {
                return $this->slash_item('base_url').$this->item('index_page').'?'.$uri;
            }
        }
    }

    // --------------------------------------------------------------------
#6

[eluser]pickupman[/eluser]
Then you would need write:
[code]
redirect('/pagex/sectiony/', 'location', '302', FALSE);
[code]

Seems like using the extra slash without all the extra code may make more sense to me.
#7

[eluser]Nicolas Santos[/eluser]
hi all,

To avoid duplicates i use a hook to redirect uris with final / to URI without.

my hook declaration
Code:
$hook['pre_controller'] = array(
    'class' => 'My_class',
    'function' => 'redirect_trailing_slash',
    'filename' => 'my_lib_file.php',
    'filepath' => 'libraries',
    'params' => array()
);

my redirect code
Code:
function redirect_trailing_slash() {
        $uri = $_SERVER['REQUEST_URI'];
        // 1st condition is important not to redirect the home page
        if (strlen($uri) > 1 && substr($uri, -1, 1) == "/") {
            header("location: " . substr($uri, 0, -1), TRUE, 301);
            exit;
        }
        return;
    }
#8

[eluser]wapatv[/eluser]
Thanks pickupman and Nicolas,

What I end up doing was the following.

I have a auto-loaded library (ie: myautolib), so I decided to add a similar function like the redirect() core function, minus the site_url() function that does the trim to my auto-loaded library (ie: myautolib.php).

/libraries/myautolib.php
Code:
function redirect_uri($uri = '', $method = 'location', $http_response_code = 302) {

        switch ($method) {
            case 'refresh' : header("Refresh:0;url=" . $uri);
                break;
            default : header("Location: " . $uri, TRUE, $http_response_code);
                break;
        }
        exit;
    }

Then all I need to do is call it like this in my controller:
Code:
$this->myautolib->redirect_uri('/pagex/sectiony/');
#9

[eluser]Nicolas Santos[/eluser]
hello,

And why dont you create in your /application/helpers/ folder a MY_url_helper with a redirect function ? this way you can still use redirect().
#10

[eluser]wapatv[/eluser]
[quote author="Nicolas Santos" date="1301398488"]And why dont you create in your /application/helpers/ folder a MY_url_helper with a redirect function ? this way you can still use redirect().[/quote]
To tell you the truth, I've never used the helpers to overwrite a CI core function. Does doing that have any effect on performance or any other drawbacks?

Other than using the same redirect() function name, what benefits have using the helper to overwrite the core function, versus creating a custom function in an auto-loaded library?

Thanks




Theme © iAndrew 2016 - Forum software by © MyBB