【问题标题】:Storing PHP arrays in cookies在 cookie 中存储 PHP 数组
【发布时间】:2012-02-20 08:47:24
【问题描述】:

在 cookie 中存储数组的正确方法是什么?在 PHP 中 代码示例:

$number_ticket=2;
$info[7][5]=1;
$info[8][5]=1;

【问题讨论】:

    标签: php arrays cookies


    【解决方案1】:

    要将数组值存储在cookie中,首先需要将它们转换为字符串,所以这里有一些选项。

    将 cookie 存储为 JSON

    存储代码

    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.

    【讨论】:

    • 这应该是正确的答案。感谢您考虑安全性并提供参考。 +1
    • 很好的答案,谢谢。我发现你需要在json_decode() 之前stripslashes() cookie 值。
    • @hobailey 很棒的评论!我已经工作了几个小时,为什么我的代码在 PHP 变量上工作时不能与 json 编码的 cookie 一起工作!?!原因是您确实需要在 json_decode() 之前添加 stripslashes()。在 PHP 数组中获取 json 编码 cookie 的示例代码:json_decode(stripslashes($_COOKIE['mycookie']), true);
    • 只有在打开了魔术行情时才需要使用带斜杠。 fyl magic Quotes 自 PHP 5.3.0 起已弃用,自 PHP 5.4.0 起已删除。
    • explode/implode 帮助我解决了我的问题。谢谢 这应该被接受为正确答案,因为它可能涵盖了所有可能的解决方案。
    【解决方案2】:

    序列化数据:

    setcookie('cookie', serialize($info), time()+3600);
    

    然后反序列化数据:

    $data = unserialize($_COOKIE['cookie'], ["allowed_classes" => false]);
    

    data 之后,$info 和 $data 将具有相同的内容。

    【讨论】:

    • 不推荐使用序列化,因为可能存在安全漏洞。 (php.net/manual/en/function.setcookie.php -> 备注)
    • 确实,请不要在用户提交的数据上使用unserialize。这很容易通过使用 PHP 的 __wakeup 和 __destruct 方法的对象注入来利用。您可以使用json_encode/json_decode 代替serialize/unserializeowasp.org/index.php/PHP_Object_Injection
    • 对我不起作用,我通过对文件的发布请求进行了尝试,并尝试将输出的数组作为响应返回,但什么也没有返回。
    • @Black 我添加了适用于大量数据的答案。
    【解决方案3】:

    对 cookie 使用序列化和反序列化存在安全风险。用户(或攻击者)可以更改 cookie 数据,然后当您反序列化它时,它可以在您的服务器上运行 PHP 代码。不应信任 Cookie 数据。请改用 JSON!

    来自PHP's site

    无论allowed_classesoptions 值如何,都不要将不受信任的用户输入传递给unserialize()。由于对象实例化和自动加载,反序列化可能导致代码被加载和执行,恶意用户可能会利用这一点。如果您需要将序列化数据传递给用户,请使用安全、标准的数据交换格式,例如 JSON(通过 json_decode()json_encode())。

    【讨论】:

      【解决方案4】:

      试试serialize()。它将数组转换为字符串格式,然后您可以使用unserialize() 将其转换回数组。像 WordPress 这样的脚本使用它来将多个值保存到单个数据库字段中。

      您也可以像 Rob 所说的那样使用json_encode(),如果您想在 javascript 中读取 cookie,这可能很有用。

      【讨论】:

        【解决方案5】:

        Cookie 基本上是文本,因此您可以通过将数组编码为 JSON 字符串来存储数组(请参阅json_encode)。请注意,您可以存储的字符串长度是有限制的。

        【讨论】:

          【解决方案6】:

          您也可以尝试在不同的 cookie 中写入不同的元素。 cookie 名称可以设置为数组名称,并且可以作为数组提供给您的 PHP 脚本,但单独的 cookie 存储在用户的系统中。考虑explode() 来设置一个具有多个名称和值的cookie。不建议为此目的使用 serialize(),因为它可能会导致安全漏洞。查看setcookiePHP函数了解更多详情

          【讨论】:

            【解决方案7】:

            刚刚找到需要的东西。现在,我可以将访问过的产品存储在 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";
                }
            }
            

            【讨论】:

              【解决方案8】:

              最近我为我的客户创建了这段代码,我在这段代码中使用数组作为 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>";
              } 
              }
              

              【讨论】:

                【解决方案9】:

                只有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 );
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-07-08
                  • 1970-01-01
                  • 2011-07-03
                  • 2012-11-16
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多