PHP里面的SPL函数

课程准备知识

熟悉和了解数据结构的节本概念

熟悉PHP代码的编写

熟悉面向对象的概念

什么是 SPL

SPL的基本框架

SPL的常用数据结构

SPL的常用迭代器

SPL的接口

SPL函数的使用

SPL的文件处理类库

SPL标准PHP库

它是用于解决典型(常见)问题的一组接口与类的集合。

common problem

数学建模/数据结构

解决数据怎么存储的问题(病人信息怎么存储)

元素遍历

数据怎么查看的问题(病人的信息怎么看)

常用方法的统一调用

通用方法(数组、集合的大小)
自定义遍历

类定义在自动装载

让PHP程序适应大型项目的管理要求,把功能的实现分散到不同文件中。

image.png
2-1 SPL里面的数据结构

本章课程适合对数据结构理解不是很熟悉的同学
本章课程不需要有非常强的PHP基础
如果您对于双向链表、堆栈、队列、堆等数据结构概念都比较熟悉,请跳过本章内容

教学目的
理解各种数据结构
学习如何使用SPL使用各种数据结构

什么是数据结构
数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
解决的是软件开发过程中的数据如何存储和表示的问题。
新浪微博里面某个用户的数据怎么存?

image.png

SPL提供哪些数据结构呢?
双向链表、堆栈、队列、堆、降序堆、升序堆、优先级队列、定长数组、对象容器

image.png
2-1双向列表

基本概念

image.png

抽象一下

image.png

bottom:最先添加到链表中的结点叫做bottom(底部),也成为头部(head)
top:最后添加到链表中的结点叫做top(顶部),也成为尾部
链表指针:是一个当前关注的结点的标志,可以指向任意结点。
当前结点:链表指针指向的结点成为当前结点。
结点1:喜欢 结点名称和节点数据

结点名称:可以在链表中位移标识一个结点的名称,通常我们又称为结点的key或者offset
结点数据:存放在链表中的应用数据,我们通常称为value

image.png

数据结构值SPLDoublyLinkedList类

image.png

当前结点操作

rewind
current
next
prev

增加结点操作

push
unshift

增加结点操作

pop
shift

定位操作

bottom
top

定位操作

bottom
top

特定结点操作

offsetExists
offsetGet
offsetSet
offsetUnset

<?php
$obj=new SplDoublyLinkedList();
print_r($obj);
?>
image.png
<?php
$obj=new SplDoublyLinkedList();
$obj->push(1);
print_r($obj);
?>
image.png

unshift把一个元素添加到bottom的位置


image.png

push是把新的结点数据添加到列表的top顶部
unshift是把新的结点数据添加到链表的底部bottom

image.png

current是空的,说明一个也没有指向

<?php
$obj=new SplDoublyLinkedList();
$obj->push(1);
$obj->push(2);
$obj->push(3);
$obj->push(4);
$obj->unshift(10);
print_r($obj);
echo 'current : '.$obj->current();
?>
image.png

有了rewind之后,current才有意义

rewind用于比结点指针指向bottom结点
current用于获取结点指针指向的节点

$obj->next();
echo 'current : '.$obj->current()."\n";
image.png
image.png

pop操作不影响current
如果pop删除的是当前的元素的话,current会指向一个空的结点

shift是把bottom位置的结点从链表中删除,并返回

image.png
2-6堆栈的简介

先进后出
first in last out

image.png

继承自SplDoublyLinkedList类的SplStack类
操作
push:压入堆栈(存入)
pop:退出堆栈(取出)

6表示先进先出

image.png
<?php
$stack = new SplStack();
$stack->push('a');
$stack->push('b');
$stack->push('c');
print_r($stack);
$stack->bottom();
$stack->top();
$stack->offsetSet(0,'C');
//堆栈的offset=0是top所在的位置,offset=1是top位置结点靠近bottom位置的相邻结点,以此类推
print_r($stack);
?>
image.png
$stack->rewind();  //双向链表的rewind
echo "current: ".$stack->current()."\n";
$stack->next();
echo "current: ".$stack->current()."\n";   //会指向b
image.png
image.png
$stack->rewind();
while($stack->valid()){
    echo $stack->key()."current is:".$stack.current()."\n";
    $stack->next();
}

这是一个遍历的过程
next不从链表中删除数据

$popObj=

2-8队列

队列和堆栈刚好相反,最先进入队列的元素会最先走出队列
就想排队打饭,排在最前面的人,总是最先能够打到饭
继承自SPLdoublylinkedlist类的splqueue类
操作enqueue 进入队列
dequeue 退出队列

<?php
$obj = new SplQueue();
$obj->enqueue('a');
$obj->enqueue('b');
$obj->enqueue('c');
$obj->enqueue('d');
print_r($obj);

?>
image.png
echo "bottom: ".$obj->bottom()."\n";
echo "top: ".$obj->top()."\n";
image.png
$obj->offsetSet(0,'A');
print_r($obj);
image.png

dequeue是从队列中提取bottom位置的结点,并返回。同时从队列里面删除钙元素。

第三章迭代器

以代码讲解尾注,通过实例讲解各个迭代器的用法
教学目的
理解各种常用的迭代器
掌握如何使用常用的迭代器

通过某种同一的方式遍历链表或者数组中的元素的过程叫做迭代遍历,而这种同一的便利工具我们叫做迭代器。

PHP中迭代器是通过iterator接口定义的

image.png

<?php
$fruits = array(
"apple" => "apple value",
"banana" => "orange value",
"grape" => "grape value",
"plum" => "plum value"
);
print_r($fruits);
echo "********user fruits directly";

foreach($fruits as $key => $values){
echo $key." aaaa ".$values;
}
?>

image.png
$obj = new ArrayObject($fruits);
$it = $obj->getIterator();
foreach($fruits as $key => $values){
echo $key." bbbb ".$values;
}
image.png

使用迭代器

$it->rewind();
while($it->valid()){
echo $it->key()." ccc  ".$it->current()."\n";
$it->next();
}

$it->rewind();
if($it->valid()){
$it->seek(2);
while($it->valid()){
echo $it->key()." ccc  ".$it->current()."\n";
$it->next();
}
}

会从第2个元素开始

$it->ksort();
$it->asort();

appenditerator
能陆续遍历几个迭代器
按顺序迭代访问几个不同的迭代器。例如,希望在一次循环中迭代访问两个或者更多的组合

<?php
$array_a = new ArrayIterator(array('a','b','c'));
$array_b = new ArrayIterator(array('w','e','d'));

$array = new AppendIterator();
$array->append($array_a);
$array->append($array_b);

foreach($array as $key => $value){
  echo $key."   aaaa  ".$value."\n";
}

?>

image.png
multipleiterator

multipleiterator用于把多个iterator里面的数据组合成为一个整体访问

<?php
$id = new ArrayIterator(array('1','2','3'));
$name = new ArrayIterator(array('王朝阳','啊啊','阿萨'));
$num = new ArrayIterator(array('22','232','2323'));
$multi = new MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC);
$multi->attachIterator($id,"ID");
$multi->attachIterator($name,"NAME");
$multi->attachIterator($num,"NUM");
foreach($multi as $value){
print_r($value);
}

?>

image.png
FilesystemIterator
<?php
date_default_timezone_set('PRC');
$it = new FileSystemIterator('.');
foreach ($it as $finfo) {
# code...
echo date("Y-m-d H:i:s",$finfo->getMTime())."\n";
}
?>
image.png
<?php
date_default_timezone_set('PRC');
$it = new FileSystemIterator('.');
foreach ($it as $finfo) {
# code...
//echo date("Y-m-d H:i:s",$finfo->getMTime())."\n";
printf("%s\t%s\t%8s\t%s\n",date("Y-m-d H:i:s",$finfo-  >getMTime()),$finfo->isDir()?"<DIR>":"",number_format($finfo->getSize()),$finfo->getFilename());
}
?>
image.png

2017-06-29 09:14:42 282 appiterator.php
2017-06-29 09:03:28 698 arrayinterator.php
2017-06-29 10:33:32 345 filesystemiterator.php
2017-06-29 09:46:06 404 mutipleiterator.php
2017-06-28 16:38:11 735 spldoublelinkedlist.php
2017-06-28 17:27:32 244 splqueue.php
2017-06-28 17:08:17 737 splstack01.php

4-1SPL接口简介

以概念讲解为主,通过实例讲解countable接口的使用
教学目的
理解countable。outeriterator。recursiveiterator和seekableiterator四个接口的概念
熟练掌握countable的接口

image.png

spl的解除接口里面定义了最常用的接口
countable。继承了该接口的类可以直接调用count()得到元素个数
outeriterator。如果想对迭代器进行一定的处理之后再返回,可以用这个接口
recursiveiterator 可以对多层结构的迭代器进行迭代,比如遍历一棵树
seekableiterator 可以通过seek方法定位到几何里面特定元素

countable
在里面经常直接用count($obj)方法获得对象里面的元素的个数
count(array('name'=>'peter'),'id'=>'5');
可以得到结果是2
对于我们自定义的类,也可以这样访问吗?

<?php
class countmy implements Countable{
public $_mycount = 3;
public function count(){
    return $this->_mycount;
}
}
$obj = new countmy();
echo count($obj);
 ?>

outerIterator
如果想对迭代器进行一定的处理之后,再返回,可以用这个接口
IteratorIterator类是outeriterator的实现,扩展的时候可以直接继承IteratorIterator

recursiveiterator
可以对多层结构的迭代器进行迭代,比如遍历一棵树,所具有层次结构特点的数据,都可以用这个接口遍历,如,文件夹
关键方法
hashchild方法用于判断当前结点是否存在子节点
getchild方法用于得到当前子节点的迭代器

recursiveArrayiterator recursiveCachingiterator 等以recursive开头的类都能进行多层次结构化的遍历

image.png

5-1基础函数
spl函数的使用autoload
什么是autoload,为了初始化PHP中类对象,需要通过一定的方法寻找到类的定义。通常情况下,定义在一个单独的文件中。
autoload就是PHP找到这些类文件的方法

<?php
//spl_autoload_extensions('.class.php');
//spl_autoload_extensions('.php');
spl_autoload_extensions('.class.php,.php');
//设置autoload寻找PHP定义的类文件的扩展名,多个扩展名用逗号分隔,前面的扩展名有限被匹配
set_include_path(get_include_path().PATH_SEPARATOR.'libs/');//设置      autoload寻找PHP定义的类文件的目录,多个目录用PATH_SEPARATOR进行分隔
spl_autoload_register();//提示PHP使用autoload机制,查找类定义
new test();
 ?>

<?php
class test{
public function __construct(){
    echo "loadding";
}
}
 ?>

<?php
class test{
public function __construct(){
    echo "loadding  php";
}
}

5-2 使用__autoload装载类

<?php
function __autoload($class_name){
//定义—__autoload函数,可以在不调用spl_autoload_register函数的情况下完成类的装在
echo "__autoload class:".$class_name."\n";
//require_once("libs/".$class_name.'.php');
require_once("libs/".$class_name.'.class.php');//装载类
}
new test();
 ?>


function classautoloader($class_name){
//定义一个替换__autoload函数的类文件装在函数
echo "classloader".$class_name."\n";
//require_once("libs/".$class_name.'.class.php');
require_once("libs/".$class_name.'.php');
}
spl_autoload_register('classautoloader');
    //传入定义好的装在类的函数的名称__autoload函数
    new test();



<?php

function classautoloader($class_name){
//定义一个替换__autoload函数的类文件装在函数
echo "classloader".$class_name."\n";
//require_once("libs/".$class_name.'.class.php');
set_include_path("libs/");
spl_autoload($class_name.'.class');
//当我们不用require或require_once载入类文件的时候,而想通过系统查找include_path来装在类时,必须显式调用spl_autoload函数,参数是类的名称来重启类文件的自动查找
}
spl_autoload_register('classautoloader');

//传入定义好的装在类的函数的名称__autoload函数
new test();
?>

image.png
image.png
image.png

6-1spl文件处理类库
SplFileInfo用于获得文件的基本信息,比如修改时间、大小、目录等信息
SplFileObject用于操作文件的内容,比如读取,写入

<?php
date_default_timezone_set('PRC');
$file = new SplFileInfo("ttt.txt");
echo "file is create in ".date("Y-m-d H:i:s",$file->getCTime());
echo "file is modify in ".date("Y-m-d H:i:s",$file->getMTime());
echo "file is size in ".date("Y-m-d H:i:s",$file->getSize());

$fileObj = $file->openFile('r');
while ($fileObj->valid()) {
# code...
echo $fileObj->fgets();
}
$fileObj = null;
$file = null;

 ?>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 一 预定义接口 1.1 遍历 Traversable(遍历)接口 检测一个类是否可以被foreach遍历,该接口不...
    coderhu阅读 1,196评论 0 0
  • 在PHP开发过程中,如果希望从外部引入一个class,通常会使用include和require方法,去把定义这...
    四月不见阅读 1,037评论 0 0
  • B树的定义 一棵m阶的B树满足下列条件: 树中每个结点至多有m个孩子。 除根结点和叶子结点外,其它每个结点至少有m...
    文档随手记阅读 13,149评论 0 25
  • 2月14号,世界情人节,在这一天所有的恋人都会在一起庆祝,但是总有不同的原因导致可能会分隔两地的恋人们无法在一起...
    穷的只剩下代码阅读 196评论 1 0
  • 142 以前 ,从未想过自己会成为一名幼儿教师,曾幻想过自己是的公司的小小职员,每天跑业务跑...
    爱吃橘子的夏果阅读 209评论 0 2