PHP filter_var() — FILTER_VALIDATE_URL

Фильтр FILTER_VALIDATE_URL, похоже, имеет некоторые проблемы с проверкой URL-адресов, отличных от ASCII:

var_dump(filter_var('http://pt.wikipedia.org/wiki/', FILTER_VALIDATE_URL)); // http://pt.wikipedia.org/wiki/
var_dump(filter_var('http://pt.wikipedia.org/wiki/Guimarães', FILTER_VALIDATE_URL)); // false

Почему последний URL-адрес не проверяется правильно? И каковы возможные обходные пути? Запуск PHP 5.3.0.

Я также хотел бы знать, где я могу найти исходный код фильтра проверки FILTER_VALIDATE_URL.


person Alix Axel    schedule 26.01.2010    source источник
comment
Вы можете найти исходный код вместе с остальной частью исходного кода PHP. Он находится в свободном доступе в разделе «Загрузки» на их веб-сайте. Что касается вашего вопроса, это звучит как ошибка, и вы должны сообщить об этом. Единственный обходной путь, который я мог бы предложить, — это использовать какую-то другую логику (возможно, пока создать функцию для использования с FILTER_CALLBACK).   -  person zneak    schedule 26.01.2010


Ответы (3)


Анализ начинается здесь:
http://svn.php.net/viewvc/php/php-src/trunk/ext/filter/logical_filters.c?view=markup

и на самом деле делается в /trunk/ext/standard/url.c

На первый взгляд я не вижу ничего, что преднамеренно отбрасывало бы символы, отличные от ASCII, так что, вероятно, это просто отсутствие поддержки юникода. PHP плохо обрабатывает символы, отличные от ASCII, где бы то ни было. :(

person lyle    schedule 26.01.2010
comment
Хм... if (!isalnum((int)*(unsigned char *)s) && *s != '_' && *s != '.') Это должно быть причиной, какие обходные пути вы можете придумать? - person Alix Axel; 26.01.2010
comment
@Alix - Как сказал zneak, вы можете использовать FILTER_CALLBACK для написания собственных функций фильтра. На самом деле должно работать простое копирование и вставка функции C в php-скрипт и замена isalnum на более разрешительную функцию. (Потребуется некоторая корректировка указателей, но, думаю, не так много.) - person lyle; 26.01.2010

Технически это недопустимый URL-адрес в соответствии с разделом 5 RFC 1738. Браузеры автоматически кодируют символ ã в %C3%A3 перед отправкой запроса на сервер. Технически действительный полный URL здесь: http://pt.wikipedia.org/wiki/Guimar%C3%A3es Передайте это фильтру VALIDATE_URL, и он будет работать нормально. Фильтр проверяет только в соответствии со спецификацией, он не пытается исправлять/кодировать символы за вас.

person Rasmus    schedule 31.03.2010

В следующем коде используется filter_var, но кодируются не ascii-символы перед его вызовом. Надеюсь, это поможет кому-то.

<?php

function validate_url($url) {
    $path = parse_url($url, PHP_URL_PATH);
    $encoded_path = array_map('urlencode', explode('/', $path));
    $url = str_replace($path, implode('/', $encoded_path), $url);

    return filter_var($url, FILTER_VALIDATE_URL) ? true : false;
}

// example
if(!validate_url("http://somedomain.com/some/path/file1.jpg")) {
    echo "NOT A URL";
}
else {
    echo "IS A URL";
}
person Huey Ly    schedule 02.05.2017