Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
php-多维数组包装器类_Php_Arrays_Oop_Multidimensional Array - Fatal编程技术网

php-多维数组包装器类

php-多维数组包装器类,php,arrays,oop,multidimensional-array,Php,Arrays,Oop,Multidimensional Array,我有一些数据表示为多维数组。我想将这些数据嵌入到我的OO应用程序中,并为这些数据提供额外的功能,但同时也提供了一种通过传统的随机访问和使用迭代器(因此我可以使用foreach)访问这些数据的方法。换句话说,我想为多维数组实现一个包装类 我已经尝试过的: I.阵列访问 这个问题是服务器使用PHP 5.2.17,并且&offsetGet()给出了一个错误,因此我无法通过引用返回,这意味着我无法实现多维元素访问: $obj[$key1][$key2] = $value; 请注意,升级到更新的PHP版

我有一些数据表示为多维数组。我想将这些数据嵌入到我的OO应用程序中,并为这些数据提供额外的功能,但同时也提供了一种通过传统的随机访问和使用迭代器(因此我可以使用foreach)访问这些数据的方法。换句话说,我想为多维数组实现一个包装类

我已经尝试过的:

I.阵列访问 这个问题是服务器使用PHP 5.2.17,并且
&offsetGet()
给出了一个错误,因此我无法通过引用返回,这意味着我无法实现多维元素访问:

$obj[$key1][$key2] = $value;
请注意,升级到更新的PHP版本目前不是一个选项

II。使用神奇的方法 这有点棘手,但当我尝试使用一个变量作为键时,问题就出现了。例如

$obj->$key1[$key2] = $value;
解释器首先计算抛出通知并返回$key1的第一个字符,并将其用作数组中的键。我也不知道怎么解决这个问题。我曾想过使用括号强制操作优先级,但这与我在下一次尝试中遇到的问题相同:

III.使用简单的get和set函数 还是老PHP。当我试着写的时候,它哭了:

$obj->get($key1)[$key2] = $value;
因为它不知道如何索引以圆括号结尾的表达式


还有一个选择:公开阵列,同时忘记OO。但在我开始之前,我想确定没有其他方法可以做到这一点。

有时候,最好用一个例子来说明。例如,您可以拥有一个多维数组,其中第一个索引定义客户,第二个索引定义订单,第三个索引定义产品。那么这个值就是数量

IV.使用简单的get和set函数,但具有多个参数:

$value = $obj->get($key1, $key2);
$obj->set($key1, $key2, $value);

编写对象包装器的本质是,它看起来像一个对象,行为也像这样。如果您实现它,使它的外观和行为类似于一个数组,那么您也可以使用一个数组。将数组封装在行为类似数组的对象中的唯一原因是,您可以通过引用传递它,而无需使用
&
参数

如果这是您的目标,只需将数组分配给$obj,并使用
$obj->arrayprop[$key1][$key2]
。另一方面,如果希望它的行为类似于对象,则完全跳过数组语法

V.使用嵌套对象 因此,使用相同的示例,您可以编写一个customers对象(类似于集合),它嵌入order对象,等等

$quantity=$customers->getCustomerByName($customerName)->getOrder($orderNo)->getProduct($productCode)->quantity

或者,为了使其更具可读性:

$customer=$customers->getCustomerByName($customerName); $order=$customer->getOrder($orderNo); $orderLine=$order->getOrderLine($productCode); $quantity=$product->quantity

现在,每个实体都由一个对象表示。其优点是,您可以使用额外的属性轻松地扩展此结构。您可以为客户集合提供“findByCustomerNo”和“findByName”方法来查找特定客户,还可以提供“filterByPostalCode”,它可以返回仅包含该邮政编码中的客户的新集合

$order现在可以包含计算总计的函数

$orderLine可能只包含productCode(键)和数量,但通过将其作为对象,您可以轻松添加折扣、自定义名称或说明或其他属性


总而言之,这种结构允许很大的灵活性,尽管它首先需要更多的键入和一点习惯。

使用嵌套对象可以使ArrayAccess工作,而无需传递引用。但是您可以完全忘记内置的数组函数

<?php
class ArrObj implements ArrayAccess {
    private $arr;

    public function __construct($arr = null) {
        $this->arr = $arr;
    }

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

    public function offsetGet($key) {
        return $this->arr[$key];
    }

    public function offsetSet($key, $val) {
        return $this->arr[$key] = $val;
    }

    public function offsetUnset($key) {
        unset($this->arr[$key]);
    }
}

$a = new ArrObj(array(
    'foo' => new ArrObj(array(
        'bar' => 'qwe'
    ))
));

echo $a['foo']['bar'] . '<br />';
$a['foo']['bar'] = 'asd';
echo $a['foo']['bar'] . '<br />';
?>

我的第一个想法是实现一个看起来和行为都像数组的对象,并添加了类似数组的功能。但事实证明,您无法在PHP5.2.17中实现类似于数组的东西。所以我试着保持“行为举止和外表有点像”的部分,至少是这样。但事实证明,你也不能真正做到这一点。谢谢你的回答,我想我会坚持用最直接的
$obj->arrayprop[$key1][$key2]
方法来做,我觉得这很难看,但是。。。无论什么我已经对PHP恨之入骨,不必在意。这就是我的精神(我非常同意)但是为了改变你的想法,我添加了
V.使用嵌套对象。
这个嵌套对象的东西实际上非常有效。不仅像你描述的那样,而且以一种通用的方式。使用嵌套对象解决了在I中通过引用传递的问题。因此ArrayAccess再次可用。我把我的密码作为答案。谢谢你给我指出了正确的方向:停止用一般的方式编程。我想我会扔掉我的代码,重新思考这个问题,把更多的精力放在手头的问题上,而不是将来使用它的所有可能的方法上。
<?php
class ArrObj implements ArrayAccess {
    private $arr;

    public function __construct($arr = null) {
        $this->arr = $arr;
    }

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

    public function offsetGet($key) {
        return $this->arr[$key];
    }

    public function offsetSet($key, $val) {
        return $this->arr[$key] = $val;
    }

    public function offsetUnset($key) {
        unset($this->arr[$key]);
    }
}

$a = new ArrObj(array(
    'foo' => new ArrObj(array(
        'bar' => 'qwe'
    ))
));

echo $a['foo']['bar'] . '<br />';
$a['foo']['bar'] = 'asd';
echo $a['foo']['bar'] . '<br />';
?>
qwe
asd