检查 PHP 中的相对路径/URL 与绝对路径/URL

问题描述 投票:0回答:8

我需要实现函数来检查路径和 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';
}
php url relative-path absolute-path relative-url
8个回答
8
投票

用途:

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"
  ]
]
*/

5
投票

绝对路径和 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都是相对的。


4
投票

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) ; }
    

4
投票
由于我的声誉不佳,我无法对答案发表评论,所以我必须使用他从 Drupal 库复制的功能来回复 ymakux 答案。

我正在使用这个函数,我发现带有查询部分的网址(?符号后的文本)包含 |符号将被评估为 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); }

希望它对某人有帮助:)


3
投票
这个函数取自Drupal

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); }
    

3
投票

如果您已经知道 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 }
    

2
投票
我最近启动了一个 Composer 包,它可能有助于检查 URL 是否是相对/绝对(当然还有更多)。

在此处查看存储库:

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
    

0
投票
我对@CIRCLE的怀疑

答案(检查文件路径的Symfony文件系统组件):

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 }
    
© www.soinside.com 2019 - 2024. All rights reserved.