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

发布于 2024-12-04 03:03:08 字数 599 浏览 0 评论 0原文

我需要实现函数来检查路径和 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';
}

I need to implement functions to check whether paths and urls are relative, absolute, or invalid (invalid syntactically- not whether resource exists). What are the range of cases I should be looking for?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

薆情海 2024-12-11 03:03:08

使用:

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

Use:

function isAbsolute($url) {
  return isset(parse_url($url)['host']);
}

Explanation:

If the host is set, the path is absolute.

For example:

$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"
  ]
]
*/
赢得她心 2024-12-11 03:03:08

绝对路径和 URL

你是对的,Linux 中的绝对 URL 必须以 / 开头,因此检查路径开头是否有斜杠就足够了。

对于 URL,您需要检查 http://https://,正如您所写,但是,还有更多以 ftp:// 开头的 URLsftp://smb://。因此,这很大程度上取决于您想要覆盖的用途范围。

无效路径和 URL

假设您指的是 Linux,则路径中唯一禁止使用的字符是 /\0。这实际上非常依赖于文件系统,但是,您可以假设上述内容对于大多数用途都是正确的。

在 Windows 中,情况更为复杂。您可以在 Path.GetInvalidPathChars 方法 < /a> 备注下的文档。

URL 比 Linux 路径更复杂,因为唯一允许的字符是 AZaz0-9、<代码>-、<代码>.、<代码>_、<代码>~、<代码>:、<代码>/, <代码>?, <代码>#, [, ], @, !, $, &'()*+,, ;= (如另一个中所述在此处回答)。

相对路径和 URL

一般来说,既不是绝对的也不是无效的路径和 URL 都是相对的。

Absolute Paths and URLs

You are correct, absolute URLs in Linux must start with /, so checking for a slash in the start of the path will be enough.

For URLs you need to check for http:// and https://, as you wrote, however, there are more URLs starting with ftp://, sftp:// or smb://. So it is very depending on what range of uses you want to cover.

Invalid Paths and URLs

Assuming you are referring to Linux, the only chars that are forbidden in a path are / and \0. This is actually very filesystem dependent, however, you can assume the above to be correct for most uses.

In Windows it is more complicated. You can read about it in the Path.GetInvalidPathChars Method documentation under Remarks.

URLs are more complicated than Linux paths as the only allowed chars are A-Z, a-z, 0-9, -, ., _, ~, :, /, ?, #, [, ], @, !, $, &, ', (, ), *, +, ,, ; and = (as described in another answer here).

Relative Paths and URLs

In general, paths and URLs which are neither absolute nor invalid are relative.

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

From Symfony FileSystem component to check if a path is absolute:

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)
    ;
}
夜巴黎 2024-12-11 03:03:08

由于我的声誉不佳,我无法对答案发表评论,因此我必须使用他从 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\.\-\+!
amp;'\(\)*\+,;=]|%[0-9a-f]{2})+:)*
        (?:[\w\.\-\+%!
amp;'\(\)*\+,;=]|%[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); }

希望它可以帮助某人:)

Since I cannot comment on answers because of my poor reputation I have to respond to ymakux answer with the function that he copied from Drupal library.

I am using this function and I have found out that urls with query part (text after ? symbol) which contains | symbol will be evaluated to false

for example:

https://example.com/image.jpeg?fl=res,749,562,3|shr,,20|jpg,90

Will be evaluated to false.

All you have to do is add

\|

To query part of the regex so the function looks like:

public static function isAbsoluteUrl($url)
    {
        $pattern = "/^(?:ftp|https?|feed)?:?\/\/(?:(?:(?:[\w\.\-\+!
amp;'\(\)*\+,;=]|%[0-9a-f]{2})+:)*
        (?:[\w\.\-\+%!
amp;'\(\)*\+,;=]|%[0-9a-f]{2})+@)?(?:
        (?:[a-z0-9\-\.]|%[0-9a-f]{2})+|(?:\[(?:[0-9a-f]{0,4}:)*(?:[0-9a-f]{0,4})\]))(?::[0-9]+)?(?:[\/|\?]
        (?:[\w#!:\.\?\+\|=&@

Hope it helps someone :)

~*,;\/\(\)\[\]\-]|%[0-9a-f]{2})*)?$/xi"; return (bool) preg_match($pattern, $url); }

Hope it helps someone :)

浮云落日 2024-12-11 03:03:08

该函数取自Drupal

public function is_absolute($url)
{
    $pattern = "/^(?:ftp|https?|feed):\/\/(?:(?:(?:[\w\.\-\+!
amp;'\(\)*\+,;=]|%[0-9a-f]{2})+:)*
    (?:[\w\.\-\+%!
amp;'\(\)*\+,;=]|%[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);
}

This function is taken from Drupal

public function is_absolute($url)
{
    $pattern = "/^(?:ftp|https?|feed):\/\/(?:(?:(?:[\w\.\-\+!
amp;'\(\)*\+,;=]|%[0-9a-f]{2})+:)*
    (?:[\w\.\-\+%!
amp;'\(\)*\+,;=]|%[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);
}
淡紫姑娘! 2024-12-11 03:03:08

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

If you already know that the URL is well formed:

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
}
那小子欠揍 2024-12-11 03:03:08

我最近启动了一个 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

I've recently started a composer package that might be useful for checking wether URL's are relative / absolute (and more, ofcourse).

Check out the repository here: https://github.com/Enrise/UriHelper
Or the composer Packagists package here: https://packagist.org/packages/enrise/urihelper

Some examples:

$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
话少情深 2024-12-11 03:03:08

我的盐基于@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 );
}

My grain of salt based on @CIRCLE answer (Symfony FileSystem Component that checks file paths):

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 );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文