Is it safe to turn urls into links? - php

I want to turn urls in the user comments, into links.
I don't have time to test bloated anti-xss libraries like HTML Purify, so I wouldn't be allowing any html tags.
I just want to make everything go through htmlentities() and nl2br(), and then use preg_replace() to find urls and turn them into links ('a' html tags).
Is it unsafe to grab the urls I find and put them inside href='' ?
If not, what can I do about it?

Yes, it should be safe. If you wonder how, here is a function I use for this (I simplified it for the purpose of this post):
function formatPost($string) {
return nl2br(
preg_replace_callback(
'~https?://([^/\s]+)(?:/((?>[/\w]+|\S(?!\s|$))*))?~',
function($matches) {
$url = $matches[0];
$host = $matches[1];
$path = isset($matches[2]) ? $matches[2] : '';
$follow = false;
if ('' == $path) {
$text = $host;
} elseif ($_SERVER['HTTP_HOST'] == $host) {
$text = $path;
$follow = true;
} else {
$text = $host . '/' . $path;
}
return '<a href="' . $url . '"' . (!$follow ? ' rel="nofollow"' : '') . '>' . $text . '</a>';
},
htmlspecialchars($string)
)
);
}

Related

PHP dynamic breadcrumb script creates wrong URL after switching to PHP 8.0

I'm using a PHP script to create a dynamic breadcrumb navigation. I found it several years ago in another forum where it was originally posted in 2006. I updated it by removing some deprecated functions and it worked well so far. It creates the crumbs from the page URL:
$path = $this->_homepath;
$html ='';
$html .= 'Start';
$parts = explode('/', $_SERVER['PHP_SELF']);
$partscount = count($parts);
for($i = 1; $i < ($partscount - 1); $i++) {
$path .= $parts[$i] . '/';
$title = $parts[$i];
if ($this->_usereplacements == true) {
reset($this->_replacements);
foreach($this->_replacements as $search => $replace) {
$title = str_replace($search, $replace, $title);
}
}
if ($this->_replaceunderlines == true) {
$title = str_replace('_', ' ', $title);
}
if ($this->_ucfirst == true) {
$title = ucfirst($title);
}
if ($this->_ucwords == true) {
$title = ucwords($title);
}
$html .= $this->_separator . '' . $title . '';
}
The current page title, i.e. the last element of the bradcrumb, is generated as follows:
$title = '';
if ($title == '') {
$title = $parts[$partscount-1];
if ($this->_usereplacements == true) {
reset($this->_replacements);
foreach($this->_replacements as $search => $replace) {
$title = str_replace($search, $replace, $title);
}
}
if ($this->_removeextension == true) {
$title = substr($title, 0, strrpos($title, '.'));
}
if ($this->_replaceunderlines == true) {
$title = str_replace('_', ' ', $title);
}
if ($this->_ucfirst == true) {
$title = ucfirst($title);
}
if ($this->_ucwords == true) {
$title = ucwords($title);
}
}
$html .= $this->_separator . '<b>' . $title . '</b>';
I only copied relevant parts of the script and spared eg. the function declarations.
After switching from PHP 7.4 to 8.0 I found that the script is messing up a bit. Consider a page with this url: https://www.myhomepage.com/site1/site2/site3
For the crumbs of site1 the script is now generating the URL https://www.myhomepage.com/site1/site2/site1 insted of https://www.myhomepage.com/site1/, whereas for site2 it shows https://www.myhomepage.com/site1/site2/site1/site2 instead of https://www.myhomepage.com/site1/site2/. As you can see, the whole path https://www.myhomepage.com/site1/site2/ is always added as a prefix before the actual path of the crumb.
I haven't found a solution yet despite looking over this thing for two days. I suppose there have been some changes in PHP 8.0 which causes this behaviour, but I haven't found any clues in the incompatibility list (https://www.php.net/manual/de/migration80.php). I printed §path and $title and they look like they should. When echoing $html after each iteration in the for loop it shows already the wrong URLs. That's why I think that probably the for loop is the problem here. Do you have any suggestions?
Any help on this would be very much appreciated.
I finally was able to figure out what causes the strange behaviour of the script. In the declaration of the breadcrumb constructing function there is $this->_homepath = '/';. Later on I assign $path = $this->_homepath;. When I echo $path its empty instead of showing the aforementioned "/". So I directly set $path = '/'; and now everything works again as it should.

Regex for add GET param to URL

I want to add GET parameter to all URLs in special string (like html content of a website) .
For example :
Before:
$content = '... register ... login ...';
After:
$content = '... register ... login ...';
I think that this is only done with a regular expression , for this reason I wrote this function :
function makeLinks($str)
{
$str = preg_replace('#((https?://)?([-\w]+\.[-\w\.]+)+\w(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)*)#', '$1?wid=${wid}', $str);
return $str;
}
But this pattern having problems! for example :
http://google.com?foo=bar => http://google.com?wid=${wid}?foo=bar
Please help me.
Try This:
function makeLinks($str)
{
$str = preg_replace_callback('/\b((?:https?|ftp):\/\/(?:[-A-Z0-9.]+)(?:\/[-A-Z0-9+&##\/%=~_|!:,.;]*)?)(?:\?([A-Z0-9+&##\/%=~_|!:,.;]*))?/i', 'modify_url', $str);
return $str;
}
function modify_url($matches) {
$query = isset($matches[2]) ? $matches[2]:'';
$result = $matches[1].'?'.$query;
if(!empty($query)) $result .= '&';
return $result.'wid=${wid}';
}
Optionally you can just add # without affecting the ending result. I hate to use them, but here it is in case you want to use them:
function modify_url($matches) {
$result = $matches[1].'?'.#$matches[2];
if(!#empty($matches[2])) $result .= '&';
return $result.'wid=${wid}';
}
Idealy, you should extract the urls and parse them, but this solution should work.
I think there may be a short way. My solution :
function makeLinks($str) {
preg_match_all('|(https?:\/\/(www\.)?[-a-zA-Z0-9#:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9#:%_\+.~#?&//=]*))|', $str, $urls);
if ($urls && isset($urls[1])) {
foreach ($urls[1] as $url) {
$new_url = $url . (strpos($url, '?') ? '&' : '?') . 'wid=${wid}';
$str = str_replace($url, $new_url, $str);
}
}
return $str;
}

How to get rid of `?` in URL when no parameters exist?

I have the following rule which checks if the url contains any parameters that start with p2:
function unparse_url($parsed_url) {
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
$user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
$pass = ($user || $pass) ? "$pass#" : '';
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
$query = isset($parsed_url['query']) ? '?' . trim($parsed_url['query'], '&') : '';
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
return "$scheme$user$pass$host$port$path$query$fragment";
}
function strip_query($url, $query_to_strip) {
$parsed = parse_url($url);
$parsed['query'] = preg_replace('/(^|&)'.$query_to_strip.'[^&]*/', '', $parsed['query']);
return unparse_url($parsed);
}
$url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$new_url = (strip_query($url, 'p2'));
# redirect if url contains anything that starts with p2
$filtered = array_filter(array_keys($_GET), function($k) {
return strpos($k, 'p2') === 0;
});
if ( !empty($filtered) ) {
header ("Location: $new_url");
}
else {
}
If a url contain any p2* parameters, a redirect will be made to the same page without these parameters.
Example:
domain.com/?a=3&p2=1
will redirect to
domain.com/?a=3
However, with the current rule, if the original URL is:
domain.com/?p2=1
Then it will redirect to:
domain.com/?
But since it is meaningless, I want that in this case it will redirect to:
domain.com/
How can it be done?
Like #dontfight i would suggest to use mod_rewrite but if you prefer PHP you could use rtrim before you do the redirect
rtrim($url, '?');
With your code you could use like this
$filtered = array_filter(array_keys($_GET), function($k) {
return strpos($k, 'p2') === 0;
});
$new_url_trim = rtrim($new_url, '?');
if ( !empty($filtered) ) {
header ("Location: $new_url_trim");
}
else {
}
Here's another way to remove query parameters:
Parse the URL to separate it into the scheme, path, and query
Parse the query string into an array
Unset the parameter within the array
Recreate the URL
Example:
<?php
function removeQuery($url, $param) {
$parsed = parse_url($url);
parse_str($parsed['query'], $query);
unset($query[$param]);
$parsed['scheme'] .= '://';
$parsed['query'] = http_build_query($query);
if (!empty($parsed['query']))
$parsed['path'] .= '?';
return implode($parsed);
}
echo removeQuery('http://domain.com/?a=3&p2=1', 'a') . "\n";
echo removeQuery('http://domain.com/?a=3&p2=1', 'p2') . "\n";
echo removeQuery('http://domain.com/?p2=1', 'p2');
Output:
http://domain.com/?p2=1
http://domain.com/?a=3
http://domain.com/
Also I noticed that you wanted to remove p2 if it occurs anywhere in the string, so here's another version designed to do just that:
<?php
function removeP2($url) {
$parsed = parse_url($url);
parse_str($parsed['query'], $query);
foreach ($query as $key => $value)
if (strpos($key, 'p2') === 0)
unset($query[$key]);
$parsed['scheme'] .= '://';
$parsed['query'] = http_build_query($query);
if (!empty($parsed['query']))
$parsed['path'] .= '?';
return implode($parsed);
}
echo removeP2('http://domain.com/?a=3&p2=1') . "\n";
echo removeP2('http://domain.com/?a=3&p2sks=1') . "\n";
echo removeP2('http://domain.com/?p2=1');
Output:
http://domain.com/?a=3
http://domain.com/?a=3
http://domain.com/
Now to get it to redirect, you already know how to redirect:
header("Location: " . removeP2('http://' . $_SERVER[HTTP_HOST] . $_SERVER[REQUEST_URI]));
Since nobody has bothered to tell you what's wrong...
Your problem is that your strip_query() function always sets $url["query"] to a value, even if that value is an empty string:
$parsed['query'] = preg_replace('/(^|&)'.$query_to_strip.'[^&]*/', '', $parsed['query']);
When your unparse_url() function gets the URL, it's checking that array index using isset() which always passes:
$query = isset($parsed_url['query']) ? '?' . trim($parsed_url['query'], '&') : '';
Instead of checking with isset() you could use empty(), which will return false if the value is unset or if it's an empty string:
$query = !empty($parsed_url['query']) ? '?' . trim($parsed_url['query'], '&') : '';
if mod_rewrite is available, this can be done without php code.
This is not an answer, its a comment, but its a bit long.
Why are you so keen to strip this variable from the URL? What harm has it ever done to you that you must go to such lengths to eradicate its existence? And why not just...
unset($_GET['p2']);
But since it is meaningless,
In what way?
I can see some merit in the unparse_url($parsed_url) function and if you fix the bugs (hint: try some test cases with usernames and/or passwords) then it's reasonably well structured - but the subsequent code for manipulating the data is a messy mix of regular expression string splicing - which is not the right way to deal with such structured data - PHP has functions for that.
But the worst bit is then injecting another complete RTT to resolve the URL.
You are better than this rockyraw!

How to remove path after domain name from string

I have the following code :
function removeFilename($url)
{
$file_info = pathinfo($url);
return isset($file_info['extension'])
? str_replace($file_info['filename'] . "." . $file_info['extension'], "", $url)
: $url;
}
$url1 = "http://website.com/folder/filename.php";
$url2 = "http://website.com/folder/";
$url3 = "http://website.com/";
echo removeFilename($url1); //outputs http://website.com/folder/
echo removeFilename($url2);//outputs http://website.com/folder/
echo removeFilename($url3);//outputs http:///
Now my problem is that when there is only only a domain without folders or filenames my function removes website.com too.
My idea is there is any way on php to tell my function to do the work only after third slash or any other solutions you think useful.
UPDATED : ( working and tested )
<?php
function removeFilename($url)
{
$parse_file = parse_url($url);
$file_info = pathinfo($parse_file['path']);
return isset($file_info['extension'])
? str_replace($file_info['filename'] . "." . $file_info['extension'], "", $url)
: $url;
}
$url1 = "http://website.com/folder/filename.com";
$url2 = "http://website.org/folder/";
$url3 = "http://website.com/";
echo removeFilename($url1); echo '<br/>';
echo removeFilename($url2); echo '<br/>';
echo removeFilename($url3);
?>
Output:
http://website.com/folder/
http://website.org/folder/
http://website.com/
Sounds like you are wanting to replace a substring and not the whole thing. This function might help you:
http://php.net/manual/en/function.substr-replace.php
Since filename is at last slash you can use substr and str_replace to remove file name from path.
$PATH = "http://website.com/folder/filename.php";
$file = substr( strrchr( $PATH, "/" ), 1) ;
echo $dir = str_replace( $file, '', $PATH ) ;
OUTPUT
http://website.com/folder/
pathinfo cant recognize only domain and file name. But if without filename url is ended by slash
$a = array(
"http://website.com/folder/filename.php",
"http://website.com/folder/",
"http://website.com",
);
foreach ($a as $item) {
$item = explode('/', $item);
if (count($item) > 3)
$item[count($item)-1] ='';;
echo implode('/', $item) . "\n";
}
result
http://website.com/folder/
http://website.com/folder/
http://website.com
Close to the answer of splash58
function getPath($url) {
$item = explode('/', $url);
if (count($item) > 3) {
if (strpos($item[count($item) - 1], ".") === false) {
return $url;
}
$item[count($item)-1] ='';
return implode('/', $item);
}
return $url;
}

Strip off specific parameter from URL's querystring

I have some links in a Powerpoint presentation, and for some reason, when those links get clicked, it adds a return parameter to the URL. Well, that return parameter is causing my Joomla site's MVC pattern to get bungled.
What's an efficient way to strip off this return parameter using PHP?
Example:
http://mydomain.example/index.php?id=115&Itemid=283&return=aHR0cDovL2NvbW11bml0
The safest "correct" method would be:
Parse the url into an array with parse_url()
Extract the query portion, decompose that into an array using parse_str()
Delete the query parameters you want by unset() them from the array
Rebuild the original url using http_build_query()
Quick and dirty is to use a string search/replace and/or regex to kill off the value.
In a different thread Justin suggests that the fastest way is to use strtok()
$url = strtok($url, '?');
See his full answer with speed tests as well here: https://stackoverflow.com/a/1251650/452515
This is to complement Marc B's answer with an example, while it may look quite long, it's a safe way to remove a parameter. In this example we remove page_number
<?php
$x = 'http://url.example/search/?location=london&page_number=1';
$parsed = parse_url($x);
$query = $parsed['query'];
parse_str($query, $params);
unset($params['page_number']);
$string = http_build_query($params);
var_dump($string);
function removeParam($url, $param) {
$url = preg_replace('/(&|\?)'.preg_quote($param).'=[^&]*$/', '', $url);
$url = preg_replace('/(&|\?)'.preg_quote($param).'=[^&]*&/', '$1', $url);
return $url;
}
parse_str($queryString, $vars);
unset($vars['return']);
$queryString = http_build_query($vars);
parse_str parses a query string, http_build_query creates a query string.
Procedural Implementation of Marc B's Answer after refining Sergey Telshevsky's Answer.
function strip_param_from_url($url, $param)
{
$base_url = strtok($url, '?'); // Get the base URL
$parsed_url = parse_url($url); // Parse it
// Add missing {
if(array_key_exists('query',$parsed_url)) { // Only execute if there are parameters
$query = $parsed_url['query']; // Get the query string
parse_str($query, $parameters); // Convert Parameters into array
unset($parameters[$param]); // Delete the one you want
$new_query = http_build_query($parameters); // Rebuilt query string
$url =$base_url.'?'.$new_query; // Finally URL is ready
}
return $url;
}
// Usage
echo strip_param_from_url( 'http://url.example/search/?location=london&page_number=1', 'location' )
You could do a preg_replace like:
$new_url = preg_replace('/&?return=[^&]*/', '', $old_url);
Here is the actual code for what's described above as the "the safest 'correct' method"...
function reduce_query($uri = '') {
$kill_params = array('gclid');
$uri_array = parse_url($uri);
if (isset($uri_array['query'])) {
// Do the chopping.
$params = array();
foreach (explode('&', $uri_array['query']) as $param) {
$item = explode('=', $param);
if (!in_array($item[0], $kill_params)) {
$params[$item[0]] = isset($item[1]) ? $item[1] : '';
}
}
// Sort the parameter array to maximize cache hits.
ksort($params);
// Build new URL (no hosts, domains, or fragments involved).
$new_uri = '';
if ($uri_array['path']) {
$new_uri = $uri_array['path'];
}
if (count($params) > 0) {
// Wish there was a more elegant option.
$new_uri .= '?' . urldecode(http_build_query($params));
}
return $new_uri;
}
return $uri;
}
$_SERVER['REQUEST_URI'] = reduce_query($_SERVER['REQUEST_URI']);
However, since this will likely exist prior to the bootstrap of your application, you should probably put it into an anonymous function. Like this...
call_user_func(function($uri) {
$kill_params = array('gclid');
$uri_array = parse_url($uri);
if (isset($uri_array['query'])) {
// Do the chopping.
$params = array();
foreach (explode('&', $uri_array['query']) as $param) {
$item = explode('=', $param);
if (!in_array($item[0], $kill_params)) {
$params[$item[0]] = isset($item[1]) ? $item[1] : '';
}
}
// Sort the parameter array to maximize cache hits.
ksort($params);
// Build new URL (no hosts, domains, or fragments involved).
$new_uri = '';
if ($uri_array['path']) {
$new_uri = $uri_array['path'];
}
if (count($params) > 0) {
// Wish there was a more elegant option.
$new_uri .= '?' . urldecode(http_build_query($params));
}
// Update server variable.
$_SERVER['REQUEST_URI'] = $new_uri;
}
}, $_SERVER['REQUEST_URI']);
NOTE: Updated with urldecode() to avoid double encoding via http_build_query() function.
NOTE: Updated with ksort() to allow params with no value without an error.
This one of many ways, not tested, but should work.
$link = 'http://mydomain.example/index.php?id=115&Itemid=283&return=aHR0cDovL2NvbW11bml0';
$linkParts = explode('&return=', $link);
$link = $linkParts[0];
Wow, there are a lot of examples here. I am providing one that does some error handling. It rebuilds and returns the entire URL with the query-string-param-to-be-removed, removed. It also provides a bonus function that builds the current URL on the fly. Tested, works!
Credit to Mark B for the steps. This is a complete solution to tpow's "strip off this return parameter" original question -- might be handy for beginners, trying to avoid PHP gotchas. :-)
<?php
function currenturl_without_queryparam( $queryparamkey ) {
$current_url = current_url();
$parsed_url = parse_url( $current_url );
if( array_key_exists( 'query', $parsed_url )) {
$query_portion = $parsed_url['query'];
} else {
return $current_url;
}
parse_str( $query_portion, $query_array );
if( array_key_exists( $queryparamkey , $query_array ) ) {
unset( $query_array[$queryparamkey] );
$q = ( count( $query_array ) === 0 ) ? '' : '?';
return $parsed_url['scheme'] . '://' . $parsed_url['host'] . $parsed_url['path'] . $q . http_build_query( $query_array );
} else {
return $current_url;
}
}
function current_url() {
$current_url = 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
return $current_url;
}
echo currenturl_without_queryparam( 'key' );
?>
$var = preg_replace( "/return=[^&]+/", "", $var );
$var = preg_replace( "/&{2,}/", "&", $var );
Second line will just replace && to &
very simple
$link = "http://example.com/index.php?id=115&Itemid=283&return=aHR0cDovL2NvbW11bml0"
echo substr($link, 0, strpos($link, "return") - 1);
//output : http://example.com/index.php?id=115&Itemid=283
#MarcB mentioned that it is dirty to use regex to remove an url parameter. And yes it is, because it's not as easy as it looks:
$urls = array(
'example.com/?foo=bar',
'example.com/?bar=foo&foo=bar',
'example.com/?foo=bar&bar=foo',
);
echo 'Original' . PHP_EOL;
foreach ($urls as $url) {
echo $url . PHP_EOL;
}
echo PHP_EOL . '#AaronHathaway' . PHP_EOL;
foreach ($urls as $url) {
echo preg_replace('#&?foo=[^&]*#', null, $url) . PHP_EOL;
}
echo PHP_EOL . '#SergeS' . PHP_EOL;
foreach ($urls as $url) {
echo preg_replace( "/&{2,}/", "&", preg_replace( "/foo=[^&]+/", "", $url)) . PHP_EOL;
}
echo PHP_EOL . '#Justin' . PHP_EOL;
foreach ($urls as $url) {
echo preg_replace('/([?&])foo=[^&]+(&|$)/', '$1', $url) . PHP_EOL;
}
echo PHP_EOL . '#kraftb' . PHP_EOL;
foreach ($urls as $url) {
echo preg_replace('/(&|\?)foo=[^&]*&/', '$1', preg_replace('/(&|\?)foo=[^&]*$/', '', $url)) . PHP_EOL;
}
echo PHP_EOL . 'My version' . PHP_EOL;
foreach ($urls as $url) {
echo str_replace('/&', '/?', preg_replace('#[&?]foo=[^&]*#', null, $url)) . PHP_EOL;
}
returns:
Original
example.com/?foo=bar
example.com/?bar=foo&foo=bar
example.com/?foo=bar&bar=foo
#AaronHathaway
example.com/?
example.com/?bar=foo
example.com/?&bar=foo
#SergeS
example.com/?
example.com/?bar=foo&
example.com/?&bar=foo
#Justin
example.com/?
example.com/?bar=foo&
example.com/?bar=foo
#kraftb
example.com/
example.com/?bar=foo
example.com/?bar=foo
My version
example.com/
example.com/?bar=foo
example.com/?bar=foo
As you can see only #kraftb posted a correct answer using regex and my version is a little bit smaller.
Remove Get Parameters From Current Page
<?php
$url_dir=$_SERVER['REQUEST_URI'];
$url_dir_no_get_param= explode("?",$url_dir)[0];
echo $_SERVER['HTTP_HOST'].$url_dir_no_get_param;
This should do it:
public function removeQueryParam(string $url, string $param): string
{
$parsedUrl = parse_url($url);
if (isset($parsedUrl[$param])) {
$baseUrl = strtok($url, '?');
parse_str(parse_url($url)['query'], $query);
unset($query[$param]);
return sprintf('%s?%s',
$baseUrl,
http_build_query($query)
);
}
return $url;
}
Simple solution that will work for every url
With this solution $url format or parameter position doesn't matter, as an example I added another parameter and anchor at the end of $url:
https://example.com/index.php?id=115&Itemid=283&return=aHR0cDovL2NvbW11bml0&bonus=test#test2
Here is the simple solution:
$url = 'https://example.com/index.php?id=115&Itemid=283&return=aHR0cDovL2NvbW11bml0&bonus=test#test2';
$url_query_stirng = parse_url($url, PHP_URL_QUERY);
parse_str( $url_query_stirng, $url_parsed_query );
unset($url_parsed_query['return']);
$url = str_replace( $url_query_stirng, http_build_query( $url_parsed_query ), $url );
echo $url;
Final result for $url string is:
https://example.com/index.php?id=115&Itemid=283&bonus=test#test2
Some of the examples posted are so extensive. This is what I use on my projects.
function removeQueryParameter($url, $param){
list($baseUrl, $urlQuery) = explode('?', $url, 2);
parse_str($urlQuery, $urlQueryArr);
unset($urlQueryArr[$param]);
if(count($urlQueryArr))
return $baseUrl.'?'.http_build_query($urlQueryArr);
else
return $baseUrl;
}
function remove_attribute($url,$attribute)
{
$url=explode('?',$url);
$new_parameters=false;
if(isset($url[1]))
{
$params=explode('&',$url[1]);
$new_parameters=ra($params,$attribute);
}
$construct_parameters=($new_parameters && $new_parameters!='' ) ? ('?'.$new_parameters):'';
return $new_url=$url[0].$construct_parameters;
}
function ra($params,$attr)
{ $attr=$attr.'=';
$new_params=array();
for($i=0;$i<count($params);$i++)
{
$pos=strpos($params[$i],$attr);
if($pos===false)
$new_params[]=$params[$i];
}
if(count($new_params)>0)
return implode('&',$new_params);
else
return false;
}
//just copy the above code and just call this function like this to get new url without particular parameter
echo remove_attribute($url,'delete_params'); // gives new url without that parameter
I know this is an old question but if you only want to remove one or few named url parameter you can use this function:
function RemoveGet_Regex($variable, $rewritten_url): string {
$rewritten_url = preg_replace("/(\?)$/", "", preg_replace("/\?&/", "?", preg_replace("/((?<=\?)|&){$variable}=[\w]*/i", "", $rewritten_url)));
return $rewritten_url;
}
function RemoveGet($name): void {
$rewritten_url = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
if(is_array($name)) {
for($i = 0; $i < count($name); $i++) {
$rewritten_url = RemoveGet_Regex($name[$i], $rewritten_url);
$is_set[] = isset($_GET[$name[$i]]);
}
$array_filtered = array_filter($is_set);
if (!empty($array_filtered)) {
header("Location: ".$rewritten_url);
}
}
else {
$rewritten_url = RemoveGet_Regex($name, $rewritten_url);
if(isset($_GET[$name])) {
header("Location: ".$rewritten_url);
}
}
}
In the first function preg_replace("/((?<=\?)|&){$variable}=[\w]*/i", "", $rewritten_url) will remove the get parameter, and the others will tidy it up. The second function will then redirect.
RemoveGet("id"); will remove the id=whatever from the url. The function can also work with arrays. For your example,
Remove(array("id","Item","return"));
To strip any parameter from the url using PHP script you need to follow this script:
function getNewArray($array,$k){
$dataArray = $array;
unset($array[$k]);
$dataArray = $array;
return $dataArray;
}
function getFullURL(){
return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
}
$url = getFullURL();
$url_components = parse_url($url);
// Use parse_str() function to parse the
// string passed via URL
parse_str($url_components['query'], $params);
print_r($params);
<ul>
<?php foreach($params as $k=>$v){?>
<?php
$newArray = getNewArray($params,$k);
$parameters = http_build_query($newArray);
$newURL = $_SERVER['PHP_SELF']."?".$parameters;
?>
<li><?=$v;?> X
<?php }?>
</ul>
here is functions optimized for speed. But this functions DO NOT remove arrays like a[]=x&a[1]bb=y&a[2]=z by array name.
function removeQueryParam($query, $param)
{
$quoted_param = preg_quote($param, '/');
$pattern = "/(^$quoted_param=[^&]*&?)|(&$quoted_param=[^&]*)/";
return preg_replace($pattern, '', $query);
}
function removeQueryParams($query, array $params)
{
if ($params)
{
$pattern = '/';
foreach ($params as $param)
{
$quoted_param = preg_quote($param, '/');
$pattern .= "(^$quoted_param=[^&]*&?)|(&$quoted_param=[^&]*)|";
}
$pattern[-1] = '/';
return preg_replace($pattern, '', $query);
}
return $query;
}
<? if(isset($_GET['i'])){unset($_GET['i']); header('location:/');} ?>
This will remove the 'i' parameter from the URL. Change the 'i's to whatever you need.

Categories