Проверка относительных абсолютных путей / URL-адресов в PHP

Мне нужно реализовать функции, чтобы проверить, являются ли пути и 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); } 

Надеюсь, это кому-то поможет 🙂