Question

A have a delete link which goes to another page, call a function, if the function is successful, then I sent the user back to the page where they clicked delete.

I use this to go back:

if ($booking->deleteBooking($_GET['id']))
{
    header('Location: ' . $_SERVER['HTTP_REFERER']);
}

My link would look something like this:

/calendar.php?id=1&month=04&day=25&year=2014&t=11&v=true&f=true&reserved=true

Can I trim the link and remove &reserved=true when it's sent back?

Était-ce utile?

La solution

Rather than performing string manipulations that could be prone to error, I suggest that you use PHP's URL functions to parse the HTTP_REFERER header and adjust it accordingly:

// parse the referrer
$referer = parse_url($_SERVER['HTTP_REFERER']);

// parse the querystring part
parse_str($referer['query'], $querystring);

// unset the reserved parameter (only if value is 'true'?)
if ($querystring['reserved'] === 'true') unset($querystring['reserved']);

// reconstruct the revised querystring
$referer['query'] = http_build_query($querystring);

// redirect to the adjusted URL
header('Location: ' . http_build_url($referer));

Autres conseils

I suggest you avoid regex and str_replace because they will quickly fall flat when your URL structure changes.

I would put this in a class now because this is not the last time you'll need to do this (I just had to do it last week) or some other URL related thing. So, you should go ahead and encapsulate the functionality in one place now rather than later. You can always change the implementation later in one place if you find a better or more correct way to handle the task.

A few fairly important caveats regarding your script and possible solutions...

HTTP_REFERER can't really be relied upon. Browsers are not required to send it and many do not. You can get around that by sending the URL yourself in the query string (properly escaped) or possibly via a hidden form field. Otherwise, your redirect and script is going to fail in a lot of cases! See HTTP Referer not always being passed

You should always exit after sending a Location header if you want an immediate redirect... otherwise your script will keep chugging along happily doing stuff. (database queries, etc, etc) To that end, I would encapsulate your redirect code as well and have done so in my example solution.

http_build_url is not available by default in PHP. It's a pecl_http thing. Ultimately, it's not really required in this case and my example solution works without it.


Example Class Usage:

$referrer = 'http://example.com/calendar.php?id=1&month=04&day=25&year=2014&t=11&v=true&f=true&reserved=true';

$url = new URL($referrer);

$url->remove_param('reserved');

$url->redirect();


Class Code:

class URL
{
    public $url = '';

    function __construct ($url)
    {
        $this->url = $url;
    }

    function redirect ($response_code = 301)
    {
        header('Location: ' . $this->url, true, $response_code);
        exit;
    }

    function remove_param ($param)
    {
        // Do nothing to URL without a Query String (hat tip @eggyal)
        if (strpos($this->url, '?') === false) return $this->url;

        // Split URL into base URL and Query String
        list($url, $query) = explode('?', $this->url, 2);

        // Parse Query String into array
        parse_str($query, $params);

        // Remove the parameter in question
        unset($params[$param]);

        // Rebuild Query String
        $query = http_build_query($params);

        // Piece URL back together and save to object
        $this->url = $url . ($query ? "?$query" : '');

        // Return URL in case developer really just wants an instant result
        return $this->url;
    }
} 

Caveat: This will not retain any URL fragments (ie #fragment) In the case of HTTP_REFERER this should not matter as most browsers won't send that anyway. If that is functionality you decide you need, then it can easily be coded in at a later time.

Namespacing: For simplicity's sake, the code examples are not namespaced. However, for real life implementations, I suggest getting in the habit of using "namespace App;" at the top of any in-house class files and calling the class as such "new App\Class();" Especially if you're using or might ever use any third-party code in your project.

Performance Note: Don't worry about performance until it becomes a problem... your time is always the biggest bottleneck... not PHP. Value your time more than PHP's time! PHP will always be faster than spending your time copy pasta coding. Encapsulate your code (in classes or functions) and have time left to go outside and enjoy the weather now and in the future when you need to re-factor.

use preg_replace

 preg_replace('/^&reserved=true/', '', $_SERVER['HTTP_REFERER']);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top