我需要实现函数来检查路径和 url 是否是相对、绝对或无效(语法上无效 - 不是资源是否存在)。我应该寻找哪些案例?
function check_path($dirOrFile) {
// If it's an absolute path: (Anything that starts with a '/'?)
return 'absolute';
// If it's a relative path:
return 'relative';
// If it's an invalid path:
return 'invalid';
}
function check_url($url) {
// If it's an absolute url: (Anything that starts with a 'http://' or 'https://'?)
return 'absolute';
// If it's a relative url:
return 'relative';
// If it's an invalid url:
return 'invalid';
}
用途:
function isAbsolute($url) {
return isset(parse_url($url)['host']);
}
说明:
如果设置了主机,则路径是绝对路径。
例如:
$test = [
'/link?param=1'=>parse_url('/assa?ass'),
'//aaa.com/link?param=1'=>parse_url('//assa?ass'),
'http://aaa.com/link?param=1'=>parse_url('http://as.plassa?ass')
];
var_export($test);
/* Output:
[
"/link?param=1" => array:2 [▼ // Not absolute
"path" => "/assa"
"query" => "ass"
]
"//aaa.com/link?param=1" => array:2 [▼ // Absolute because of host
"host" => "assa"
"query" => "ass"
]
"http://aaa.com/link?param=1" => array:3 [▼ // Absolute because of host
"scheme" => "http"
"host" => "as.plassa"
"query" => "ass"
]
]
*/
绝对路径和 URL
你是对的,Linux 中的绝对 URL 必须以
/
开头,因此检查路径开头是否有斜杠就足够了。
对于 URL,您需要检查
http://
和 https://
,正如您所写,但是,还有更多以 ftp://
、sftp://
或 smb://
开头的 URL。因此,这很大程度上取决于您想要覆盖的用途范围。
无效路径和 URL
假设您指的是 Linux,路径中唯一禁止使用的字符是
/
和 \0
。这实际上非常依赖文件系统,但是,您可以假设上述内容对于大多数用途都是正确的。
在 Windows 中情况更复杂。您可以在备注下的Path.GetInvalidPathChars Method文档中阅读相关内容。
URL 比 Linux 路径更复杂,因为唯一允许的字符是 A-Z
、
a-z
、
0-9
、
-
、
.
、
_
、
~
、
:
、
/
》 ,
?
,
#
,
[
,
]
,
@
,
!
,
$
,
&
,
'
,
(
,
)
、
*
、
+
、
,
、
;
和
=
(如另一个答案此处中所述)。
相对路径和 URL
一般来说,既不是绝对的也不是无效的路径和URL都是相对的。
Symfony FileSystem 组件 检查路径是否是绝对路径:
public function isAbsolutePath($file)
{
return strspn($file, '/\\', 0, 1)
|| (strlen($file) > 3 && ctype_alpha($file[0])
&& substr($file, 1, 1) === ':'
&& strspn($file, '/\\', 2, 1)
)
|| null !== parse_url($file, PHP_URL_SCHEME)
;
}
我正在使用这个函数,我发现带有查询部分的网址(?符号后的文本)包含 |符号将被评估为 false
例如:
https://example.com/image.jpeg?fl=res,749,562,3|shr,,20|jpg,90
将被评估为 false。
您所要做的就是添加
\|查询正则表达式的一部分,函数如下所示:
public static function isAbsoluteUrl($url)
{
$pattern = "/^(?:ftp|https?|feed)?:?\/\/(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=]|%[0-9a-f]{2})+:)*
(?:[\w\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})+@)?(?:
(?:[a-z0-9\-\.]|%[0-9a-f]{2})+|(?:\[(?:[0-9a-f]{0,4}:)*(?:[0-9a-f]{0,4})\]))(?::[0-9]+)?(?:[\/|\?]
(?:[\w#!:\.\?\+\|=&@$'~*,;\/\(\)\[\]\-]|%[0-9a-f]{2})*)?$/xi";
return (bool) preg_match($pattern, $url);
}
希望它对某人有帮助:)
public function is_absolute($url)
{
$pattern = "/^(?:ftp|https?|feed):\/\/(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=]|%[0-9a-f]{2})+:)*
(?:[\w\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})+@)?(?:
(?:[a-z0-9\-\.]|%[0-9a-f]{2})+|(?:\[(?:[0-9a-f]{0,4}:)*(?:[0-9a-f]{0,4})\]))(?::[0-9]+)?(?:[\/|\?]
(?:[\w#!:\.\?\+=&@$'~*,;\/\(\)\[\]\-]|%[0-9a-f]{2})*)?$/xi";
return (bool) preg_match($pattern, $url);
}
如果您已经知道 URL 的格式正确:
if(strpos($uri,'://')!==false){
//protocol: absolute url
}elseif(substr($uri,0,1)=='/'){
//leading '/': absolute to domain name (half relative)
}else{
//no protocol and no leading slash: relative to this page
}
在此处查看存储库:
https://github.com/Enrise/UriHelper 或者这里的 Composer Packagists 包:https://packagist.org/packages/enrise/urihelper
一些例子:
$uri = new \Enrise\Uri('http://usr:[email protected]:81/mypath/myfile.html?a=b&b[]=2&b[]=3#myfragment');
echo $uri->getScheme(); // http
echo $uri->getUser(); // usr
echo $uri->getPass(); // pss
echo $uri->getHost(); // example.com
echo $uri->getPort(); // 81
echo $uri->getPath(); // /mypath/myfile.html
echo $uri->getQuery(); // a=b&b[]=2&b[]=3
echo $uri->getFragment(); // myfragment
echo $uri->isSchemeless(); // false
echo $uri->isRelative(); // false
$uri->setScheme('scheme:child:scheme.VALIDscheme123:');
$uri->setPort(null);
echo $uri->getUri(); //scheme:child:scheme.VALIDscheme123:usr:[email protected]/mypath/myfile.html?a=b&b[]=2&b[]=3#myfragment
public function is_absolute_url( $url ) {
if ( substr( $url, 0, 1 ) === '/' ||
// minimun absolute url lenght 5: a://a.
strlen( $url ) < 5
) {
return false;
}
// chars before the first '://' in the URL are only alphabetic letters?
$scheme = strtok( $url, '://' );
if ( ! $scheme || // no scheme found.
! ctype_alpha( $scheme ) // scheme with only alphabetic letters.
) {
return false;
}
// confirm URI has a valid scheme.
return null !== parse_url( $url, PHP_URL_SCHEME ); // phpcs:ignore
}