0

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

我已经尝试过的:

一、ArrayAccess 这个问题是服务器使用PHP 5.2.17&offsetGet()报错,无法通过引用返回,也就是无法实现多维元素访问:

$obj[$key1][$key2] = $value;

请注意,升级到较新的 PHP 版本目前不是一个选项

二、使用魔术方法 这有点棘手,但是当我尝试使用变量作为键时,我的问题就出现了。例如

$obj->$key1[$key2] = $value;

解释器首先评估$key1[$key2]抛出一个通知并返回 $key1 的第一个字符,并将其用作我数组上的键。这个我也不知道怎么解决。我曾想过使用方括号来强制操作优先级,但这与我下一次尝试的问题相同:

三、使用简单的 get 和 set 函数 再说一遍,旧的 PHP。当我尝试写作时它哭了:

$obj->get($key1)[$key2] = $value;

因为它不知道如何索引以圆括号结尾的表达式。

仍然有失策的选择:将数组公开并一起忘记 OO。但在我去那里之前,我想确定真的没有其他方法可以做到这一点。

4

2 回答 2

2

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

四。使用简单的 get 和 set 函数,但有多个参数:

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

或者

$quantity = $orderedQuantities($customerName, $orderNo, $productCode);

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

如果这是您的目标,只需将数组分配给 $obj,然后使用$obj->arrayprop[$key1][$key2]. 另一方面,如果您希望它表现得像一个对象,请完全跳过数组语法。

五、使用嵌套对象 所以使用同一个例子,你可以写一个客户对象(一种集合),它嵌入了订单对象等。

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

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

$customer = $customers->getCustomerByName($customerName); $order = $customer->getOrder($orderNo); $orderLine= $order->getOrderLine($productCode); $数量 = $产品->数量;

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

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

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

总而言之,这种结构提供了很大的灵活性,尽管它一开始需要更多的输入和一点点习惯。

于 2012-12-03T02:28:39.780 回答
0

使用嵌套对象可以使 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
于 2012-12-03T04:03:30.783 回答