【问题标题】:php - multi-dimensional array wrapper classphp - 多维数组包装类
【发布时间】:2012-12-03 02:21:12
【问题描述】:

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

我已经尝试过的:

我。数组访问 这个问题是服务器使用的是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。但在我去那里之前,我想确定真的没有其他方法可以做到这一点。

【问题讨论】:

    标签: php arrays oop multidimensional-array


    【解决方案1】:

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

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

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

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

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

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

    V.使用嵌套对象 因此,使用相同的示例,您可以编写一个客户对象(一种集合),其中嵌入了订单对象等。

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

    或者,使其更具可读性:

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

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

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

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

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

    【讨论】:

    • 我的第一个想法是实现一个看起来和行为都像数组的对象,并添加了类似数组的功能。但事实证明,您无法在 PHP 5.2.17 中实现看起来像数组的东西。所以我试着至少坚持“表现得像和有点像”部分。但事实证明,你也不能真正做到这一点。感谢您的回答,我想我会坚持使用最直接的$obj->arrayprop[$key1][$key2] 方式来做到这一点,我觉得这真的很难看,但是......无论如何。我已经非常讨厌 PHP 了。
    • 这就是精神(我真的同意)。 :) 但是为了改变你的想法,我添加了V. Using nested objects.
    • 这个嵌套对象的东西实际上很好用。不仅如您所描述的,而且还以一般的方式。使用嵌套对象解决了 I 中的引用传递问题。因此 ArrayAccess 再次可用。我发布我的代码作为答案。感谢您为我指明了正确的方向:停止以通用方式对所有内容进行编程。我想我会扔掉我的代码并重新考虑这一点,更多地关注手头的问题,反对未来使用它的所有可能方式。
    【解决方案2】:

    使用嵌套对象可以使 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-20
      • 2022-01-07
      • 2013-03-04
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多