steveo225
steveo225

Reputation: 11882

Programmatically get domain for cookie

I want to set the domain for a cookie and the session cookie so it applies to all sub-domains. I know I can do this using the following:

session_set_cookie_params(0, '/', '.example.com');
set_cookie('name', value, expires, '/', '.example.com');

How do I get .example.com from the server variables in PHP? The problem is, I need to get it to work for all types of domain patterns, e.g.

Upvotes: 1

Views: 2328

Answers (3)

axew3
axew3

Reputation: 311

It seem to be impossible, without an array containing values. Possible to avoid the iteration into array to check for +- all domains, but not for all. With something like this (that maybe can be improved) you'll get ever the correct cookie domain name. It iterate only one time the array, and checking for one value: https://www.axew3.com/w3/2017/05/extract-domain-name-for-cookie-php-function/

EDITED: the code has been improved.

IMPROVED VERSION:

$w3domains = array(".aero",".biz",".cat",".com",".coop",".edu",".gov",".info",".int",".jobs",".mil",".mobi",".museum",
    ".name",".net",".org",".travel",".ac",".ad",".ae",".af",".ag",".ai",".al",".am",".an",".ao",".aq",".ar",".as",".at",".au",".aw",
    ".az",".ba",".bb",".bd",".be",".bf",".bg",".bh",".bi",".bj",".bm",".bn",".bo",".br",".bs",".bt",".bv",".bw",".by",".bz",".ca",
    ".cc",".cd",".cf",".cg",".ch",".ci",".ck",".cl",".cm",".cn",".co",".cr",".cs",".cu",".cv",".cx",".cy",".cz",".de",".dj",".dk",".dm",
    ".do",".dz",".ec",".ee",".eg",".eh",".er",".es",".et",".eu",".fi",".fj",".fk",".fm",".fo",".fr",".ga",".gb",".gd",".ge",".gf",".gg",".gh",
    ".gi",".gl",".gm",".gn",".gp",".gq",".gr",".gs",".gt",".gu",".gw",".gy",".hk",".hm",".hn",".hr",".ht",".hu",".id",".ie",".il",".im",
    ".in",".io",".iq",".ir",".is",".it",".je",".jm",".jo",".jp",".ke",".kg",".kh",".ki",".km",".kn",".kp",".kr",".kw",".ky",".kz",".la",".lb",
    ".lc",".li",".lk",".lr",".ls",".lt",".lu",".lv",".ly",".ma",".mc",".md",".mg",".mh",".mk",".ml",".mm",".mn",".mo",".mp",".mq",
    ".mr",".ms",".mt",".mu",".mv",".mw",".mx",".my",".mz",".na",".nc",".ne",".nf",".ng",".ni",".nl",".no",".np",".nr",".nu",
    ".nz",".om",".pa",".pe",".pf",".pg",".ph",".pk",".pl",".pm",".pn",".pr",".ps",".pt",".pw",".py",".qa",".re",".ro",".ru",".rw",
    ".sa",".sb",".sc",".sd",".se",".sg",".sh",".si",".sj",".sk",".sl",".sm",".sn",".so",".sr",".st",".su",".sv",".sy",".sz",".tc",".td",".tf",
    ".tg",".th",".tj",".tk",".tm",".tn",".to",".tp",".tr",".tt",".tv",".tw",".tz",".ua",".ug",".uk",".um",".us",".uy",".uz", ".va",".vc",
    ".ve",".vg",".vi",".vn",".vu",".wf",".ws",".ye",".yt",".yu",".za",".zm",".zr",".zw");

$w3cookie_domain = 'axew3.com';
//$w3cookie_domain = 'sub.mydomain.eu';
//$w3cookie_domain = 'tes.originalgangster.co.uk';
//$w3cookie_domain = 'sub3.sub2.sub1.example.co.uk';
//$w3cookie_domain = 'subdomain.example.co.uk';
//$w3cookie_domain = 'sub1.sub2.example.it';
//$w3cookie_domain = 'example.co.uk';

$count_dot = substr_count($w3cookie_domain, ".");

     if($count_dot >= 3){
      preg_match('/.*(\.)([-a-z0-9]+)(\.[-a-z0-9]+)(\.[a-z]+)/', $w3cookie_domain, $w3m0, PREG_OFFSET_CAPTURE);
      $w3cookie_domain = $w3m0[2][0].$w3m0[3][0].$w3m0[4][0];
   }

   $ckcd = explode('.',$w3cookie_domain);

  if(!in_array('.'.$ckcd[1], $w3domains)){
   $w3cookie_domain = preg_replace('/^[^\.]*\.([^\.]*)\.(.*)$/', '\1.\2', $w3cookie_domain);
  }

    $w3cookie_domain = '.' . $w3cookie_domain;

    echo $w3cookie_domain;

Upvotes: 0

steveo225
steveo225

Reputation: 11882

I found an answer and came up with the following solution that works most of the time, with the exception of 3 or less characters in domain name with a 2 character TLD (like www.ex.co):

$domain = false;
$host = parse_url('http://'.$_SERVER['SERVER_NAME'], PHP_URL_HOST);
if(preg_match('/([a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $host, $m)) {
    $domain = $m[1];
}

Upvotes: 1

You would use the $_SERVER['SERVER_NAME'] variable. It will return the host in which the script is being executed.

If you want a specific part you can use explode.

$temp = explode(".", $_SERVER['SERVER_NAME']);
$host = implode(".", ($temp[count($temp) - 1], $temp[count($temp) - 2]));

I do not recommend it, for instance a .co.uk domain would be caught incorrectly. You got the idea.

Upvotes: 0

Related Questions