URL का उपडोमेन प्राप्त करने के लिए PHP फ़ंक्शन


107

क्या उपडोमेन का नाम पाने के लिए PHP में कोई फ़ंक्शन है?

निम्नलिखित उदाहरण में मैं URL का "en" भाग प्राप्त करना चाहूंगा:

en.example.com

6
क्या आपके पास एक URL है जो स्ट्रिंग चर में संग्रहीत है या यह URL कहाँ से आ रहा है? संदर्भ क्या है? कृपया विस्तार से बताएं।
फेलिक्स क्लिंग

आप एक regex का उपयोग नहीं कर सकते हैं जो कुछ पसंद करता है (^|://)(.*)\.और .*किस पर कब्जा करता है ? मैं बल्कि php और regex दोनों को चूसता हूं, लेकिन यह ध्यान में आता है।
corsiKa

उस में क्या मिलना चाहिए en.foo.bar.example.comया en.example.co.uk?
अल्वारो गोंजालेज

parse_url भी मदद कर सकता है
स्वप्निल

जवाबों:


132

यहाँ एक लाइन समाधान है:

array_shift((explode('.', $_SERVER['HTTP_HOST'])));

या अपने उदाहरण का उपयोग कर:

array_shift((explode('.', 'en.example.com')));

संपादित करें: डबल कोष्ठक जोड़कर "फिक्स्ड" केवल चर संदर्भ द्वारा पारित किया जाना चाहिए।


EDIT 2 : PHP 5.4 से शुरू आप बस यह कर सकते हैं:

explode('.', 'en.example.com')[0];

17
केवल चर संदर्भ द्वारा पारित किया जाना चाहिए।
तमसे पाप

8
क्या आप explode(...)[0]इन दिनों बदलाव का उपयोग करने के बजाय सिर्फ करने में सक्षम नहीं हैं ? कई वर्षों से PHPing नहीं किया गया है
Tor Valamo

त्रुटि:Strict Standards: Only variables should be passed by reference.
जस्टिन

1
बहुत यकीन है कि आप (विस्फोट कर सकते हैं ... ()) [0] हालांकि, फ़ंक्शन पैरेन्थेसिस (5.4 से पहले) के बजाय रिटर्न ऐरे पर काम करना चाहिए
Garet Claborn

3
यह समाधान किसी प्रकार के मामले में काम नहीं करेगा www.en.example.comऔर इस तरह wwwउपडोमेन के रूप में वापस आ जाएगा ।
लोलबास

65

Parse_url फ़ंक्शन का उपयोग करता है ।

$url = 'http://en.example.com';

$parsedUrl = parse_url($url);

$host = explode('.', $parsedUrl['host']);

$subdomain = $host[0];
echo $subdomain;

कई उप-डोमेन के लिए

$url = 'http://usa.en.example.com';

$parsedUrl = parse_url($url);

$host = explode('.', $parsedUrl['host']);

$subdomains = array_slice($host, 0, count($host) - 2 );
print_r($subdomains);

@ माइक लुईस - क्या यह कई उप-डोमेन की समस्या को हल करता है, जैसे कि usa.en.example.com? बस सोच (मेरा खुद का जवाब नहीं है, btw)।
जारेड फरिश

@ जेरेड, बस कई उप डोमेन का पता लगाने के लिए एक समाधान जोड़ा गया।
माइक लुईस

1
@ माइक - क्या यह tx.usa.en.example.com के साथ काम करेगा? (या science.news.bbc.co.uk )? (btw, यह एक काम कर लिंक नहीं है, सिर्फ एक उदाहरण है, हालांकि news.bbc.co.uk काम करता है)
जेरेड फरिश

4
यह सब कुछ है कि एक 'शब्द' TLD जैसे नेट, कॉम, बिज़ आदि के लिए काम करता है। हालांकि, उदाहरण के लिए, co.uk के साथ काम करते समय, यह नहीं करता है। जैसा कि यहां देखा गया है यह वास्तव में हल करने के लिए एक कठिन समस्या है।
माइक लुईस

2
यह भी विफल रहता है अगर वहाँ कोई उपडोमेन नहीं है।
raveren

32

आप इसे पहले डोमेन नाम (जैसे sub.example.com => example.co.uk) प्राप्त करके कर सकते हैं और फिर उप डोमेन प्राप्त करने के लिए स्ट्रैस का उपयोग कर सकते हैं।

$testArray = array(
    'sub1.sub2.example.co.uk',
    'sub1.example.com',
    'example.com',
    'sub1.sub2.sub3.example.co.uk',
    'sub1.sub2.sub3.example.com',
    'sub1.sub2.example.com'
);

foreach($testArray as $k => $v)
{
    echo $k." => ".extract_subdomains($v)."\n";
}

function extract_domain($domain)
{
    if(preg_match("/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i", $domain, $matches))
    {
        return $matches['domain'];
    } else {
        return $domain;
    }
}

function extract_subdomains($domain)
{
    $subdomains = $domain;
    $domain = extract_domain($subdomains);

    $subdomains = rtrim(strstr($subdomains, $domain, true), '.');

    return $subdomains;
}

आउटपुट:

0 => sub1.sub2
1 => sub1
2 =>
3 => sub1.sub2.sub3
4 => sub1.sub2.sub3
5 => sub1.sub2

2
यह सबसे अच्छा समाधान लगता है क्योंकि यह डोमेन नाम को बिना उपडोमेन के लिए भी अनुमति देता है, बजाय डोमेन नाम को फिर से शुरू करने के रूप में उपडोमेन पहले डॉट के पहले भाग के रूप में। एक उपडोमेन के अस्तित्व की जाँच के लिए बहुत उपयोगी है।
कार्ल

मुझे "आधार" डोमेन (उपडोमेन के बिना) प्राप्त करने की आवश्यकता थी, और मैं मेजबान को विस्फोट करके और forलूप के साथ सरणी के अंतिम तत्वों को प्राप्त करके अपना समाधान बना रहा था , लेकिन मुझे उनकी लंबाई की जांच करनी थी (पता लगाने के लिए कि क्या वे "co.uk" जैसे डोमेन का एक हिस्सा थे)। वास्तव में, मैं क्या कर रहा था की तुलना में आपका समाधान कहीं अधिक सरल है। रेगेक्स जान बचाते हैं, धन्यवाद!
योन

1
बहुत बढ़िया .. यह सभी डोमेन प्रकारों और उप डोमेन के लिए इतनी अच्छी तरह से काम करता है .. अच्छा है।
जॉन

2
हालांकि यह समाधान बहुत साफ-सुथरा है और लगभग सभी मामलों में काम कर सकता है , इस बात से अवगत रहें कि डोमेन नाम में 6 से अधिक चार्ट हो सकते हैं, जैसे pvt.k12.ma.us, health.vnया यहाँ तक कि k12.ak.us। इसके अलावा, डोमेन नाम चीनी या रूसी वर्ण सेट का उपयोग किया जा सकता है ताकि रेगेक्स भाग [a-z\.]{2,6}उनसे मेल न खाए। उदाहरण के लिए यहाँ देखें डोमेन नाम: publicsuffix.org/list
pomeh

12

http://php.net/parse_url

<?php
  $url = 'http://user:password@sub.hostname.tld/path?argument=value#anchor';
  $array=parse_url($url);
  $array['host']=explode('.', $array['host']);

  echo $array['host'][0]; // returns 'en'
?>

7

डोमेन प्रत्यय के लिए एकमात्र विश्वसनीय स्रोत डोमेन रजिस्ट्रार हैं, आप उनकी जानकारी के बिना उपडोमेन नहीं खोज सकते। Https://publicsuffix.org पर सभी डोमेन प्रत्ययों के साथ एक सूची है । यह साइट एक PHP लाइब्रेरी से भी जुड़ती है: https://github.com/jeremykendall/php-domain-parser

कृपया नीचे एक उदाहरण खोजें। मैंने en.test.co.uk के लिए नमूना भी जोड़ा है जो एक बहु प्रत्यय (co.uk) के साथ एक डोमेन है।

<?php

require_once 'vendor/autoload.php';

$pslManager = new Pdp\PublicSuffixListManager();
$parser = new Pdp\Parser($pslManager->getList());
$host = 'http://en.example.com';
$url = $parser->parseUrl($host);

echo $url->host->subdomain;


$host = 'http://en.test.co.uk';
$url = $parser->parseUrl($host);

echo $url->host->subdomain;

5

सबसे सरल और सबसे तेज़ समाधान।

$sSubDomain = str_replace('.example.com','',$_SERVER['HTTP_HOST']);

4

सीधे शब्दों में ...

    preg_match('/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/i', $url, $match);

सिर्फ $ मैच पढ़ें [1]

काम करने का उदाहरण

यह यूआरएल की इस सूची के साथ पूरी तरह से काम करता है

$url = array(
    'http://www.domain.com', // www
    'http://domain.com', // --nothing--
    'https://domain.com', // --nothing--
    'www.domain.com', // www
    'domain.com', // --nothing--
    'www.domain.com/some/path', // www
    'http://sub.domain.com/domain.com', // sub
    'опубликованному.значения.ua', // опубликованному ;)
    'значения.ua', // --nothing--
    'http://sub-domain.domain.net/domain.net', // sub-domain
    'sub-domain.third-Level_DomaIN.domain.uk.co/domain.net' // sub-domain
);

foreach ($url as $u) {
    preg_match('/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/i', $u, $match);
    var_dump($match);
}

2
PS - मुझे इसका कोई अंदाजा नहीं है कि यह रूसी पाठ में क्या लिखा गया है। बस ru.wikipedia.org से कुछ आकस्मिक शब्दों को लिया ;)
कामाफेदर

क्या यह यूक्रेनी नहीं है? .uaयूक्रेन के लिए देश कोड है।
nalply

नहीं। बस मिली जानकारी। लेकिन मुझे यकीन नहीं है, मैं उन्हें भेद करने के लिए काफी अच्छा नहीं हूं;)
कामाफेदर

3
रूसी के संबंध में, रूसी से अंग्रेजी में एक Google अनुवाद "प्रकाशित मूल्यों" के रूप में वापस आता है (यदि किसी को मेरी तरह उत्सुक था)
जेरेमी हैरिस

@ कामाफेदर बुलेटप्रूफ दिखता है। किसी भी तरह से सिर्फ $match[1]हिस्सा पाने के लिए ? $match[0]अनावश्यक लगता है।
एंड्रेस एसके

3
$REFERRER = $_SERVER['HTTP_REFERER']; // Or other method to get a URL for decomposition

$domain = substr($REFERRER, strpos($REFERRER, '://')+3);
$domain = substr($domain, 0, strpos($domain, '/'));
// This line will return 'en' of 'en.example.com'
$subdomain = substr($domain, 0, strpos($domain, '.')); 

1
वर्तमान होस्ट (जैसे $_SERVER['HTTP_HOST']) का पता लगाने के लिए बेहतर तरीके हैं, फिर स्पूफ-सक्षम रेफ़र हेडर पर भरोसा करते हुए, यह मानते हुए कि उत्तर के पीछे सामान्य विचार क्या है।
मैथ्यू

ठीक है, मैं एक पुराने कोड का उपयोग कर रहा था। उदाहरण अभी भी खड़ा है। यह सवाल की जड़ नहीं है।
जारेड फरिश

बस इन टिप्पणियों को ऊपर जोड़ने के लिए, $ _SERVER ['HTTP_HOST'] पर भरोसा करना संभव नहीं है, क्योंकि एक मौका है कि इसे सेट नहीं किया जा सकता है।
gmslzr

2

PHP 7.0: विस्फोट कार्य का उपयोग करना और सभी परिणामों की एक सूची बनाना।

list($subdomain,$host) = explode('.', $_SERVER["SERVER_NAME"]);

उदाहरण: sub.domain.com

echo $subdomain; 

परिणाम: उप

echo $host;

परिणाम: डोमेन


आप TLD की तरह भूल जाते हैं .co.uk- आपका स्निपेट इन TLD के साथ काम नहीं करेगा
Adrian Preuss

1

मैंने जो सबसे अच्छा और छोटा समाधान पाया, वह है

array_shift(explode(".",$_SERVER['HTTP_HOST']));

सख्त त्रुटि का कारण होगा। एक्सप्लोड के आउटपुट को array_shift पर सीधे पास नहीं किया जा सकता है।
यक

1

जिन लोगों को 'त्रुटि: सख्त मानक: केवल चर को संदर्भ द्वारा पारित किया जाना चाहिए।' इस तरह का उपयोग करें:

$env = (explode(".",$_SERVER['HTTP_HOST'])); $env = array_shift($env);


यह सवाल नहीं था, लेकिन आपके इनपुट के लिए धन्यवाद।
FazoM


1

वास्तव में एक 100% गतिशील समाधान नहीं है - मैं सिर्फ यह पता लगाने की कोशिश कर रहा हूं और विभिन्न डोमेन एक्सटेंशन (DTL) के कारण यह कार्य वास्तव में इन सभी एक्सटेंशनों को पार्स करने और हर बार उन्हें जांचने के बिना वास्तव में मुश्किल होगा:

.com vs .co.uk vs org.uk

सबसे विश्वसनीय विकल्प एक स्थिर (या डेटाबेस प्रविष्टि आदि) को परिभाषित करना है जो वास्तविक डोमेन नाम को संग्रहीत करता है और इसे $_SERVER['SERVER_NAME']उपयोग से हटा देता हैsubstr()

defined("DOMAIN")
    || define("DOMAIN", 'mymaindomain.co.uk');



function getSubDomain() {

    if (empty($_SERVER['SERVER_NAME'])) {

        return null;

    }

    $subDomain = substr($_SERVER['SERVER_NAME'], 0, -(strlen(DOMAIN)));

    if (empty($subDomain)) {

        return null;

    }

    return rtrim($subDomain, '.');

}

अब यदि आप इस फ़ंक्शन का उपयोग कर रहे हैं, तो http://test.mymaindomain.co.ukयह आपको देगा testया यदि आपके पास कई उप-डोमेन स्तर हैं, http://another.test.mymaindomain.co.ukतो another.test- जब तक आप निश्चित रूप से अपडेट नहीं करते DOMAIN

आशा है कि ये आपकी मदद करेगा।



1

रेगेक्स, स्ट्रिंग फ़ंक्शंस, parse_url () या उनके संयोजन का उपयोग करना इसका वास्तविक समाधान नहीं है। बस डोमेन के साथ किसी भी प्रस्तावित समाधान का परीक्षण करें test.en.example.co.uk, कोई सही परिणाम नहीं होगा।

सही समाधान का उपयोग पैकेज है जो सार्वजनिक प्रत्यय सूची के साथ डोमेन को पार्स करता है । मैं TLDExtract का पुन: अध्ययन करता हूं , यहां नमूना कोड है:

$extract = new LayerShifter\TLDExtract\Extract();

$result = $extract->parse('test.en.example.co.uk');
$result->getSubdomain(); // will return (string) 'test.en'
$result->getSubdomains(); // will return (array) ['test', 'en']
$result->getHostname(); // will return (string) 'example'
$result->getSuffix(); // will return (string) 'co.uk'

1

यह मेरा समाधान है, यह सबसे आम डोमेन के साथ काम करता है, आप एक्सटेंशन के सरणी को आवश्यकतानुसार फिट कर सकते हैं:

$SubDomain = explode('.', explode('|ext|', str_replace(array('.com', '.net', '.org'), '|ext|',$_SERVER['HTTP_HOST']))[0]);

0
// For www.abc.en.example.com 
$host_Array = explode(".",$_SERVER['HTTP_HOST']); // Get HOST as array www, abc, en, example, com
array_pop($host_Array); array_pop($host_Array);   // Remove com and exmaple
array_shift($host_Array);                         // Remove www (Optional)
echo implode($host_Array, ".");                   // Combine array abc.en

0

मुझे पता है कि मैं वास्तव में खेल के लिए देर से जा रहा हूँ, लेकिन यहाँ जाता है।

मैंने क्या किया HTTP_HOST सर्वर चर ($_SERVER['HTTP_HOST'] ) और डोमेन में अक्षरों की संख्या (इसलिए इसके लिए example.com11 होगा) लिया गया।

फिर मैंने substrउपडोमेन प्राप्त करने के लिए फ़ंक्शन का उपयोग किया । मैंने किया

$numberOfLettersInSubdomain = strlen($_SERVER['HTTP_HOST'])-12
$subdomain = substr($_SERVER['HTTP_HOST'], $numberOfLettersInSubdomain);

मैंने 11 के बजाय 12 पर सबस्ट्रिंग को काट दिया क्योंकि दूसरे पैरामीटर के लिए सबस्ट्रिंग 1 पर शुरू होता है। तो अब अगर आपने test.example.com, का मान दर्ज किया है$subdomain होगा test

यह उपयोग करने से बेहतर है explodeक्योंकि अगर उपडोमेन .में यह है, तो यह इसे काट नहीं देगा।


आपके जवाब में प्रारंभ स्थिति "0" गायब थी। $ उपडोमेन = पदार्थ ($ _ SERVER ['HTTP_HOST'], 0, $ numberOfLettersInSubdomain);
जेमी

0

यदि आप ड्रुपल 7 का उपयोग कर रहे हैं

इससे आपको मदद मिलेगी:

global $base_path;
global $base_root;  
$fulldomain = parse_url($base_root);    
$splitdomain = explode(".", $fulldomain['host']);
$subdomain = $splitdomain[0];

0
$host = $_SERVER['HTTP_HOST'];
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
$domain = $matches[0];
$url = explode($domain, $host);
$subdomain = str_replace('.', '', $url[0]);

echo 'subdomain: '.$subdomain.'<br />';
echo 'domain: '.$domain.'<br />';

0

PHP 5.3 से आप सच्चे पैरामीटर के साथ स्ट्रैस () का उपयोग कर सकते हैं

echo strstr($_SERVER["HTTP_HOST"], '.', true); //prints en

यह केवल तभी काम करेगा जब wwwस्ट्रिंग स्टार्ट न हो। थोड़ा बहुत तुच्छ दृष्टिकोण।
फुआबर

यह टीम के अन्य डेवलपर्स के लिए चीजों को सरल बनाता है, मैं इसे कुछ उन्नत रेग एक्सप की तुलना में उपयोग करूंगा। यदि आप www का उपयोग ट्रिम करना चाहते हैं ($ s, 'www'); या बस इसे अपने व्यावसायिक तर्क में समायोजित करें ...
tasmaniski

1
पूर्णता के लिए, www है वास्तव में एक उप डोमेन। यह आमतौर पर ऐतिहासिक कारणों से डोमेन नाम के लिए उपनाम है।
लेवी मॉरिसन

0

इसे इस्तेमाल करे...

$domain = 'en.example.com';
$tmp = explode('.', $domain);
$subdomain = current($tmp);
echo($subdomain);     // echo "en"

मुझे लगता है कि यह ओपी और आगे आने वाले दर्शकों के लिए अधिक उपयोगी होगा, जब आप कुछ व्याख्याओं को आप के साथ जोड़ देंगे।
रिपोर्टर

0
function get_subdomain($url=""){
    if($url==""){
        $url = $_SERVER['HTTP_HOST'];
    }
    $parsedUrl = parse_url($url);
    $host = explode('.', $parsedUrl['path']);
    $subdomains = array_slice($host, 0, count($host) - 2 );
    return implode(".", $subdomains);
}

1
लाइन # 7 होनी चाहिए$host = explode('.', isset($parsedUrl['path']) ? $parsedUrl['path'] : $parsedUrl['host']);
काल

0

आप इसका भी उपयोग कर सकते हैं

echo substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.', -5));

0

मैं कुछ ऐसा कर रहा हूं

$url = https://en.example.com

$splitedBySlash = explode('/', $url);
$splitedByDot = explode('.', $splitedBySlash[2]);

$subdomain = $splitedByDot[0];

0

हम कई उपडोमेन को संभालने के लिए इस फ़ंक्शन का उपयोग करते हैं और कई tld आईपी ​​और लोकलहोस्ट को भी संभालते हैं

function analyse_host($_host)
    {
        $my_host   = explode('.', $_host);
        $my_result = ['subdomain' => null, 'root' => null, 'tld' => null];

        // if host is ip, only set as root
        if(filter_var($_host, FILTER_VALIDATE_IP))
        {
            // something like 127.0.0.5
            $my_result['root'] = $_host;
        }
        elseif(count($my_host) === 1)
        {
            // something like localhost
            $my_result['root'] = $_host;
        }
        elseif(count($my_host) === 2)
        {
            // like jibres.com
            $my_result['root'] = $my_host[0];
            $my_result['tld']  = $my_host[1];
        }
        elseif(count($my_host) >= 3)
        {
            // some conditons like
            // ermile.ac.ir
            // ermile.jibres.com
            // ermile.jibres.ac.ir
            // a.ermile.jibres.ac.ir

            // get last one as tld
            $my_result['tld']  = end($my_host);
            array_pop($my_host);

            // check last one after remove is probably tld or not
            $known_tld    = ['com', 'org', 'net', 'gov', 'co', 'ac', 'id', 'sch', 'biz'];
            $probably_tld = end($my_host);
            if(in_array($probably_tld, $known_tld))
            {
                $my_result['tld'] = $probably_tld. '.'. $my_result['tld'];
                array_pop($my_host);
            }

            $my_result['root'] = end($my_host);
            array_pop($my_host);

            // all remain is subdomain
            if(count($my_host) > 0)
            {
                $my_result['subdomain'] = implode('.', $my_host);
            }
        }

        return $my_result;
    }

0

मान लीजिए कि वर्तमान url = sub.example.com

    $ होस्ट = array_reverse (विस्फोट) ('।, $ _SERVER [' SERVER_NAME ']));

    यदि (गणना ($ होस्ट)> = 3) {
       गूंज "मुख्य डोमेन =" है। $ होस्ट [1]। "। $ होस्ट [0]।" और उपडोमेन = "है। $ होस्ट [2];
       // मुख्य डोमेन = example.com है और उप डोमेन = उप है
    } अन्य {
       गूंज "मुख्य डोमेन =" है। $ होस्ट [1]। "।" $ होस्ट [0]। "और उपडोमेन पाया";
       // "मुख्य डोमेन है = example.com और उपडोमेन नहीं मिला";
    }


-3

यदि आप केवल वही चाहते हैं जो पहली अवधि से पहले आता है:

list($sub) = explode('.', 'en.example.com', 2);

क्या होगा अगर शुरुआत में एक प्रोटोकॉल हैंडलर है, जैसे http: //, https: //, ftp: //, आदि ...? ;)
जारेड फरिश

@Jared, वहाँ कोई प्रोटोकॉल नहीं है जो वह पार्स करने के लिए देख रहा है ... लेकिन अगर वहाँ थे, तो मैं parse_url()मेजबान को निकालने के लिए उपयोग करूँगा ।
मैथ्यू

इसलिए हमने दो दृष्टिकोण प्रदान किए हैं जो विभिन्न संदर्भों में उचित होंगे।
जारेड फरिश

मुख्य रूप से, मुझे खुशी है कि किसी ने रेगेक्स उत्तर (अभी तक) पोस्ट नहीं किया है। मेरे उत्तर की अंतिम पंक्ति का उल्लेख नहीं करना भी वही करता है जो आपके द्वारा किया जाता है।
जारेड फरिश

और अगर hostname en.example.co.uk है?
मार्क बी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.