PHP中模拟JSONArray

前面整理过一篇文章,描述php中的array与json的array和object的转换关系。http://www.cnblogs.com/x3d/p/php-json-array-object-type.html

在实际开发中,如何保障这种关系呢?一般来说,需要定义一些类型来做映射。

废话不多说,上码。

1. 最终用法

use hybridonecollectionJSONArray;

// json

$arr = new JSONArray();

//$arr[2] = 444; // 异常 不是从0开始

$arr[0] = 1;
$arr[1] = 2;
$arr[2] = 3;

var_dump($arr->__toArray());

$arr[6] = 66; // 异常 索引跳跃
$arr['91'] = 91; // 异常 不是整型

2. 相关基础类


<?php

namespace hybridonecollection;

use ArrayIterator;
use IteratorAggregate;
use ArrayAccess;
use Countable;

use hybridoneCollection;

/**
 * PHP的数组结构灵活,但在输出JSON数据时往往造成混乱,针对JSON内置的数据集合类型映射对应的PHP类
 * JSONArray的特征:
 * 数据的下标:
 * 必须是数字索引,
 * 必须从0开始,
 * 必须从小到大依次增加、中间不可以跳跃、顺序不可变动
 */
class JSONArray implements Collection, ArrayAccess, Countable, IteratorAggregate
{
    /**
     *
     * @var array
     */
    private $data;

    public function __toArray(): array
    {
        return $this->data;
    }
    
    /**
     * Returns an iterator for traversing the data.
     * This method is required by the SPL interface [[IteratorAggregate]].
     * It will be implicitly called when you use `foreach` to traverse the collection.
     * @return ArrayIterator an iterator for traversing the cookies in the collection.
     */
    public function getIterator()
    {
        return new ArrayIterator($this->data);
    }

    /**
     * Returns the number of data items.
     * This method is required by Countable interface.
     * @return integer number of data elements.
     */
    public function count()
    {
        return count($this->data);
    }
    
    /**
     * 
     * @param mixed $offset
     * @return boolean
     */
    private function offsetLegal($offset)
    {
        return is_int($offset);
    }

    /**
     * This method is required by the interface [[ArrayAccess]].
     * @param int $offset the offset to check on
     * @return boolean
     */
    public function offsetExists($offset)
    {
        if (!$this->offsetLegal($offset)) {
            throw new IllegalOffsetException;
        }
        return isset($this->data[$offset]);
    }

    /**
     * This method is required by the interface [[ArrayAccess]].
     * @param integer $offset the offset to retrieve element.
     * @return mixed the element at the offset, null if no element is found at the offset
     */
    public function offsetGet($offset)
    {
        if (!$this->offsetLegal($offset)) {
            throw new IllegalOffsetException;
        }
        
        return isset($this->data[$offset]) ? $this->data[$offset] : null;
    }

    /**
     * This method is required by the interface [[ArrayAccess]].
     * @param integer $offset the offset to set element
     * @param mixed $item the element value
     */
    public function offsetSet($offset, $item)
    {
        if (!$this->offsetLegal($offset)) {
            throw new IllegalOffsetException;
        }
        
        if (!$this->offsetExists($offset) && ($offset > $this->count())) {
            throw new IllegalOffsetException('offset value is illegal, must be ordered integer value or existed offset given');
        }
        
        $this->data[$offset] = $item;
    }

    /**
     * This method is required by the interface [[ArrayAccess]].
     * @param mixed $offset the offset to unset element
     */
    public function offsetUnset($offset)
    {
        if (!$this->offsetLegal($offset)) {
            throw new IllegalOffsetException;
        }
        
        unset($this->data[$offset]);
    }

}

3. 其它

JSONObject 类可以依葫芦画瓢。

原文地址:https://www.cnblogs.com/x3d/p/php-jsonarray.html