- PVSM.RU - https://www.pvsm.ru -
Задача:
Пример: | http://site.ru/page.php |
/page.php |
site.ru/page.php |
---|---|---|---|
scheme | http | ||
host | site.ru | site.ru | |
path | page.php | page.php | page.php |
В этом нам должен помочь класс ZendUriHttp
. У него есть нужные нам методы parse($uri)
, getHost()
, getPath()
и т.п.
Но! При разборе URL'а типа «site.ru/page.php
» (без «http://
») getHost()
вернёт пустую строку, а getPath()
вернёт «site.ru/page.php
».
Вот мой способ достичь желаемого. По формату абсолютная неполная ссылка идентична ссылке относительно источнику (тип относительной ссылки). Распознать абсолютную неполную ссылку можно проверив её TDL (домен первого уровня). Если такой домен существует — ссылку можно считать абсолютной неполной.
public function myParse($url){
$Http = new Http($url);
if($Http->isValidRelative()){
// если url разобран как относительный
$path = $Http->getPath();
// если path начинается со «/» — ссылка не может быть воспринята как «неправильный» формат абсолютной ссылки
// и считается относительной
if( $path{0} !== '/' ){
// иначе пробуем собрать абсолютную ссылку...
$absoluteUrl = '//'.urldecode($Http->toString());
$absoluteHttp = new Http($absoluteUrl);
// (1)
$Hostname = new Hostname(array('allow'=>Hostname::ALLOW_DNS, 'useTldCheck'=>false));
$decode = true;
// ... и проверить её хост на правильность (2)
if ($Hostname->isValid($absoluteHttp->getHost($decode))) {
// в случае правильности хоста считаем, что ссылку абсолютной «неправильного» формата
$Http = $absoluteHttp;
}
}
}
return $Http;
}
ZendValidatorHostname
так, чтобы он проверил присутствие домена первого уровня ссылки в массиве $validIdns
getHost()
параметр $decode = true;
для того чтобы декодировать хост. Метод getHost()
сласса ZendUriHttp
не предполагает ни каких параметров и ни чего не декодирует! Для чего тогда это и как это работает?!.. Читайте ниже.
К сожалению, ZF2 толком не работает с IDN, что нам придётся компенсировать. Для этого нужно скачать любой понравившийся класс, кодирующий и декодирующий url с помощью punycode и расширить класс ZendUriHttp
.
namespace ApplicationOther;
use ZendUriHttp as ZendHttp;
use ApplicationModelIdnaConvert;
class Http extends ZendHttp
{
public function setHost($host){
if($host){
$idn = new IdnaConvert();
$host = $idn->encode($host);
}
return parent::setHost($host);
}
public function getHost($decode=false) {
if($decode && $this->host){
$idn = new IdnaConvert();
return $idn->decode($this->host);
}
return parent::getHost();
}
}
Соответственно, наш метод myParse()
должен использовать именно расширенный класс Http
, который при разборе URL сможет кодировать РФ-домены; а при вызове метода getHost($decode)
, мы будем иметь возможность вернуть Punycode-представление или декодированное представление, в зависимости от переданного методу параметра.
P.S. Есть сомнения по качеству вышеизложенного, но вместе с тем это один из поводов опубликовать пост, чтобы узнать мнение тех, кто более опытен по части ZF2. Ещё один повод — я ни где не нашёл решения этой, казалось бы, очевидной задачи. Может быть от вас я узнаю о других, быть может более простых и грамотных вариантах.
Автор: deffect
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/zend-framework-2/46335
Ссылки в тексте:
[1] Источник: http://habrahabr.ru/post/198614/
Нажмите здесь для печати.