SPL接口学习总结
迭代器接口描述(接口在C里定义,这只是描述)
interface Iterator
{
public function current();
public function key();
public function next();
public function rewind();
}
//迭代器辅助函数
function print_entry($iterator)
{
print($iterator->current());
return true;
} $array = array(1,2,3);
$iterator = new ArrayIterator($array);
iterator_apply($iterator, 'print_entry',array($iterator)); //相当于array_walk
观察者模式
观察者模式:允许某个类观察另外一个类的状态,当被观察的类的状态发生变化时, 这个模式会得到通知
被观察的类叫subject,负责观察的类叫做observer
SPL提供了SplSubject和SplObserver接口
SplSubject 接口
interface SplSubject
{
public function attach(SplObserver $observer);
public function detach(SplObserver $observer);
public function notify();
}
SplObserver 接口
interface SplObserver
{
public function update(SplObserver $subject);
}
//被观察者
class DemoSubject implements SplSubject
{
private $observers, $value;
public function __construct()
{
$this->observers = array();
} public function attach(SplObserver $observer)
{
$this->observers[] = $observer;
} public function detach(SplObserver $observer)
{
if($idx = array_search($observer, $this->observers))
{
unset($this->observers[$idx]);
}
} public function notify()
{
foreach ($this->observers as $observer)
{
$observer->update($this);
}
} public function setValue($value)
{
$this->value = $value;
$this->notify();
} public function getValue()
{
return $this->value;
}
}
//观察者
class DemoObserver implements SplObserver
{
public function update(SplSubject $subject)
{
echo 'The new value is ' . $subject->getValue();
}
} $subject = new DemoSubject();
$observer = new DemoObserver();
$subject->attach($observer);
$subject->setValue('hello,world');
更好的观察者模式
观察模式的优点在于,挂接到订阅者上的观察者可多可少,并且不需要提前知道哪个类会响应subject类发出的事件
PHP6提供了SplObjectStorage类,这个类提升了观察者模式的可用性.这个类与数组相似,但它只能存储唯一性的对象,而且只存储这些对象的引用.这种做法有几个好处.
现在不能挂接一个类两次,可以防止多交代调用同一个对象的update()方法,而且,不需要迭代访问或者搜索集合,就可以从集合中删除某个对象,这提高了效率
//被观察者
class DemoSubject implements SplSubject
{
private $observers, $value;
public function __construct()
{
$this->observers = new SplObjectStorage();
}
public function attach(SplObserver $observer)
{
$this->observers->attach($observer);
}
public function detach(SplObserver $observer)
{
$this->observers->detach($observer);
}
public function notify()
{
foreach($this->observers as $observer)
{
$this->observers->update($this);
}
}
public function setValue($value)
{
$this->value = $value;
$this->notify();
}
public function getValue()
{
return $this->value;
}
}
//观察者
class DemoObserver implements SplObserver
{
public function update(SplSubject $subject)
{
echo 'The new value is ' . $subject->getValue();
}
}
$subject = new DemoSubject();
$observer = new DemoObserver();
$subject->attach($observer);
$subject->attach($observer);
$subject->setValue('hello,world');
序列化
SPL的Serializable接口为一些高级的序列化场景提供了支持,非SPL的序列化魔术方法的__sleep和__wakeup有一些问题,这些问题在SPL接口中都得到了解决
魔术方法不能序列化基类的私有变量.实现的__sleep函数必须返回变量名称的一个数组,并且要包含在序列化输出结果中,由于序列化发生的程序中,基类的私有成员的访问受到了限制.
通过允许调用父类的serialize()方法, Serializable接口消除了这一限制,父类的serialize()方法可以返回父类中序列化后的私有成员.
//魔术方法的序列化技术
error_reporting(E_ALL); //显示错误通知 class Base
{
private $baseVar;
public function __construct()
{
$this->baseVar = 'foo';
}
} class Extender extends Base
{
private $extendVar;
public function __construct()
{
parent::__construct();
$this->extendVar = 'bar';
}
public function __sleep()
{
return array('extenderVar','baseVar');
}
} $instance = new Extender();
$serialized = serialize($instance);
echo $serialized . '\n';
$restored = unserialize($serialized);
序列化对象(包含私有属性)
Serializable接口:
当实现 Serialize()方法,要求返回代表这个对象的序列化以后的字符,这个字符串通常是通过调用 serialize()方法获得的
unserialize()方法允许重新构造对象,它接受序列化的字符串作为输入.
interface Iterator
{
public function serialize();
public function unserialize($serialized);
}
error_reporting(E_ALL); //显示错误通知 class Base implements Serializable
{
private $baseVar;
public function __construct()
{
$this->baseVar = 'foo';
} public function serialize()
{
return serialize($this->baseVar);
} public function unserialize($serialized)
{
$this->baseVar = unserialize($serialized);
} public function printMe()
{
echo $this->baseVar . '\n';
}
} class Extender extends Base
{
private $extendVar;
public function __construct()
{
parent::__construct();
$this->extendVar = 'bar';
}
public function serialize()
{
$baseSerialized = parent::serialize();
return serialize(array($this->extendVar,$baseSerialized));
} public function unserialize($serialized)
{
$temp = unserialize($serialized);
$this->extendVar = $temp[0];
parent::unserialize($temp[1]);
}
} $instance = new Extender();
$serialized = serialize($instance);
echo $serialized . '\n';
$restored = unserialize($serialized);
$restored->printMe();
SPL自动加载
安全的类加载方法
if(spl_autoload_call($class_name) && class_exists('className',false))
{
echo 'className was loaded';
//安全的实例化className类
$instance = new className;
}
else
{
//在这里实例化className类是不安全的
echo 'className was not found';
}
为对象设置一个独一无二的代码
class a{}
$instance = new a();
$reference = $instance;
echo spl_object_hash($instance) . PHP_EOL;
echo spl_object_hash($reference);
IteratorAggregate接口
IteratorAggregate接口是用来将Iterator接口要求实现的5个迭代器方法委托给其他类的.
这让你可以在类的外部实现迭代功能,并允许重新使用常用的迭代器方法,而不是在编写的每个可迭代类中重复使用这些方法
class MyIterableClass implements IteratorAggregate
{
protected $arr;
public function __construct()
{
$this->arr = array(1,2,3);
}
public function getIterator()
{
return new ArrayIterator($this->arr);
}
} //foreach循环遍历一个类
foreach(new MyIterableClass() as $value)
{
echo $value . PHP_EOL;
}
数组迭代器
数组迭代器实现SQL的LIMIT子句和OFFSET子句相同的迭代访问功能
$arr = array('a','b','c','e','f','g','h','i','j','k');
$arrIterator = new ArrayIterator($arr);
$limitIterator = new LimitIterator($arrIterator, 3, 4);
foreach($limitIterator as $v)
{
echo $v;
}
在一个循环中抚今追昔访问两个或多个数组
$arrFirst = new ArrayIterator(array(1,2,3));
$arrSecond = new ArrayIterator(array(4,5,6));
$iterator = new AppendIterator();
$iterator->append($arrFirst);
$iterator->append($arrSecond);
foreach($iterator as $v)
{
echo $v;
}
高级的数组合并功能
使用LimitIterator迭代器,AppendIterator迭代器和iterator_to_array()函数创建一个包含了每个输入数组前两元素的数组
$arrFirst = new ArrayIterator(array(1,2,3));
$arrSecond = new ArrayIterator(array(4,5,6));
$iterator = new AppendIterator();
$iterator->append(new LimitIterator($arrFirst, 0, 2));
$iterator->append(new LimitIterator($arrSecond, 0, 2));
print_r(iterator_to_array($iterator,false));
过滤数组接口FilterIterator
class GreaterThanThreeFilterIterator extends FilterIterator
{
public function accept()
{
return ($this->current() > 3);
}
}
$arr = new ArrayIterator(array(1,2,3,4,5,6,7,8));
$iterator = new GreaterThanThreeFilterIterator($arr);
print_r(iterator_to_array($iterator));
正则过滤数组接口regexIterator从FilterIterator类继承而来,允许使用几种正则表达式模式来匹配那些键值
$arr = array('apple','avocado','orange','pineapple');
$arrIterator = new ArrayIterator($arr);
$iterator = new RegexIterator($arrIterator, '/^a/');
print_r(iterator_to_array($iterator));
递归数组接口RecursiveArrayIterator,RecursiveIteratorIterator
$arr = array(
0 => 'a',
1 => array('a','b','c'),
2 => 'b',
3 => array('a','b','c'),
4 => 'c'
);
$arrayIterator = new RecursiveArrayIterator($arr);
$it = new RecursiveIteratorIterator($arrayIterator);
print_r(iterator_to_array($it,false));
数组重载
ArrayAccess接口:允许使用[]数组语法访问数据
使用ArrayAccess接口使对象的行为看起来和数组一样,包含四个方法
interface Iterator
{
public function offsetExistsw($offset);
public function offsetSet($offset,$value);
public function offsetGet($offset);
public function offsetUnSet($offset);
}
class MyArray implements ArrayAccess
{
protected $_arr;
public function __construct()
{
$this->_arr = array();
} public function offsetSet($offset, $value)
{
$this->_arr[$offset] = $value;
} public function offsetGet($offset)
{
return $this->_arr[$offset];
} public function offsetExists($offset)
{
return array_key_exists($offset, $this->_arr);
} public function offsetUnset($offset)
{
unset($this->_arr[$offset]);
} }
$myArray = new MyArray(); //创建可作为数组使用的对象
$myArray['first'] = 'test'; //offsetSet,通过键值设置数据
$demo = $myArray['first']; //offsetGet,通过键值获得数据
unset($myArray['first']); //offsetUnset,移除键值
ArrayObject类是一个ArrayAccess接口的实现类,它还提供了迭代功能,以及很多用来排序和处理数据的非常有用的方法
$myArray = new ArrayObject();
$myArray['first'] = 'first';
$myArray['second'] = 'second';
$myArray['third'] = 'third'; $demo = $myArray['first'];
unset($myArray['first']);
$numElements = count($myArray);
foreach($myArray as $key=>$value)
{
echo $value . PHP_EOL;
}
var_dump($myArray);
SPL接口学习总结的更多相关文章
- C# 常用接口学习 ICollection<T>
C# 常用接口学习 ICollection<T> 作者:乌龙哈里 时间:2015-11-01 平台:Window7 64bit,Visual Studio Community 2015 参 ...
- C# 常用接口学习 IComparable 和 IComparer
C# 常用接口学习 IComparable 和 IComparer 作者:乌龙哈里 时间:2015-11-01 平台:Window7 64bit,Visual Studio Community 201 ...
- 工程化编程实战callback接口学习笔记
一.编译并运行 help.version命令执行正常,但quit命令出错 二.Debug 从命令输入到执行过程: 源代码: 更改后: 运行结果:能正确运行quit命令 Callback接口学习成果: ...
- caffe的python接口学习(1):生成配置文件
caffe是C++语言写的,可能很多人不太熟悉,因此想用更简单的脚本语言来实现.caffe提供matlab接口和python接口,这两种语言就非常简单,而且非常容易进行可视化,使得学习更加快速,理解更 ...
- PHP 开发 APP 接口 学习笔记与总结 - APP 接口实例 [3] 首页 APP 接口开发方案 ② 读取缓存方式
以静态缓存为例. 修改 file.php line:11 去掉 path 参数(方便),加上缓存时间参数: public function cacheData($k,$v = '',$cacheTim ...
- OpenCV(C++接口)学习笔记1-图像读取、显示、保存
OpenCV在2.0加入版本号之后C++接口函数,学习前C语言的接口功能.现在OpenCV它已被发展到2.4.9版本号,所以,我决定学习C++接口函数,与步伐. 1.创建图像 cv::Mat imag ...
- C# 常用接口学习 IEnumerable<T>
作者:乌龙哈里 时间:2015-10-24 平台:Window7 64bit,Visual Studio Community 2015 本文参考: MSDN IEnumerable<T> ...
- java Thread 接口学习
对于程序员来说 Thread应该都不会陌生,具体的接口调用不是本篇的重点.Thread的基本概念及接口的使用:java多线程 下面将更多的从底层实现角度讲一下Thread. Thread的声明如下: ...
- JDBC 接口学习
说明:文章所有内容皆选自实验楼教程[JDBC 入门教程],想要学习更多JDBC,可以点击教程进行学习~ JDBC 简介 JDBC 的全称是 Java Database Connectivity,叫做 ...
随机推荐
- BZOJ1880或洛谷2149 [SDOI2009]Elaxia的路线
BZOJ原题链接 洛谷原题链接 显然最长公共路径是最短路上的一条链. 我们可以把最短路经过的边看成有向边,那么组成的图就是一张\(DAG\),这样题目要求的即是两张\(DAG\)重合部分中的最长链. ...
- VC 中引用js文件
#include "comutil.h" using namespace MSScriptControl; #include <MsHTML.h> #include & ...
- win10自带输入法的标点符号切换
快捷键是ctrl+句号 然后开启设置,把中文也用英文标点也选上.
- django网页分页
blog/views.py from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger #导入分页插件包 def ...
- 【repost】javascript:;与javascript:void(0)使用介绍
有时候我们在编写js过程中,需要触发事件而不需要返回值,那么就可能需要这样的写法 最近看了好几个关于<a>标签和javascript:void(0)的帖子,谨记于此,以资查阅. 注:以下代 ...
- 3 week work—Position
源代码部分: (1)httm部分: <!DOCTYPE html> <html lang="en"> <head> <meta chars ...
- Django Admin 专题
Django admin Django强大的功能之一就是提供了Admin后台管理界面,简单配置就可以对数据库内容做管理 创建ModelAdmin并注册 from django.contrib impo ...
- git 依据SHA值提取文件patch
git format-patch -M master //当前分支所有超前master的提交 git format-patch -s SHA值 //此SHA值提交以后的所有PATCH git form ...
- [UWP]使用Picker构建应用内图片公共裁剪组件
在上一篇博文<[UWP]如何实现UWP平台最佳图片裁剪控件>中我讲解了编写ImageCropper控件的过程及知识分享.在那篇文章里,我大言不惭的称其为UWP平台最佳图片裁剪控件(主要是没 ...
- Hessian学习(springboot环境)
Hessian介绍: Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议 ...