Мне нужно реализовать функции, чтобы проверить, являются ли пути и 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'; }
Абсолютные пути и URL-адреса
Вы правы, абсолютные URL-адреса в Linux должны начинаться с /
, поэтому проверки на косую черту в начале пути будет достаточно.
Для URL-адресов вам нужно проверить для http://
и https://
, как вы писали, однако, есть больше URL-адресов, начинающихся с ftp://
, sftp://
или smb://
. Так что это очень зависит от того, какой диапазон использования вы хотите покрыть.
Недействительные пути и URL-адреса
Предполагая, что вы имеете в виду Linux, единственными символами, которые запрещены в пути, являются /
и \0
. Это на самом деле очень зависит от файловой системы, однако вы можете считать, что это было правильно для большинства применений.
В Windows это сложнее. Вы можете прочитать об этом в документации по методу Path.GetInvalidPathChars в разделе «Примечания».
URL-адреса более сложны, чем пути Linux, поскольку единственными допустимыми символами являются AZ
, az
, 0-9
, -
0-9
, _
, ~
, :
, /
?
, #
, [
, ]
, @
!
, $
, &
, '
, (
, )
, *
, +
;
и =
(как описано в другом ответе здесь ).
Относительные пути и URL-адреса
В общем, пути и URL-адреса, которые не являются абсолютными и недействительными, относительны.
Недавно я приступил к созданию пакета композитора, который может быть полезен для проверки URL-адреса URL-адреса относительно / абсолютного (и более того, конечно).
Ознакомьтесь с репозиторием здесь: https://github.com/Enrise/UriHelper Или пакет компоновщиков композиторов здесь: https://packagist.org/packages/enrise/urihelper
Некоторые примеры:
$uri = new \Enrise\Uri('http://usr:pss@example.com: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:pss@example.com/mypath/myfile.html?a=b&b[]=2&b[]=3#myfragment
Эта функция взята из 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); }
Из компонента 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) ; }
Поскольку я не могу комментировать ответы из-за моей плохой репутации, я должен ответить на ответ ymakux функцией, которую он скопировал из библиотеки Drupal.
Я использую эту функцию, и я обнаружил, что URL-адреса с частью запроса (текст после символа?), Который содержит | символ будет оценен как false
например:
http://img.ruphp.com/php/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); }
Надеюсь, это кому-то поможет 🙂