【问题标题】:Multidimensional arrays in class with __set and __get具有 __set 和 __get 的类中的多维数组
【发布时间】:2014-12-02 00:36:45
【问题描述】:

我正在尝试编写一个包装 $_SESSION 的简单类。 这个想法是,我将能够从引用 $_SESSION 变量的类中设置和获取值,让 __set 和 __get 执行我需要的其他一些东西。

我目前拥有的,远未完成:

class Session 
{
    // Property declarations
    public $data = array();

    /**
     * Class initialization
     */
    public function __construct() 
    {       
        if (!session_id()) {
            ini_set('session.cookie_lifetime', 0);
            ini_set('session.gc-maxlifetime', 0);

            session_start();
        }

        $this->data =& $_SESSION;
    }

    /**
     * Get session ID
     * @return string 
     */
    public function getId() 
    {
        return session_id();
    }
}

我正在尝试使其工作如下:

$session->images['directory'] = 1;

将与

相同
$_SESSION['images']['directory'] = 1;

echo $session->images['directory'];

应该依次输出:1

关键是,我想使用多维数组,如下所示:

$session->images['foo']['bar'] = 'works';

对于 SO 和 php.net 的许多示例中提供的常规 __set 和 __get 函数,这不起作用。

当然,在页面重新加载/导航之后,我将能够使用它们各自的值访问相同的变量。

我尝试的是搜索 Google 和 Stackoverflow,我一直在“ArrayAcces”上登陆,但似乎无法弄清楚如何使用它来解决我的问题。

有人指出我正确的方向吗?

【问题讨论】:

  • php.net/manual/en/language.oop5.overloading.php#object.get :示例 1 中的代码正是您所需要的。您只需要添加您编写的构造函数即可。
  • @SergiuParaschiv 恐怕这行不通,我应该注意到我想要多维数组,所以使用该解决方案, $session->images['foo']['bar'] = '没有';不会工作。
  • @Milanzor ArrayAccess 以不同的方式工作。有对象,但可以访问数组。
  • 你已经链接了一个我之前已经检查过的问题/答案,但它似乎仍然不是我的解决方案。

标签: php arrays class session multidimensional-array


【解决方案1】:

我知道这已经存在了很长一段时间 - 但这是你的答案。

最初我认为您必须使用递归。但后来我想起 PHP 做了一个引用指针。于是我去查找了PHP在线文档中的信息:

http://php.net/manual/en/language.references.php

这让我尝试了一些事情,我想出了以下内容。现在,我使用了 in() 和 out(),因为我没有使用 __set 和 __get 进行测试。我只是想让它工作。所以这里有两个函数:

public function in( $v, $d )
{
    $v = $this->get_id( $v );
    $a = explode( ".", $v );
    $b = &$this->info;
    foreach( $a as $k=>$v ){
        if( !isset($b[$v]) ){ $b[$v] = array(); $b = &$b[$v]; }
           else { $b = &$b[$v]; }
        }

    $b = $d;
    return true;
}
public function out( $v )
{
    $v = $this->get_id( $v );
    $a = explode( ".", $v );
    $b = &$this->info;
    foreach( $a as $k=>$v ){
        if( isset($b[$v]) ){ $b = &$b[$v]; }
            else { return false; }
        }

    return $b;
}

我用 in("this.is.a.test", 5) 和 out("this.is.a.test") 测试了上面的代码。这产生了以下输出:

In: 1
Out: 5
Array
(
    [cleric] => Array
        (
            [this] => Array
                (
                    [is] => Array
                        (
                            [a] => Array
                                (
                                    [test] => 5
                                )

                        )

                )

        )

)

(是的 - 我正在开发一个 D&D 程序来为我跟踪角色。)

我在上面设置了“牧师”前缀,我在其中执行了 IN 和 OUT 功能。所以第一行(“牧师”)来自前缀。 :-)

无论如何,这比使用递归执行此操作要快很多。我希望这有帮助。 :-) 或者,如果您已经从 CakePHP 中得到答案 - 那也很棒! :-)

【讨论】:

  • 大约 2.5 年前我问过这个问题,从那时起我学到了一些东西,魔术 _set 和 _get 也将是我对自己问题的回答。我在 CakePHP 中找到了这种用法的好例子,但所有其他框架都有类似的类。感谢您的努力!
  • 我正在修改我的答案。我找到了一种快速简便的方法,您可以在 __set 和 __get 函数中使用它。请参阅我修改后的答案。
猜你喜欢
  • 1970-01-01
  • 2011-03-07
  • 2010-12-09
  • 1970-01-01
  • 2016-06-09
  • 2011-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多