我有一些数据表示为多维数组。我想将这些数据嵌入到我的OO应用程序中,并为这些数据提供额外的功能,但也可以通过传统的随机访问和使用迭代器来访问它(因此我可以使用foreach)。换句话说,我想为多维数组实现一个包装类。
我已经尝试过:
予。了ArrayAccess
这个问题是服务器使用PHP 5.2.17并且&offsetGet()
给出错误,因此我不能通过引用返回,这意味着我无法实现多维元素访问:
$obj[$key1][$key2] = $value;
请注意,升级到较新的PHP版本目前不是一个选项
II。使用魔术方法 这有点棘手,但是当我尝试使用变量作为键时,我的问题就出现了。 E.g。
$obj->$key1[$key2] = $value;
解释器首先评估$key1[$key2]
抛出通知并返回$ key1的第一个字符,并将其用作我的数组的键。我也不知道如何解决这个问题。我想过使用括号来强制操作优先级,但这与我下次尝试时的问题相同:
III。使用简单的获取和设置功能 再次,老PHP。当我尝试写作时,它哭了:
$obj->get($key1)[$key2] = $value;
因为它不知道如何索引以圆括号结尾的表达式。
还有失去的度假选项:让阵列公开并忘记OO。但在我去那儿之前,我想确定没有别的办法可以做到这一点。
答案 0 :(得分:2)
有时候,最好用一个例子来表示。例如,您可以拥有一个包含产品订购数量的多维数组,其中第一个索引定义客户,第二个索引定义订单,第三个索引定义产品。那么价值就是数量。
<强> IV。使用简单的get和set函数,但有多个参数:
$value = $obj->get($key1, $key2);
$obj->set($key1, $key2, $value);
或
$quantity = $orderedQuantities($customerName, $orderNo, $productCode);
编写对象包装器的本质是它看起来像一个对象并且表现得像这样。如果你实现它,使它看起来和行为像一个数组,你也可以使用一个数组。将数组包装在一个行为类似于数组的对象中的唯一原因是您可以通过引用传递它,而不使用&
参数。
如果这是您的目标,只需将数组分配给$ obj,然后使用$obj->arrayprop[$key1][$key2]
。另一方面,如果您希望它的行为类似于对象,则完全跳过数组语法。
<强>诉使用嵌套对象 因此,使用相同的示例,您可以编写客户对象(一种集合),嵌入订单对象等。
$ quantity = $ customers-&gt; getCustomerByName($ customerName) - &gt; getOrder($ orderNo) - &gt; getProduct($ productCode) - &gt; quantity;
或者,为了使其更具可读性:
$ customer = $ customers-&gt; getCustomerByName($ customerName); $ order = $ customer-&gt; getOrder($ orderNo); $ orderLine = $ order-&gt; getOrderLine($ productCode); $ quantity = $ product-&gt;数量;
现在,每个实体都由一个对象表示。优点是您可以使用额外的属性轻松扩展此结构。您可以为客户集合'findByCustomerNo'和'findByName'方法查找特定客户,还可以提供'filterByPostalCode',它可以返回仅包含该邮政编码中客户的新集合。
$ order现在可以包含计算总数的函数。
$ orderLine可能只包含productCode(键)和数量,但通过使其成为对象,您可以轻松添加折扣,自定义名称或描述或其他属性。
总而言之,这种结构可以提供很大的灵活性,虽然它最初需要更多的输入,而且有点习惯。
答案 1 :(得分: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