PHP:修改多维数组干净的方式? [英] PHP: Cleanest way to modify multidimensional array?

查看:147
本文介绍了PHP:修改多维数组干净的方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序,它加载静态配置设置,并将其解析为阵列有一个配置类。结果
当我需要重写运行时的一些元素,我需要做这个访问里面的配置级公共变量; 组$ config->值['ONELEVEL'] ['twolevel'] ='改为';

I've got a Config class in my application, which loads static config settings and parses them into arrays.
As I need to override some elements during runtime, I would need to access the public variable inside the Config-class by doing this; $config->values['onelevel']['twolevel'] = 'changed';

我想提出一个名为重写方法,这是否适合我,但我不能让我的身边会是什么做到这一点的最佳途径头我的配置文件可能会在未来的嵌套级别的未知量。

I would like to make a method that is called override that does this for me, but I cant get my head around what would be the best way to do it as my config files may get unknown amount of nested levels in the future.

这将是可爱的做类似组$ config-> onelevel-> twolevel ='改为',让__set魔术方法采取筑巢的照顾,但是从我所知道的,这是不可能的。

It would be lovely to do something like $config->onelevel->twolevel = 'changed' and let the __set magic method take care of the nesting, but from what I can tell, it isn't possible.

什么是做到这一点的最好方法是什么?

What would be the best way to do this?

推荐答案

这是可以做到你想做的。

It is possible to do what you want.

这例子是大量迁入由<一个启发href=\"http://framework.zend.com/$c$c/filedetails.php?repname=Zend%20Framework&path=/trunk/library/Zend/Config.php\">Zend_Config在对了ArrayAccess接口中的P​​HP文件中给出的例子。

This example is largly inspired by Zend_Config and the example given in the PHP docs on the ArrayAccess interface.

编辑:结果
<击>只有一个小的警告:你需要调用的toArray()上的数据重新presenting一个数组,将其转换为一个数组,作为类的内部需求隐蔽阵列数据自身的实例,以便与对象属性操作员访问 - &GT;

edit:
With one minor caveat: you need to call toArray() on data representing an array, to convert it to an array, as the class internally needs to covert array data to an instance of itself, to allow access with the object property operator ->:

呃,这是不是真的有必要了,当然,因为它现在实现了ArrayAccess。 ;-)结果
/修改

Eh, that's not really necessary anymore of course, since it implements ArrayAccess now. ;-)
/edit

class Config
    implements ArrayAccess
{
    protected $_data;

    public function __construct( array $data )
    {
        foreach( $data as $key => $value )
        {
            $this->$key = $value;
        }
    }

    public function __get( $key )
    {
        return $this->offsetGet( $key );
    }

    public function __isset( $key )
    {
        return $this->offsetExists( $key );
    }

    public function __set( $key, $value )
    {
        $this->offsetSet( $key, $value );
    }

    public function __unset( $key )
    {
        $this->offsetUnset( $key );
    }

    public function offsetSet( $offset, $value )
    {
        $value = is_array( $value ) ? new self( $value ) : $value;

        if( is_null( $offset ) )
        {
            $this->_data[] = $value;
        }
        else
        {
            $this->_data[ $offset ] = $value;
        }
    }

    public function offsetExists( $offset )
    {
        return isset( $this->_data[ $offset ] );
    }

    public function offsetUnset( $offset )
    {
        unset( $this->_data[ $offset ] );
    }

    public function offsetGet( $offset )
    {
        return isset( $this->_data[ $offset ] ) ? $this->_data[ $offset ] : null;
    }

    public function toArray()
    {
        $array = array();
        $data = $this->_data;
        foreach( $data as $key => $value )
        {
            if( $value instanceof Config )
            {
                $array[ $key ] = $value->toArray();
            }
            else
            {
                $array[ $key ] = $value;
            }
        }
        return $array;
    }
}

编辑2:结果
配置类,甚至可以极大地延长 ArrayObject的简化。作为一个额外的好处,你可以将它转换为一个适当的阵列也。

edit 2:
The Config class can even be greatly simplified by extending ArrayObject. As an added benefit, you can cast it to a proper array also.

class Config
    extends ArrayObject
{
    protected $_data;

    public function __construct( array $data )
    {
        parent::__construct( array(), self::ARRAY_AS_PROPS );
        foreach( $data as $key => $value )
        {
            $this->$key = $value;
        }
    }

    public function offsetSet( $offset, $value )
    {
        $value = is_array( $value ) ? new self( $value ) : $value;

        return parent::offsetSet( $offset, $value );
    }
}

实例:

$configData = array(
    'some' => array(
        'deeply' => array(
            'nested' => array(
                'array' => array(
                    'some',
                    'data',
                    'here'
                )
            )
        )
    )
);
$config = new Config( $configData );
// casting to real array
var_dump( (array) $config->some->deeply->nested->array );

$config->some->deeply->nested->array = array( 'new', 'awsome', 'data', 'here' );
// Config object, but still accessible as array
var_dump( $config->some->deeply->nested->array[ 0 ] );

$config[ 'some' ][ 'deeply' ][ 'nested' ][ 'array' ] = array( 'yet', 'more', 'new', 'awsome', 'data', 'here' );
var_dump( $config[ 'some' ][ 'deeply' ][ 'nested' ][ 'array' ] );

$config[ 'some' ][ 'deeply' ][ 'nested' ][ 'array' ][] = 'append data';
var_dump( $config[ 'some' ][ 'deeply' ][ 'nested' ][ 'array' ] );

var_dump( isset( $config[ 'some' ][ 'deeply' ][ 'nested' ][ 'array' ] ) );

unset( $config[ 'some' ][ 'deeply' ][ 'nested' ][ 'array' ] );
var_dump( isset( $config[ 'some' ][ 'deeply' ][ 'nested' ][ 'array' ] ) );

// etc...

这篇关于PHP:修改多维数组干净的方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆