I have a list of absolute URLs. I need to make sure that they all have trailing slashes, as applicable. So:
我有一个绝对url列表。我需要确保它们都有拖尾斜杠,视情况而定。所以:
- http://www.domain.com/ <-- does not need a trailing slash
- http://www.domain.com/ <——不需要拖尾斜杠。
- http://www.domain.com <-- needs a trailing slash
- http://www.domain.com <——需要一个尾部斜杠。
- http://www.domain.com/index.php <-- does not need a trailing slash
- http://www.domain.com/index.php <——不需要尾斜杠
- http://www.domain.com/?message=hello <-- does not need a trailing slash
- http://www.domain.com/?消息=hello <-不需要尾斜杠
I'm guessing I need to use regex, but matching URLs are a pain. Was hoping for an easier solution. Ideas?
我想我需要使用regex,但是匹配url是很痛苦的。我希望有一个更简单的解决办法。想法吗?
5 个解决方案
#1
14
Rather than doing this using regex, you could use parse_url()
to do this. For example:
您可以使用parse_url()而不是使用regex进行此操作。例如:
$url = parse_url("http://www.example.com/ab/abc.html?a=b#xyz");
if(!isset($url['path'])) $url['path'] = '/';
$surl = $url['scheme']."://".$url['host'].$url['path'].'?'.$url['query'].'#'.$url['fragment'];
echo $surl;
#2
19
For this very specific problem, not using a regex at all might be an option as well. If your list is long (several thousand URLs) and time is of any concern, you could choose to hand-code this very simple manipulation.
对于这个非常特殊的问题,完全不使用regex也可能是一个选项。如果您的列表很长(有几千个url),并且需要关注时间,您可以选择手工编写这个非常简单的操作。
This will do the same:
这也将起到同样的作用:
$str .= (substr($str, -1) == '/' ? '' : '/');
It is of course not nearly as elegant or flexible as a regular expression, but it avoids the overhead of parsing the regular expression string and it will run as fast as PHP is able to do it.
It is arguably less readable than the regex, though this depends on how comfortable the reader is with regex syntax (some people might acually find it more readable).
当然,它不像正则表达式那样优雅和灵活,但是它避免了解析正则表达式字符串的开销,并且它的运行速度将和PHP一样快。它的可读性可能不如regex,尽管这取决于读者对regex语法的理解程度(有些人可能会觉得它更容易读)。
It will certainly not check that the string is really a well-formed URL (such as e.g. zerkms' regex), but you already know that your strings are URLs anyway, so that is a bit redundant.
它当然不会检查字符串是否是一个格式良好的URL(例如zerkms的regex),但是您已经知道您的字符串是URL,所以这有点多余。
Though, if your list is something like 10 or 20 URLs, forget this post. Use a regex, the difference will be zero.
不过,如果你的列表中有10到20个url,请忘记这篇文章。使用正则表达式,其差值为零。
#3
3
$url = 'http://www.domain.com';
$need_to_add_trailing_slash = preg_match('~^https?://[^/]+$~', $url);
#4
1
Try this:
试试这个:
if (!preg_match("/.*\/$/", $url)) {
$url = "$url" . "/";
}
#5
1
This may not be the most elegant solution, but it works like a charm. First we get the full url, then check to see if it has a a trailing slash. If not, check to see that there is no query string, it isn't an actual file, and isn't an actual directory. If the url meets all these conditions we do a 301 redirect with the trailing slash added.
这可能不是最优雅的解决方案,但它就像一种魅力。首先我们得到完整的url,然后检查它是否有一个尾斜杠。如果不是,检查是否没有查询字符串,它不是实际的文件,也不是实际的目录。如果url满足所有这些条件,我们将使用添加了斜杠的301重定向。
If you're unfamiliar with PHP headers... note that there cannot be any output - not even whitespace - before this code.
如果您不熟悉PHP头文件……请注意,在此代码之前不可能有任何输出(甚至是空格)。
$url = $_SERVER['REQUEST_URI'];
$lastchar = substr( $url, -1 );
if ( $lastchar != '/' ):
if ( !$_SERVER['QUERY_STRING'] and !is_file( $_SERVER['DOCUMENT_ROOT'].$url ) and !is_dir( $_SERVER['DOCUMENT_ROOT'].$url ) ):
header("HTTP/1.1 301 Moved Permanently");
header( "Location: $url/" );
endif;
endif;
#1
14
Rather than doing this using regex, you could use parse_url()
to do this. For example:
您可以使用parse_url()而不是使用regex进行此操作。例如:
$url = parse_url("http://www.example.com/ab/abc.html?a=b#xyz");
if(!isset($url['path'])) $url['path'] = '/';
$surl = $url['scheme']."://".$url['host'].$url['path'].'?'.$url['query'].'#'.$url['fragment'];
echo $surl;
#2
19
For this very specific problem, not using a regex at all might be an option as well. If your list is long (several thousand URLs) and time is of any concern, you could choose to hand-code this very simple manipulation.
对于这个非常特殊的问题,完全不使用regex也可能是一个选项。如果您的列表很长(有几千个url),并且需要关注时间,您可以选择手工编写这个非常简单的操作。
This will do the same:
这也将起到同样的作用:
$str .= (substr($str, -1) == '/' ? '' : '/');
It is of course not nearly as elegant or flexible as a regular expression, but it avoids the overhead of parsing the regular expression string and it will run as fast as PHP is able to do it.
It is arguably less readable than the regex, though this depends on how comfortable the reader is with regex syntax (some people might acually find it more readable).
当然,它不像正则表达式那样优雅和灵活,但是它避免了解析正则表达式字符串的开销,并且它的运行速度将和PHP一样快。它的可读性可能不如regex,尽管这取决于读者对regex语法的理解程度(有些人可能会觉得它更容易读)。
It will certainly not check that the string is really a well-formed URL (such as e.g. zerkms' regex), but you already know that your strings are URLs anyway, so that is a bit redundant.
它当然不会检查字符串是否是一个格式良好的URL(例如zerkms的regex),但是您已经知道您的字符串是URL,所以这有点多余。
Though, if your list is something like 10 or 20 URLs, forget this post. Use a regex, the difference will be zero.
不过,如果你的列表中有10到20个url,请忘记这篇文章。使用正则表达式,其差值为零。
#3
3
$url = 'http://www.domain.com';
$need_to_add_trailing_slash = preg_match('~^https?://[^/]+$~', $url);
#4
1
Try this:
试试这个:
if (!preg_match("/.*\/$/", $url)) {
$url = "$url" . "/";
}
#5
1
This may not be the most elegant solution, but it works like a charm. First we get the full url, then check to see if it has a a trailing slash. If not, check to see that there is no query string, it isn't an actual file, and isn't an actual directory. If the url meets all these conditions we do a 301 redirect with the trailing slash added.
这可能不是最优雅的解决方案,但它就像一种魅力。首先我们得到完整的url,然后检查它是否有一个尾斜杠。如果不是,检查是否没有查询字符串,它不是实际的文件,也不是实际的目录。如果url满足所有这些条件,我们将使用添加了斜杠的301重定向。
If you're unfamiliar with PHP headers... note that there cannot be any output - not even whitespace - before this code.
如果您不熟悉PHP头文件……请注意,在此代码之前不可能有任何输出(甚至是空格)。
$url = $_SERVER['REQUEST_URI'];
$lastchar = substr( $url, -1 );
if ( $lastchar != '/' ):
if ( !$_SERVER['QUERY_STRING'] and !is_file( $_SERVER['DOCUMENT_ROOT'].$url ) and !is_dir( $_SERVER['DOCUMENT_ROOT'].$url ) ):
header("HTTP/1.1 301 Moved Permanently");
header( "Location: $url/" );
endif;
endif;