【发布时间】:2012-02-20 08:47:24
【问题描述】:
在 cookie 中存储数组的正确方法是什么?在 PHP 中 代码示例:
$number_ticket=2;
$info[7][5]=1;
$info[8][5]=1;
【问题讨论】:
在 cookie 中存储数组的正确方法是什么?在 PHP 中 代码示例:
$number_ticket=2;
$info[7][5]=1;
$info[8][5]=1;
【问题讨论】:
要将数组值存储在cookie中,首先需要将它们转换为字符串,所以这里有一些选项。
存储代码
setcookie('your_cookie_name', json_encode($info), time()+3600);
阅读代码
$data = json_decode($_COOKIE['your_cookie_name'], true);
如果您需要在前端使用 JavaScript 读取 cookie,也可以选择 JSON。
实际上,您可以使用任何 encrypt_array_to_string/decrypt_array_from_string 方法组将数组转换为字符串并将字符串转换回 same 数组。
例如,您还可以将explode/implode 用于整数数组。
来自 PHP.net
Do not pass untrusted user input to unserialize(). - 任何来自 HTTP 的东西,包括 cookie 都是不可信的!
与安全相关的参考资料
setcookie('my_array[0]', 'value1' , time()+3600);
setcookie('my_array[1]', 'value2' , time()+3600);
setcookie('my_array[2]', 'value3' , time()+3600);
如果你打印$_COOKIE变量之后,你会看到以下内容
echo '<pre>';
print_r( $_COOKIE );
die();
数组
(
[my_array] => 数组
(
[0] => 值1
[1] => 价值2
[2] => 价值3
)
)
这是记录在案的 PHP 功能。
来自 PHP.net
Cookies names can be set as array names and will be available to your PHP scripts as arrays but separate cookies are stored on the user's system.
【讨论】:
json_decode() 之前stripslashes() cookie 值。
序列化数据:
setcookie('cookie', serialize($info), time()+3600);
然后反序列化数据:
$data = unserialize($_COOKIE['cookie'], ["allowed_classes" => false]);
data 之后,$info 和 $data 将具有相同的内容。
【讨论】:
unserialize。这很容易通过使用 PHP 的 __wakeup 和 __destruct 方法的对象注入来利用。您可以使用json_encode/json_decode 代替serialize/unserialize。 owasp.org/index.php/PHP_Object_Injection
对 cookie 使用序列化和反序列化存在安全风险。用户(或攻击者)可以更改 cookie 数据,然后当您反序列化它时,它可以在您的服务器上运行 PHP 代码。不应信任 Cookie 数据。请改用 JSON!
来自PHP's site:
无论allowed_classes 的
options值如何,都不要将不受信任的用户输入传递给unserialize()。由于对象实例化和自动加载,反序列化可能导致代码被加载和执行,恶意用户可能会利用这一点。如果您需要将序列化数据传递给用户,请使用安全、标准的数据交换格式,例如 JSON(通过json_decode()和json_encode())。
【讨论】:
试试serialize()。它将数组转换为字符串格式,然后您可以使用unserialize() 将其转换回数组。像 WordPress 这样的脚本使用它来将多个值保存到单个数据库字段中。
您也可以像 Rob 所说的那样使用json_encode(),如果您想在 javascript 中读取 cookie,这可能很有用。
【讨论】:
Cookie 基本上是文本,因此您可以通过将数组编码为 JSON 字符串来存储数组(请参阅json_encode)。请注意,您可以存储的字符串长度是有限制的。
【讨论】:
您也可以尝试在不同的 cookie 中写入不同的元素。 cookie 名称可以设置为数组名称,并且可以作为数组提供给您的 PHP 脚本,但单独的 cookie 存储在用户的系统中。考虑explode() 来设置一个具有多个名称和值的cookie。不建议为此目的使用 serialize(),因为它可能会导致安全漏洞。查看setcookiePHP函数了解更多详情
【讨论】:
刚刚找到需要的东西。现在,我可以将访问过的产品存储在 cookie 中,并在它们返回网站时显示。
// set the cookies
setcookie("product[cookiethree]", "cookiethree");
setcookie("product[cookietwo]", "cookietwo");
setcookie("product[cookieone]", "cookieone");
// after the page reloads, print them out
if (isset($_COOKIE['product'])) {
foreach ($_COOKIE['product'] as $name => $value) {
$name = htmlspecialchars($name);
$value = htmlspecialchars($value);
echo "$name : $value <br />\n";
}
}
【讨论】:
最近我为我的客户创建了这段代码,我在这段代码中使用数组作为 cookie,实际上这段代码是用户使用 cookie 获取最近查看的页面,希望它对你有所帮助...!
function curPageURL() { // get url
return 'http' . ((
!empty($_SERVER['HTTPS']) &&
$_SERVER['HTTPS'] !== 'off' ||
$_SERVER['SERVER_PORT'] == 443
) ? 's' : '') . '://' . $_SERVER['SERVER_NAME'] . (
$_SERVER['SERVER_PORT'] == 80 ? '' : $_SERVER['SERVER_PORT']
) . $_SERVER['REQUEST_URI'];
}
$currentPage = curPageURL(); // call function
$counter = $_COOKIE['_counter']; // set counter variable
if(!$_COOKIE['_PAGES']){ // if _Pages cookie
$default = 1; // set default value to 1
setcookie("_counter",$default,time()+7200); // set counter cookie
setcookie("_PAGES[$default]",$currentPage, time()+3600); // set cookie
}
else{ // if ! _Pages cookie
$default = $counter+1; // set default value to +1
setcookie("_counter",$default,time()+7200); // set counter cookie
}
if(@in_array($currentPage, @$_COOKIE['_PAGES'])){ // if same url found
}
else{ // if new url found
setcookie("_PAGES[$default]",$currentPage, time()+3600); // set cookie
}
if($_COOKIE['_PAGES']){
foreach ($_COOKIE['_PAGES'] as $value){
echo "<a href='{$value}'>{$value}</a>";
}
}
【讨论】:
只有this 决定帮助我将大量数据类型数组存储在 cookie 中。 奇迹般有效。谢谢 Eric,你拯救了我的一天。
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 );
}
【讨论】: