数组转换
这里只说明如果将一个数组转换问对象后,既可以按照数组方式访问和遍历,又可以使用对象的属性方式访问的。
先弄一个可以遍历的类再说
这里借助的是 迭代器接口 Iterator
官网对应链接:http://php.net/manual/zh/language.generators.comparison.php
1. 先写一个抽象类 实现 迭代器 接口
2. 实现迭代器接口所有的方法。
使用静态延迟绑定实现 递归生成,而不是只有一级的可以实现;
这样我们就得到一个可以遍历的对象了。
看一个例子:
abstract class CommonIterator implements \Iterator
{
protected $array;
/**
* 构造函数
* @param Array $arr 要转换的数组
*/
public function __construct(Array $arr)
{
$this -> array = $arr;
foreach ($arr as $k => $v) {
if(is_array($v)){
$this -> array [$k] = new static($v);
continue;
}
$this -> array [$k] = ($v);
}
}
/**
* 初始化数组时 调用的方法
* @return [type] [description]
*/
public function rewind()
{
return reset($this -> array);
}
/**
* 检测 数组中键存不存在
* @return [type] [description]
*/
public function valid()
{
return array_key_exists($this -> key(), $this -> array);
}
/**
* 获取当前数组指针指向的内容
* @return mixed 指向的内容
*/
public function current()
{
return current($this -> array);
}
/**
* 获取指针指向的键
* @return int|string 指针指向的键
*/
public function key()
{
return key($this -> array);
}
/**
* 使指针指向下一位
* @return function [description]
*/
public function next()
{
return next($this -> array);
}
}
访问对象的属性就是访问 数组中的键值的实现
其实很简单,通过魔术方法 __get ,就可以实现。
在前面的基础上 添加魔术方法。
1. 再写一个抽象类继承上面的抽象类
2. 添加魔术方法
3. 既然获取有了判断是否设置也写上吧,万一用上了呢。
下面代码:
abstract class BaseCommon extends CommonIterator
{
/**
* 对象魔术方法 当属性没有的时候或者属性私有的时候 触发这个方法
* @param string $name 属性名
* @return mixed 返回的属性对应的值
*/
public function __get($name)
{
if(isset($this -> array[$name]))
return $this -> array[$name];
return null;
}
/**
* 判断对象属性存不存在
* @param string $index 要判断的下标
* @return boolean 结果
*/
public function __isset($index)
{
return isset($this->array[$index]);
}
}
实现访问数组方式访问对象的属性
这里我们借助 ArrayAccess
这个接口
再写一个抽象类,继承前面的抽象类并实现 `ArrayAccess` 接口的所有方法。
这样我们就可以按照数组的形式访问对象了。
abstract class ArrayCommon extends BaseCommon implements \ArrayAccess
{
/**
* [字段是否存在]
* @param [string] $index [字段名]
* @return [boolean] [字段是否存在]
*/
function offsetExists($index)
{
return isset($this->array[$index]);
}
/**
* [获取字段]
* @param [string] $index [字段名]
* @return [string] [字段值]
*/
function offsetGet($index) {
return $this->array[$index];
}
/**
* [设置字段]
* @param [string] $index [字段名]
* @param [string] $newvalue [字段值]
*/
function offsetSet($index, $newvalue) {
$this->array[$index] = $newvalue;
}
/**
* [删除字段]
* @param [string] $index [字段名]
*/
function offsetUnset($index) {
unset($this->array[$index]);
}
}
写在最后
这样从上面的最后一个抽象类 继承的类 就可以实现 既可以用对象方式访问有可以用数组方式访问了。
感觉少了点啥
万年之后 ……
终于想起来了。怎么把数组再还原回来呢?
再弄一个抽象类 继承上面的抽象类
第一次写的时候忘了使用递归了,导致只能得到一层的还原数据
这样我们就把一个对象还原到原始的数组了。
代码:
abstract class newContinent extends ArrayCommon
{
/**
* 对象转换成数组
* @return array 转换后的数组
*/
public function toArray()
{
$arr = $this -> array;
foreach ($arr as $k => $v) {
if(is_object($v)){
$arr [$k] = $v -> toArray();
continue;
}
}
return $arr;
}
}
最最最后了
综合上面的代码 我们就能实现前面所说的所有的功能,并且任意一个级别的对象都会有 toArray
方法,自我感觉还是非常好用的。
完整示例
abstract class CommonIterator implements \Iterator,\ArrayAccess
{
protected $array;
/**
* 构造函数
* @param Array $arr 要转换的数组
*/
public function __construct(Array $arr)
{
$this -> array = $arr;
foreach ($arr as $k => $v) {
if(is_array($v)){
$this -> array [$k] = new static($v);
continue;
}
$this -> array [$k] = ($v);
}
}
/**
* 初始化数组时 调用的方法
* @return [type] [description]
*/
public function rewind()
{
return reset($this -> array);
}
/**
* 检测 数组中键存不存在
* @return [type] [description]
*/
public function valid()
{
return array_key_exists($this -> key(), $this -> array);
}
/**
* 获取当前数组指针指向的内容
* @return mixed 指向的内容
*/
public function current()
{
return current($this -> array);
}
/**
* 获取指针指向的键
* @return int|string 指针指向的键
*/
public function key()
{
return key($this -> array);
}
/**
* 使指针指向下一位
* @return function [description]
*/
public function next()
{
return next($this -> array);
}
/**
* 对象魔术方法 当属性没有的时候或者属性私有的时候 触发这个方法
* @param string $name 属性名
* @return mixed 返回的属性对应的值
*/
public function __get($name)
{
if(isset($this -> array[$name]))
return $this -> array[$name];
return null;
}
/**
* 判断对象属性存不存在
* @param string $index 要判断的下标
* @return boolean 结果
*/
public function __isset($index)
{
return isset($this->array[$index]);
}
/**
* 对象转换成数组
* @return array 转换后的数组
*/
public function toArray()
{
$arr = $this -> array;
foreach ($arr as $k => $v) {
if(is_object($v)){
$arr [$k] = $v -> toArray();
continue;
}
}
return $arr;
}
/**
* [字段是否存在]
* @param [string] $index [字段名]
* @return [boolean] [字段是否存在]
*/
function offsetExists($index)
{
return isset($this->array[$index]);
}
/**
* [获取字段]
* @param [string] $index [字段名]
* @return [string] [字段值]
*/
function offsetGet($index) {
return $this->array[$index];
}
/**
* [设置字段]
* @param [string] $index [字段名]
* @param [string] $newvalue [字段值]
*/
function offsetSet($index, $newvalue) {
$this->array[$index] = $newvalue;
}
/**
* [删除字段]
* @param [string] $index [字段名]
*/
function offsetUnset($index) {
unset($this->array[$index]);
}
}
评论已关闭