Проверить, является ли строка URL-адресом в PHP

Как проверить, закодирована ли строка URL?

Какой из следующих подходов лучше?

  • Найдите строку для символов, которые будут закодированы, а какие нет, и если они существуют, то они не закодированы, или
  • Используйте что-то вроде этого, которое я сделал:

function is_urlEncoded($string){
 $test_string = $string;
 while(urldecode($test_string) != $test_string){
  $test_string = urldecode($test_string);
 }
 return (urlencode($test_string) == $string)?True:False; 
}

$t = "Hello World > how are you?";
if(is_urlEncoded($sreq)){
 print "Was Encoded.\n";
}else{
 print "Not Encoded.\n";
 print "Should be ".urlencode($sreq)."\n";
}

Вышеприведенный код работает, но не в тех случаях, когда строка была дважды закодирована, как в этих примерах:

  • $t = "Hello%2BWorld%2B%253E%2Bhow%2Bare%2Byou%253F";
  • $t = "Hello+World%2B%253E%2Bhow%2Bare%2Byou%253F";

Ответы

Ответ 1

Вы никогда не узнаете наверняка, является ли строка кодировкой URL или предполагается, что в ней должна быть последовательность %2B. Вместо этого, вероятно, это зависит от того, откуда взялась строка, т.е. Если она была обработана вручную или из какого-либо приложения.

Лучше ли искать строку для символов, которые будут закодированы, а какие нет, и если они существуют, то это не закодировано.

Я думаю, что это лучший подход, поскольку он будет заботиться о вещах, которые были сделаны программно (при условии, что приложение не оставило бы некодированный символ позади).

Одна вещь, которая будет вводить в заблуждение здесь... Технически, % "должен быть" закодирован, если он будет присутствовать в конечном значении, поскольку он является особым символом. Возможно, вам придется комбинировать свои подходы, чтобы искать символы с кодировкой, а также проверять, что строка успешно декодируется, если ни один не найден.

Ответ 2

У меня есть один трюк:

вы можете сделать это, чтобы избежать двойного кодирования. Каждый раз при первом декодировании он снова кодируется;

$string = urldecode($string);

Затем повторите

$string = urlencode($string);

Выполняя этот путь, мы можем избежать двойного кодирования:)

Ответ 3

Вот что я только что собрал.

if ( urlencode(urldecode($data)) === $data){
    echo 'string urlencoded';
} else {
    echo 'string is NOT urlencoded';
}

Ответ 4

Я думаю, что нет надежного способа сделать это. Например, рассмотрим следующее:

$t = "A+B";

Является ли этот URL закодированным "A B" или он должен быть закодирован в "A% 2BB"?

Ответ 5

ну, термин "закодированный url" немного расплывчатый, возможно простая проверка регулярных выражений сделает трюк

$is_encoded = preg_match('~%[0-9A-F]{2}~i', $string);

Ответ 6

Нет надежного способа сделать это, так как есть строки, которые остаются неизменными в процессе кодирования, то есть "abc" закодированы или нет? Нет четкого ответа. Кроме того, как вы столкнулись, некоторые символы имеют несколько кодировок... Но...

Ваша схема проверки кодировки декодирования не работает из-за того, что некоторые символы могут быть закодированы более чем одним способом. Однако небольшая модификация вашей функции должна быть достаточно надежной, просто проверьте, изменяет ли декодер строку, если это так, она была закодирована.

Конечно, это не будет дураком, поскольку "10 + 20 = 30" вернет true (+ преобразуется в космос), но мы на самом деле просто делаем арифметику. Я предполагаю, что это то, что вы пытаетесь скрыть, - я сожалею, что не думаю, что там идеальное решение.

НТН.

Edit:
Как я уже упоминал в своем собственном комментарии (просто повторяя здесь для ясности), хорошим компромиссом, вероятно, будет проверка наличия недопустимых символов в вашем URL-адресе (например, пробел), и если они некоторые не закодированы. Если их нет, попробуйте декодировать и посмотреть, меняется ли строка. Это все равно не будет обрабатывать вышеизложенную арифметику (что невозможно), но, надеюсь, будет достаточно.

Ответ 7

Как насчет:

if (urldecode(trim($url)) == trim($url)) { $url_form = 'decoded'; }
  else { $url_form = 'encoded'; }

Не будет работать с двойным кодированием, но это все равно вне рамки?

Ответ 8

@user187291 работает только с ошибкой, когда + не закодирован.

Я знаю, что это очень старый пост. Но это сработало со мной.

$is_encoded = preg_match('~%[0-9A-F]{2}~i', $string);
if($is_encoded) {
 $string  = urlencode(urldecode(str_replace(['+','='], ['%2B','%3D'], $string)));
} else {
  $string = urlencode($string);
}

Ответ 9

отправить переменную, которая делит декодирование, когда вы уже получаете данные с URL-адреса.

?path=folder/new%20file.txt&decode=1

Ответ 10

Я использую следующий тест, чтобы проверить, были ли строки urlencoded:

if(urlencode($str) != str_replace(['%','+'], ['%25','%2B'], $str))

Если строка уже была указана на urlencoded, единственными символами, которые будут изменены с помощью двойной кодировки, являются% (которая запускает все закодированные строки символов) и + (которая заменяет пробелы). Измените их назад, и вы должны иметь исходную строку.

Сообщите мне, если это сработает для вас.

Ответ 11

Я нашел.
URL-адрес для примера: https://example.com/xD?foo=bar&uri=https%3A%2F%2Fexample.com%2FxD
Вам нужно нашёл код $ _GET ['uri'] или нет:

preg_match("/.*uri=(.*)&?.*/", $_SERVER['REQUEST_URI'], $r);
if (isset($_GET['uri']) && urldecode($r['1']) === $r['1']) {
  // Code Here if url is not encoded
}

Ответ 12

private static boolean isEncodedText (String val, String... encoding) throws UnsupportedEncodingException   {       String decodedText = URLDecoder.decode(val, TransformFetchConstants.DEFAULT_CHARSET);

    if(encoding != null && encoding.length > 0){
        decodedText = URLDecoder.decode(val, encoding[0]);
    }

    String encodedText =  URLEncoder.encode(decodedText);

    return encodedText.equalsIgnoreCase(val) || !decodedText.equalsIgnoreCase(val);

}