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

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

废话不多说,上码。

1. 最终用法

use hybrid\one\collection\JSONArray;

// 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 hybrid\one\collection; use ArrayIterator;
use IteratorAggregate;
use ArrayAccess;
use Countable; use hybrid\one\Collection; /**
* 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 类可以依葫芦画瓢。

PHP中模拟JSONArray的更多相关文章

  1. 如何在C#中模拟C++的联合(Union)?[C#, C++] How To Simulate C++ Union In C#?

    1 什么是联合? 联合(Union)是一种特殊的类,一个联合中的数据成员在内存中的存储是互相重叠的.每个数据成员都在相同的内存地址开始.分配给联合的存储区数量是“要包含它最大的数据成员”所需的内存数. ...

  2. Python中模拟enum枚举类型的5种方法分享

    这篇文章主要介绍了Python中模拟enum枚举类型的5种方法分享,本文直接给出实现代码,需要的朋友可以参考下   以下几种方法来模拟enum:(感觉方法一简单实用) 复制代码代码如下: # way1 ...

  3. 在C#中模拟Javascript的setTimeout方法

    在C#中模拟Javascript的setTimeout方法 背景 每种语言都有自己的定时器(Timer),很多人熟悉Javascript中的setInterval和setTimeout,在Javasc ...

  4. iOS开发概述UIkit动力学,讲述UIKit的Dynamic特性,UIkit动力学是UIkit框架中模拟真实世界的一些特性。

    转发:http://my.oschina.net/u/1378445/blog/335014 iOS UIKit动力学 Dynamics UIAttachmentBehavior 实现iMessage ...

  5. 在SoapUI中模拟用户操作

    SoapUI作为一款接口测试工具,具有极大的灵活性和拓展性.它可以通过安装插件,拓展其功能.Selenium作为一款Web自动化测试插件可以很好的与SoapUI进行集成.如果要在SoapUI中模拟用户 ...

  6. C#7.2——编写安全高效的C#代码 c# 中模拟一个模式匹配及匹配值抽取 走进 LINQ 的世界 移除Excel工作表密码保护小工具含C#源代码 腾讯QQ会员中心g_tk32算法【C#版】

    C#7.2——编写安全高效的C#代码 2018-11-07 18:59 by 沉睡的木木夕, 123 阅读, 0 评论, 收藏, 编辑 原文地址:https://docs.microsoft.com/ ...

  7. php中模拟多继承如何实现

    php中模拟多继承如何实现 一.总结 一句话总结:其实你继承别人也是想调用别人类里面的方法和属性,所以可以这样做:这本类中创建目标类的对象,然后通过这个对象来调用方法和属性,这样比继承来的方便. 二. ...

  8. .net中模拟键盘和鼠标操作

    原文:.net中模拟键盘和鼠标操作 周银辉 其实SendKeys类提供的方法蛮好用的,可惜的是WPF中不能用了,说是WPF的消息循环方式改成了Dispatcher,所以直接调用System.Windo ...

  9. CSS中模拟父元素选择器

    很多情况下,我们需要找到父元素,但可惜的是css中并没有这样的一个选择器. 至于原因可以看张鑫旭的如何在CSS中实现父选择器效果这篇文章. 简单来说这个实现并不是真正的父元素选择器,只是利用其它思路来 ...

随机推荐

  1. scp报错 -bash: scp: command not found

    环境:RHEL6.5 使用scp命令报错: [root@oradb23 media]# scp /etc/hosts oradb24:/etc/ -bash: scp: command not fou ...

  2. 使用RequireJS并实现一个自己的模块加载器 (一)

    RequireJS & SeaJS 在 模块化开发 开发以前,都是直接在页面上引入 script 标签来引用脚本的,当项目变得比较复杂,就会带来很多问题. JS项目中的依赖只有通过引入JS的顺 ...

  3. python中IndentationError: expected an indented block错误的解决方法

    IndentationError: expected an indented block 翻译为IndentationError:预期的缩进块 解决方法:有冒号的下一行要缩进,该缩进就缩进

  4. 多线程条件通行工具——CountDownLatch

    CountDownLatch的作用是,线程进入等待后,需要计数器达到0才能通行. CountDownLatch(int)构造方法,指定初始计数. await()等待计数减至0. await(long, ...

  5. Linux命令

    系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS ...

  6. svnserver hook python

    在使用中可能会遇到的错误排除 :1.Error: svn: 解析"D:\www\test"出错,或svn: E020024: Error resolving case of 'D: ...

  7. [Intel Edison开发板] 01、Edison开发板性能简述

    Integrated Wi-Fi certified in 68 countries, Bluetooth® 4.0 support, 1GB DDR and 4GB flash memory sim ...

  8. atitit 商业项目常用模块技术知识点 v3 qc29

    atitit 商业项目常用模块技术知识点 v3 qc29 条码二维码barcodebarcode 条码二维码qrcodeqrcode 条码二维码dm码生成与识别 条码二维码pdf147码 条码二维码z ...

  9. salesforce 零基础学习(六十一)apex:component简单使用以及图片轮转播放的实现

    有的时候,我们项目有可能有类似需求:做一个简单的图像轮转播放功能,不同的VF页面调用可以显示不同的图片以及不同的图片描述.这种情况,如果在每个页面单独处理相关的图像轮转播放则显得代码特别冗余,此种情况 ...

  10. egret3D与2D混合开发,画布尺寸不一致的问题

    egret3d的GUI目前还没有,在做3d游戏的时候没有UI可用,只能使用egret2d的EUI组件库,egret3d与egret2d混合开发,canvas3d的大小与位置与canvas2d并没有重合 ...