note 94390 modified in function.setcookie by danbrown
| From: | danbrown@php.net | Date: | Mon, 02 Nov 2009 15:28:33 +0000 |
| Subject: | note 94390 modified in function.setcookie by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-162332@lists.php.net to get a copy of this message | ||
The server my php code is running on has sessions disabled so I am forced to store a fair bit of
arbitrary data in cookies. Using array names was impractical and problematic, so I implemented a
splitting routine. I do not serialize any class instances, just arrays and simple objects.
In a nutshell, when setting a cookie value, I serialize it, gzcompress it, base64 encode it, break
it into pieces and store it as a set of cookies. To fetch the cookie value I get the named piece
then iterate through piece names rebuilding the base64 data, then reverse the rest of the process.
The only other trick is deleting the pieces correctly.
Sessions are better, but if they are not available this is a viable alternative. I chose gz over bz
for compression because it looked faster with only slightly worse ratios.
Here is a simplified version of my implementation. This is a good starting point but is not
suitable for most uses. For example, the domain and path are hard coded and no return values are
checked for validity.
<?php
define( 'COOKIE_PORTIONS' , '_piece_' );
function clearpieces( $inKey , $inFirst ) {
$expire = time()-3600;
for ( $index = $inFirst ; array_key_exists( $inKey.COOKIE_PORTIONS.$index , $_COOKIE ) ; $index +=
1 ) {
setcookie( $inKey.COOKIE_PORTIONS.$index , '' , $expire , '/' , '' ,
0 );
unset( $_COOKIE[$inKey.COOKIE_PORTIONS.$index] );
}
}
function clearcookie( $inKey ) {
clearpieces( $inKey , 1 );
setcookie( $inKey , '' , time()-3600 , '/' , '' , 0 );
unset( $_COOKIE[$inKey] );
}
function storecookie( $inKey , $inValue , $inExpire ) {
$decode = serialize( $inValue );
$decode = gzcompress( $decode );
$decode = base64_encode( $decode );
$split = str_split( $decode , 4000 );//4k pieces
$count = count( $split );
for ( $index = 0 ; $index < $count ; $index += 1 ) {
$result = setcookie( ( $index > 0 ) ? $inKey.COOKIE_PORTIONS.$index : $inKey , $split[$index] ,
$inExpire , '/' , '' , 0 );
}
clearpieces( $inKey , $count );
}
function fetchcookie( $inKey ) {
$decode = $_COOKIE[$inKey];
for ( $index = 1 ; array_key_exists( $inKey.COOKIE_PORTIONS.$index , $_COOKIE ) ; $index += 1 ) {
$decode .= $_COOKIE[$inKey.COOKIE_PORTIONS.$index];
}
$decode = base64_decode( $decode );
$decode = gzuncompress( $decode );
return unserialize( $decode );
}
?>
--was--
The server my php code is running on has sessions disabled so I am forced to store a fair bit of
arbitrary data in cookies. Using array names was impractical and problematic, so I implemented a
splitting routine. I do not serialize any class instances, just arrays and simple objects.
In a nutshell, when setting a cookie value, I serialize it, gzcompress it, base64 encode it, break
it into pieces and store it as a set of cookies. To fetch the cookie value I get the named piece
then iterate through piece names rebuilding the base64 data, then reverse the rest of the process.
The only other trick is deleting the pieces correctly.
Sessions are better, but if they are not available this is a viable alternative. I chose gz over bz
for compression because it looked faster with only slightly worse ratios.
Here is a simplified version of my implementation. This is a good starting point but is not
suitable for most uses. For example, the domain and path are hard coded and no return values are
checked for validity.
define( 'COOKIE_PORTIONS' , '_piece_' );
function clearpieces( $inKey , $inFirst ) {
$expire = time()-3600;
for ( $index = $inFirst ; array_key_exists( $inKey.COOKIE_PORTIONS.$index , $_COOKIE ) ; $index +=
1 ) {
setcookie( $inKey.COOKIE_PORTIONS.$index , '' , $expire , '/' , '' ,
0 );
unset( $_COOKIE[$inKey.COOKIE_PORTIONS.$index] );
}
}
function clearcookie( $inKey ) {
clearpieces( $inKey , 1 );
setcookie( $inKey , '' , time()-3600 , '/' , '' , 0 );
unset( $_COOKIE[$inKey] );
}
function storecookie( $inKey , $inValue , $inExpire ) {
$decode = serialize( $inValue );
$decode = gzcompress( $decode );
$decode = base64_encode( $decode );
$split = str_split( $decode , 4000 );//4k pieces
$count = count( $split );
for ( $index = 0 ; $index < $count ; $index += 1 ) {
$result = setcookie( ( $index > 0 ) ? $inKey.COOKIE_PORTIONS.$index : $inKey , $split[$index] ,
$inExpire , '/' , '' , 0 );
}
clearpieces( $inKey , $count );
}
function fetchcookie( $inKey ) {
$decode = $_COOKIE[$inKey];
for ( $index = 1 ; array_key_exists( $inKey.COOKIE_PORTIONS.$index , $_COOKIE ) ; $index += 1 ) {
$decode .= $_COOKIE[$inKey.COOKIE_PORTIONS.$index];
}
$decode = base64_decode( $decode );
$decode = gzuncompress( $decode );
return unserialize( $decode );
}
http://php.net/manual/en/function.setcookie.php