douli0531 2012-12-03 02:21
浏览 23
已采纳

php - 多维数组包装类

I have some data represented as multi-dimensional arrays. I would like to embed these data into my OO application and provide extra functionality to these data but also a way to access it both with the traditional random access and using an iterator (so I could use foreach). In other words I would like to implement a wrapping class for a multi-dimensional array.

What I already tried:

I. ArrayAccess The problem with this one is that the server uses PHP 5.2.17 and &offsetGet() gives an error, thus I can't return by reference, which means I can't implement multidimensional element access:

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

Note, that upgrading to a newer PHP version is currently not an option

II. Using magic methods This is a bit trickier, but my problems rose when I tried using a variable as key. E.g.

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

The interpreter first evaluated $key1[$key2] throwing a notice and returning the first char of $key1, and uses that as key on my array. I don't know how to solve this one either. I thought of using brackets to force operation priority, but that had the same problem as in my next attempt:

III. Using simple get and set functions Again, old PHP. It cries when I try to write:

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

Because it doesn't know how to index an expression ending in round brackets.

There's still the lost resort option: make the array public and forget OO all together. But before I go there I want to be certain that there's just really no other way of doing this.

  • 写回答

2条回答 默认 最新

  • dongnanman9093 2012-12-03 02:28
    关注

    Sometimes, it's best shown with an example. For instance, you could have a multidimensional array with ordered quantities of a product, where the first index defines a customer, the second an order and the third the products. The value then is the quantity.

    IV. Using simple get and set functions, but with multiple parameters:

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

    or

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

    The essence of writing an object wrapper, is that it looks like an object and behaves like such. If you implement it so that it looks and behaves like an array, you may just as well use an array. The only reason to wrap an array in an object that behaves like an array is that you can pass it around by reference, without using & parameters.

    If that is your goal, just assign the array to $obj, and use $obj->arrayprop[$key1][$key2]. If on the other hand you want it to behave like an object, skip the array syntax altogether.

    V. Using nested objects So using the same example, you can write a customers object (kind of a collection), which embeds order objects, etc..

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

    or, to make it more readable:

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

    Now, each of these entities are represented by an object. The advantage is that you can easily extend this structure with extra properties. You can give the customer collection 'findByCustomerNo' and 'findByName' methods to find a specific customer, but also a 'filterByPostalCode', which could return a new collection containing only the customers from that postal code.

    $order could now contain functions to calculate totals.

    $orderLine may contain only a productCode (key) and a quantity, but by making it an object, you can easily add discount, a customized name or description or other properties.

    All in all, this structure allows a lot of flexibility, although it needs a little more typing at first and a little getting used to.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊
  • ¥15 安装svn网络有问题怎么办