Проверьте, является ли строка URL-адресом, закодированным в PHP - PullRequest
19 голосов
/ 28 октября 2009

Как я могу проверить, закодирована ли строка в 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";

Ответы [ 11 ]

33 голосов
/ 17 июня 2010

У меня есть одна хитрость:

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

$string = urldecode($string);

Затем снова сделайте

$string = urlencode($string);

Действуя таким образом, мы можем избежать двойного кодирования:)

11 голосов
/ 18 января 2014

Вот кое-что, что я просто собрал.

if ( urlencode(urldecode($data)) === $data){
    echo 'string urlencoded';
} else {
    echo 'string is NOT urlencoded';
}
10 голосов
/ 28 октября 2009

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

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

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

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

5 голосов
/ 28 октября 2009

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

$t = "A+B";

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

3 голосов
/ 28 октября 2009

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

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

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

НТН.

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

3 голосов
/ 28 октября 2009

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

$is_encoded = preg_match('~%[0-9A-F]{2}~i', $string);
2 голосов
/ 07 января 2015

@ 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);
}
2 голосов
/ 12 ноября 2011

А как же:

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

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

1 голос
/ 03 апреля 2011

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

?path=folder/new%20file.txt&decode=1
0 голосов
/ 24 мая 2015

закрытое статическое логическое значение isEncodedText (String val, String ... encoding) генерирует исключение 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);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...