Link to home
Start Free TrialLog in
Avatar of MacLean Fitzgerald
MacLean FitzgeraldFlag for United States of America

asked on

PHP and cookies

In PHP I want to set a cookie and have it look at the URL and store parameters in the cookie.

I can then retrieve this data later.

For example...

my URL would look like this:
www.example.com?lead_id=email-annouce-es&utm_source=annouce&utm_medium=email&utm_campaign=es

I would love to be able to extract the "email-annouce-es" from the lead_id and store in the cookie.

Any help would be appreciated.
SOLUTION
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of MacLean Fitzgerald

ASKER

I should have been more specific.  Im going to be adding this to all my webpages.  I need to look at the current URL, not a hardcoded one.  Im trying to extract that data, as you have done above, and store in the cookie.  I want it to read the browser URL.  Does that make sense?
Sure, it makes sense.  Please read the man page here to see how they choose the value of $_SERVER['QUERY_STRING'] in place of the $qry variable in my example above.
http://php.net/manual/en/function.parse-str.php

You may also want to understand this part:
http://php.net/manual/en/language.variables.external.php

PHP is remarkably self-aware.  This is one of the tools you can use to see what PHP knows about  its own installation and environment.
http://php.net/manual/en/function.phpinfo.php

And when dealing with cookies, post-request variables and other "invisible" data, your best friends in the world are var_dump() and var_export()
Im still not getting it.  I read the main page you recommended.  I ended up with this:
error_reporting(E_ALL);

$url = $_SERVER['QUERY_STRING'];

// PARSE THE URL
$qry = parse_url($url);

// PARSE THE QUERY STRING
parse_str($qry['query'], $args);

// SET A COOKIE WITH THE LEAD-ID INFORMATION
setcookie
( 'macattack2'           // COOKIE NAME
, $args['lead_id']    // COOKIE VALUE
, time() + 60*60*24   // COOKIE LIFE
, DIRECTORY_SEPARATOR // ENTIRE DOMAIN IS IN PLAY
, NULL                // NO SUBDOMAINS
, FALSE               // NO HTTPS RESTRICTIONS
, TRUE                // NO JAVASCRIPT
)
;

It does not seem to work.
It does not seem to work.
Often PHP scripts give messages or other symptoms showing what they did or did not do.  These are useful when you're trying to diagnose and correct errors.  Here are the kinds of things I would look for:

1. What does var_dump($args) show?
2. What does phpinfo() show for the values in $_SERVER?
3. What does Google Chrome console show for the information in the cookies?
4. Why do you think "it does not seem to work?"  What is the expectation and the dissonant result?
Ok.  I have been futzing with this for a few days to no avail.

To answer your 4 questions above.

1. when I print var_dump I get this:  array(0) { }
2. There are lots of values for $_SERVER in phpinfo, which one specifically?
3. Funny thing, the cookie only appears in Chrome, not Firefox or Safari.  Yet when looking at cookie, its empty.  See attachment.
4. I'm not sure.

<?php
error_reporting(E_ALL);
$url = $_SERVER["HTTP_REFERER"];
// PARSE THE URL
$qry = parse_url($url);
// PARSE THE QUERY STRING
parse_str($qry['query'], $args);
// SET A COOKIE WITH THE LEAD-ID INFORMATION
setcookie
( '_strop'           // COOKIE NAME
, $args['lead_id']    // COOKIE VALUE
, time() + 60*60*24   // COOKIE LIFE
)
; 
}
?>

Open in new window

Screen-Shot-2015-08-21-at-12.43.06-PM.pn
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
1. My first guess is that the $url variable on line 3 is wrong.  I think this should be assigned like so:
$_SERVER['QUERY_STRING']

2. You can look at the variables in the output of phpinfo() and check the QUERY_STRING, but you will have to include URL arguments in the URL of the script that runs phpinfo() so you can see these.

I can't guess at how you might find a cookie in Chrome but not in FF or Safari.  If the cookies are being done correctly they will be set in all the browsers, unless your personal browser settings deny cookies.

You might want to avoid using a leading underscore for your cookie names.  This is likely to conflict with frameworks or PHP definitions.  I put the leading underscore into the category of "just don't do that."

Very surprised you did not get a message about an undefined index on line 11 - I would have thought that $args['lead_id'] did not exist because the $url variable did not point to a query string.  Also surprised that line 15 did not cause a parse error.  Are you sure you posted the same script you used to test?

If you're new to PHP and want to get a good foundation in how the language works, this article can help you find dependable learning resources.
https://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_11769-And-by-the-way-I-am-new-to-PHP.html

Here's my teaching example script showing how to take HTML form input and set a cookie.  You can install it and run it to see it in action - the comments will tell you what the program is doing at each step of the process.  You would not want to leave this on your server because it is a security exposure, but for learning purposes it may be helpful.

<?php // cookie_example.php
/**
 * THIS SCRIPT RECEIVES INPUT FROM AN HTML FORM AND SETS A COOKIE WITH THE NAME, VALUE AND LIFE FROM THE FORM
 *
 * MAN PAGE: http://php.net/manual/en/function.setcookie.php
 *
 * TO SEE COOKIES IN FIREFOX, FOLLOW SOMETHING LIKE THIS:
 * => TOOLS
 * => OPTIONS
 * => PRIVACY
 * => SHOW COOKIES
 */
error_reporting(E_ALL);

// IF THE FORM HAS BEEN POSTED
if (!empty($_POST))
{
    // TIDY UP THE POST INPUT - CLEAN AND NOT MORE THAN 16 BYTES
    $name = substr(clean_string($_POST["name"]),0,16);
    $data = substr(clean_string($_POST["data"]),0,16);
    $life = clean_number($_POST["life"]);

    // BE SURE WE HAVE USEFUL INFORMATION
    if ( ($name == '') || ($data == '') ) die("MISSING INPUT: PLEASE <a href=\"{$_SERVER['PHP_SELF']}\">TRY AGAIN</a>");


    // CHOOSE THE COOKIE NAME, VALUE, AND LIFE IN SECONDS
    $cookie_name    = $name;
    $cookie_value   = $data;
    $cookie_life    = $life;


    // CONFIGURE THE COOKIE LIFE
    if ($life <= 0)
    {
        // USE THIS TO MAKE COOKIE EXPIRE AT END OF BROWSER LIFE
        $cookie_expires = 0;
    }
    else
    {
        // USE THIS TO MAKE A PERSISTENT COOKIE
        $cookie_expires = time() + $cookie_life;
    }


    // MAKE THE COOKIE AVAILABLE TO ALL DIRECTORY PATHS
    $cookie_path	= DIRECTORY_SEPARATOR;


    // MAKE THE COOKIE AVAILABLE TO ALL SUBDOMAINS - DOMAIN NAME STARTS WITH DOT AND OMITS WWW (OR OTHER SUBDOMAINS).
    $x = explode('.', strtolower($_SERVER["HTTP_HOST"]));
    $y = count($x);
    if ($y == 1) // MAYBE 'localhost'?
    {
        $cookie_domain = $x[0];
    }
    else // SOMETHING LIKE 'www2.atf70.whitehouse.gov'?
    {
        // USE THE LAST TWO POSITIONS TO MAKE THE HOST DOMAIN
        $cookie_domain = '.' . $x[$y-2] . '.' . $x[$y-1];
    }


    // MAKE THE COOKIE AVAILABLE TO HTTP, NOT JUST HTTPS
    $cookie_secure    = FALSE;


    // HIDE COOKIE FROM JAVASCRIPT (PHP 5.2+)
    $cookie_http      = TRUE;


    // SET THE COOKIE
    if ( setcookie
    ( $cookie_name
    , $cookie_value
    , $cookie_expires
    , $cookie_path
    , $cookie_domain
    , $cookie_secure
    , $cookie_http
    )
    )
    {
        echo PHP_EOL . "<br/>SUCCESS!  THE COOKIE HAS BEEN SET AND WILL BE AVAILABLE TO THE NEXT PAGE LOAD";
    }
    else
    {
        echo PHP_EOL . "<br/>FAILURE!  THE COOKIE WAS NOT SET AS EXPECTED";
    }


    /**
     * AT THIS POINT, THE COOKIE HAS BEEN SET, BUT IT IS NOT AVAILABLE IN THIS SCRIPT
     * THE COOKIE WILL NOT BE RETURNED FROM THE CLIENT TO THE SERVER UNTIL THE NEXT HTTP REQUEST
     * THIS IS BECAUSE THE BROWSER SENDS THE COOKIE TO THE SERVER BEFORE OUR SCRIPT STARTS RUNNING
     */
    echo '<pre>';
    echo PHP_EOL . '$_COOKIE CONTAINS '; var_dump($_COOKIE);
    echo PHP_EOL . '$_POST CONTAINS ';   var_dump($_POST);
    echo PHP_EOL . 'THE COOKIE HAS BEEN SET WITH THESE VALUES: ';
    echo PHP_EOL . 'COOKIE NAME:    ' . $cookie_name;
    echo PHP_EOL . 'COOKIE VALUE:   ' . $cookie_value;
    echo PHP_EOL . 'COOKIE EXPIRES: ' . number_format($cookie_expires) . " == " . date('r', $cookie_expires);
    echo PHP_EOL . 'COOKIE PATH:    ' . $cookie_path;
    echo PHP_EOL . 'COOKIE DOMAIN:  ' . $cookie_domain;
    echo PHP_EOL . 'COOKIE SECURE:  '; var_dump($cookie_secure);
    echo           'COOKIE HTTP:    '; var_dump($cookie_http);
    echo "</pre>";
}



/**
 * END OF THE ACTION SCRIPT THAT SET THE COOKIE
 * CREATE THE HTML FORM, USING PHP HEREDOC NOTATION
 */
$self = $_SERVER["PHP_SELF"];
$form = <<<ENDFORM
<pre>
<form method="post">
COOKIE NAME: <input name="name" /> STRING
COOKIE DATA: <input name="data" /> STRING
COOKIE LIFE: <input name="life" /> INTEGER SECONDS
<input type="submit" />
<b>TO SEE THE EXISTING COOKIES <a href="$self">CLICK HERE</a></b>
</form>
</pre>
ENDFORM;
echo $form;


// SHOW THE COOKIE ARRAY, IF ANY
echo '<pre>$_COOKIE CONTAINS '; var_dump($_COOKIE); echo "</pre>";



// UNRELATED FUNCTIONS TO TIDY UP FORM INPUT
function clean_string($string)
{
    return trim(preg_replace('/[^A-Z0-9_]/i', NULL, $string));
}

function clean_number($string)
{
    return trim(preg_replace('/[^0-9-]/i',     0,    $string));
}

// ACTIVATE THIS TO SHOW THE SCRIPT CODE
// die( highlight_file(__FILE__, TRUE) );

Open in new window

Ray helped me get started, and then separately I was able to get the final solution.