Распределение Url в php

У меня есть URL-адрес:

http://www.w3schools.com/PHP/func_string_str_split.asp

Я хочу разбить этот URL-адрес, чтобы получить только часть хоста. Для этого я использую

parse_url($url,PHP_URL_HOST);

он возвращает www.w3schools.com. Я хочу получить только "w3schools.com". есть ли какая-либо функция для этого или мне нужно сделать это вручную?

Ответы

Ответ 1

Есть много способов сделать это. Простая замена является самой быстрой, если вы знаете, что всегда хотите снять "www."

$stripped=str_replace('www.', '', $domain);

Замена regex позволяет привязать это соответствие к началу строки:

$stripped=preg_replace('/^www\./', '', $domain);

Если это всегда первая часть домена, независимо от ее www, вы можете использовать explode/implode. Хотя это легко читать, это самый неэффективный метод:

$parts=explode('.', $domain);
array_shift($parts); //eat first element
$stripped=implode('.', $parts);

Регулярное выражение достигает той же цели более эффективно:

$stripped=preg_replace('/^\w+\./', '', $domain);

Теперь вы можете себе представить, что следующее будет более эффективным, чем вышеупомянутое регулярное выражение:

$period=strpos($domain, '.');
if ($period!==false)
{
    $stripped=substr($domain,$period+1);
}
else
{
    $stripped=$domain; //there was no period
}

Но я сравнил это и обнаружил, что более миллиона итераций версия preg_replace последовательно избивает ее. Типичные результаты, нормированные на самый быстрый (поэтому он имеет единичное время 1):

  • Простая str_replace: 1
  • preg_replace с /^\w+\./: 1.494
  • strpos/substr: 1.982
  • explode/implode: 2.472

Вышеприведенные примеры кода всегда разделяют первый компонент домена, поэтому он будет отлично работать на таких доменах, как "www.example.com" и "www.example.co.uk", но не "example.com" или "www. department.example.com". Если вам нужно обрабатывать домены, которые уже могут быть основным доменом, или иметь несколько поддоменов (например, "foo.bar.baz.example.com" ) и хотите сократить их до основного домена ( "example.com" ), попробуйте следующее. Первый образец в каждом подходе возвращает только последние два компонента домена, поэтому не будет работать с доменами типа "co.uk".

  • explode:

    $parts = explode('.', $domain);
    $parts = array_slice($parts, -2);
    $stripped = implode('.', $parts);
    

    Так как explode является последовательно самым медленным подходом, мало смысла писать версию, которая обрабатывает "co.uk".

  • регулярное выражение:

    $stripped=preg_replace('/^.*?([^.]+\.[^.]*)$/', '$1', $domain);
    

    Это фиксирует последние две части из домена и заменяет полное строковое значение на захваченную часть. С несколькими субдоменами все главные части становятся лишенными.

    Чтобы работать с ".co.uk" -подобными доменами, а также с переменным количеством поддоменов, попробуйте:

    $stripped=preg_replace('/^.*?([^.]+\.(?:[^.]*|[^.]{2}\.[^.]{2}))$/', '$1', $domain);
    
  • ул:

    $end = strrpos($domain, '.') - strlen($domain) - 1;
    $period = strrpos($domain, '.', $end);
    if ($period !== false) {
        $stripped = substr($domain,$period+1);
    } else {
        $stripped = $domain;
    }
    

    Предоставление доменов co.uk:

    $len = strlen($domain);
    if ($len < 7) {
        $stripped = $domain;
    } else {
        if ($domain[$len-3] === '.' && $domain[$len-6] === '.') {
            $offset = -7;
        } else {
            $offset = -5;
        }
        $period = strrpos($domain, '.', $offset);
        if ($period !== FALSE) {
            $stripped = substr($domain,$period+1);
        } else {
            $stripped = $domain;
        }
    }
    

Режимы и основанные на str-реализации реализации могут быть сделаны все-таки немного быстрее, жертвуя краевыми случаями (где основным компонентом домена является одна буква, например, "a.com" ):

  • регулярное выражение:

    $stripped=preg_replace('/^.*?([^.]{3,}\.(?:[^.]+|[^.]{2}\.[^.]{2}))$/', '$1', $domain);
    
  • ул:

    $period = strrpos($domain, '.', -7);
    if ($period !== FALSE) {
        $stripped = substr($domain,$period+1);
    } else {
        $stripped = $domain;
    }
    

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

  • регулярное выражение нескольких поддоменов: 1
  • .co.uk regex (быстрый): 1.01
  • .co.uk str (быстрый): 1.056
  • .co.uk regex (правильно): 1.1
  • .co.uk str (правильный): 1.127
  • множественная субдомена str: 1.282
  • несколько поддоменов взорваться: 1.305

Здесь разница между временами настолько мала, что это было необычно для. Быстрое .co.uk regex, например, часто било базовое многократное поддоменное регулярное выражение. Таким образом, точная реализация не должна оказывать заметного влияния на скорость. Вместо этого выберите один на основе простоты и ясности. Пока вам не нужно обращаться с доменами .co.uk, это будет подход с множественным поддоменом regex.

Ответ 2

Вам нужно снять часть субдомена самостоятельно - для этого нет встроенной функции.

// $domain beeing www.w3scools.com
$domain = implode('.', array_slice(explode('.', $domain), -2));

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

Если вы хотите отключить www. вы можете просто сделать str_replace(), который будет быстрее:

$domain = str_replace('www.', '', $domain);

Ответ 3

Вам нужно отделить все символы перед первым возникновением c символа [.] (вместе с самим [.]) тогда и только тогда, когда в возвращаемой строке имеется более 1 появления [.].

например, если возвращаемая строка - www-139.in.ibm.com, то регулярное выражение должно быть таким, чтобы оно возвращалось in.ibm.com, поскольку это был бы домен.

Если возвращенная строка - music.domain.com, то регулярное выражение должно возвращать domain.com

В редких случаях вы получаете доступ к сайту без префикса сервера, на котором вы можете получить доступ к сайту, используя http://domain.com/pageurl, в этом случае вы получите домен непосредственно как domain.com, в этом случае регулярное выражение не должно лишать ничего

IMO это должна быть псевдо-логика регулярного выражения, если вы хотите, я могу сформировать регулярное выражение для вас, которое будет включать в себя эти вещи.