Ways to Set a Cookie With PHP
The setcookie() function is the direct way to set a cookie with PHP.
Yet, sometimes it doesn't work.
Note: This article is for people who are comfortable working with cookies. If you need to learn more, a tutorial at the level you feel you are at might be found with a "HTTP cookie tutorial" search.
The most common reason setcookie() doesn't work, in my experience, is because setcookie() is called after some web page content has already been sent to the browser. The setcookie() function must be used before any web page content at all has been sent, while the PHP script is still in the process of sending header information.
"Header information" is information PHP sends to the browser before the web page content itself is sent. Examples of header information are the type of content that will be sent, the character set to use, cookies, and length of the content.
As a point of interest, most of the header content is sent automatically by PHP. However, some header information, like cookies, you have to be proactive about sending.
The PHP function SetCookieAbsolute() accompanying this article is a workaround for cases when a cookie must be set after some web page content has already been sent to the browser. It can be likened to an automatic relay — when the setcookie() function can't be used, it relays the task to JavaScript.
Here is an overview of how it works:
-
PHP function SetCookieAbsolute() determines whether or not PHP headers have already been sent.
-
If no, PHP will set the cookie via the header information still being sent to the browser.
-
If yes, PHP sends JavaScript code to the browser so the browser's JavaScript will set the cookie.
-
There are two reasons setting a cookie can fail that the PHP function SetCookieAbsolute() intentionally does not work around.
-
The cookie may require a secure HTTPS connection with the browser.
A secure connection is required by specifying the "secure" flag with the cookie information. The flag requires the cookie content to be encrypted so it can't be read while the data is traveling to and from the browser and the server.
If you specify the "secure" flag for a cookie and the browser is not on an HTTPS connection, the cookie won't be set. The PHP function SetCookieAbsolute() will not bypass a "secure" flag.
-
The cookie may require that it be read and set only through either an HTTP or HTTPS connection.
An HTTP(S)-only cookie sharing restriction can be implemented by specifying the "httponly" flag with the cookie information. It prevents JavaScript from reading and setting the cookie because JavaScript doesn't use HTTP or HTTPS for cookies.
The primary reason for specifying the "httponly" flag is to prevent a cross-site scripting (XSS) attack using the cookie.
If you specify the "httponly" flag, the cookie will either be set via the PHP header information or not be set at all. The PHP function SetCookieAbsolute() won't even try setting it via JavaScript when the cookie has an "httponly" flag. It is assumed you've specified the flag for a reason.
Cookies that must be accessed with JavaScript must not have the "httponly" flag. These would be any cookies that must be set or read by the browser.
There can be many reasons for requiring JavaScript to set and read cookies. Here are two examples:
- Updating content on the web page in response to user actions — clicking to reveal a div, selecting a language, any user action that is recorded in a cookie — so the same page can be restored if it is reloaded or returned to in the future.
- Carrying information from page to page that was collected with JavaScript. An example is the site visitor's geographical location based on their IP address. Another example is information the user provided earlier that may be used for pre-filling forms.
The "httponly" flag for a cookie is quite restrictive. Still, many consider it a best-practice when the cookie is not required to be accessed with JavaScript.
Using PHP Function SetCookieAbsolute()
In essence, you:
Paste the function SetCookieAbsolute() into your PHP code.
Call the function with details about the cookie you want to set.
Function SetCookieAbsolute() determines whether to set the cookie with PHP or with JavaScript — with PHP if it can; otherwise with JavaScript.
First, I'll provide the source code for function SetCookieAbsolute(). Then information about how to call it with details about the cookie you want to set.
The Function SetCookieAbsolute() Source Code
Put this PHP function SetCookieAbsolute() source code with any other PHP code on your web page. Paste it in as is; no customization required.
function SetCookieAbsolute( $cookie = array('name'=>'testing','value'=>'test value') ) { /* June 22, 2018. Will Bontrager Software LLC. https://www.willmaster.com/ */ $cookie['name'] = preg_replace('/[^\w\_]/','',$cookie['name']); if( empty($cookie['name']) or empty($cookie['value']) ) { return; } if( isset($cookie['expire']) and empty($cookie['expires']) ) { $cookie['expires'] = $cookie['expire']; } if( isset($cookie['domain']) and substr_count($cookie['domain'],'.') < 2 ) { $cookie['domain'] = ".{$cookie['domain']}"; } if( headers_sent() and empty($cookie['httponly']) ) { $cookie['value'] = str_replace("'","\\'",$cookie['value']); echo "<script>\nvar cookieline = encodeURIComponent('{$cookie['name']}');"; echo "\ncookieline += '=';"; echo "\ncookieline += encodeURIComponent('{$cookie['value']}');"; if( isset($cookie['expires']) ) { $expiration = (preg_replace('/ [\-\+]\d+$/','',gmdate('r',$cookie['expires']))) . ' GMT'; echo "\ncookieline += '; expires=$expiration';"; } if( isset($cookie['path']) ) { echo "\ncookieline += '; path={$cookie['path']}';"; } if( isset($cookie['domain']) ) { echo "\ncookieline += '; domain={$cookie['domain']}';"; } if( isset($cookie['secure']) and $cookie['secure'] ) { echo "\ncookieline += '; secure';"; } echo "\ndocument.cookie = cookieline;\n</script>"; } else { if( empty($cookie['path']) ) { $cookie['path'] = ''; } if( empty($cookie['expire']) ) { $cookie['expire'] = 0; } if( empty($cookie['domain']) ) { $cookie['domain'] = ''; } $cookie['secure'] = ( isset($cookie['secure']) and $cookie['secure'] ) ? 'secure' : false; $cookie['httponly'] = ( isset($cookie['httponly']) and $cookie['httponly'] ) ? 'HttpOnly' : false; setcookie($cookie['name'],$cookie['value'],$cookie['expire'],$cookie['path'],$cookie['domain'],$cookie['secure'],$cookie['httponly']); } } # function SetCookieAbsolute()
When the PHP function SetCookieAbsolute() is on your web page, you're ready to use it.
Using SetCookieAbsolute()
In the examples, I'll be using a PHP array variable named $MyCookie
. The array name could be any other valid PHP array name. If you use a different array name for your application, change the example code accordingly.
The $MyCookie
array is used to specify various values for the cookie. Example:
$MyCookie = array(); $MyCookie['name'] = "testing_name"; $MyCookie['value'] = "I'm testing a cookie :)"; SetCookieAbsolute($MyCookie);
On the first line, the array is initialized. It guarantees that $MyCookie contains no values at that point. It's done this way in case you've used $MyCookie
for other cookies and it might still contain information from that use.
On the next two lines of the example, a cookie name and a cookie value are specified, a name testing_name
and a value I'm testing a cookie :)
.
On the last line, function SetCookieAbsolute() is called with the $MyCookie
array. It sets a cookie named "testing_name" with a "I'm testing a cookie :)" value.
Other information for the cookie can also be specified so long as they follow the $MyCookie = array();
line and precede the SetCookieAbsolute($MyCookie);
line. In between those two lines, the information can be specified in any order.
Here is an example that specifies every type of information it is possible to specify for a cookie. All but the cookie name and the cookie value are optional.
$MyCookie = array(); $MyCookie['name'] = "testing_name"; $MyCookie['value'] = "I'm testing a cookie :)"; $MyCookie['expires'] = time() + (24*60*60); // to expire in 24 hours. $MyCookie['domain'] = ".example.com"; $MyCookie['httponly'] = true; $MyCookie['secure'] = true; $MyCookie['path'] = '/'; SetCookieAbsolute($MyCookie);
The original Netscape cookie specification talks about the various types of information that can be set with cookies — except the httponly flag, a feature that was added by browsers at a later date.
Specify the cookie information you require for the cookie you are setting. Then function SetCookieAbsolute() sets the cookie with PHP or with JavaScript.
(This article first appeared in Possibilities newsletter.)
Will Bontrager