php语言标准库,SPL(PHP标准库)

//SPL:PHP标准库,Standand  PHP  Library   解决常见问题的一组接口与类的集合

/*

问题:数学建模/数据结构,解决数据如何存储的问题

元素便利,数据如何查看的问题

常用方法的统一调用(通用方法,自定义遍历)

类定义的自动装载

*/

/*

SPL的基本框架

数据结构     基础接口    基础函数

迭代器       异常        其它

*/

/*SPL的常用数据结构

双向链表    堆栈    队列     堆     降序堆   升序堆    优先级队列    定长数组    对象容器

*/

//双向链表

微博用户A        微博用户B         微博用户C       //如果是单向的,则为单向链表

注:最先添加到列表当中的节点:Bottom/head

最后添加到列表当中的节点:Top,也称为尾部

链表指针:是当前关注的节点的标识,可以指向任意节点

当前节点:链表指针指向的节点

节点的组成:节点名称key/offset        节点数据value

SqlDoublyLinkedList类

操作:

当前节点操作:rewind(第一个节点),current(当前节点),next(下一个节点),prev(前一个节点)

增加节点操作:push,array_unshift

删除节点操作:pop,shift

定位操作:     bottom,top

特定节点操作:offsetExists,offsetGet,offsetSet,offsetUnset

双向链表在SPL中的实现:PHP -f   SqlDoublyLinkedList.php可以在cmd中测试

$obj=new  SqlDoublyLinkedList();

$obj->push(1);         //将1推入链表,也就是添加到顶部top

$obj->push(2);

$obj->push(3);

$obj->unshift(10);     //反向将10推入链表,也就是10将键值0占据,也就是添加到底部botton

$obj->rewind();        //调用rewind后,才会有指针,也就是才有current(当前指针的节点值),将指针指向bottom

$obj->next();          //指针向后移动一次

$obj->prev();          //指针向前移动一次

echo "current:".$obj->current();    //获取当前节点的值

if($obj->current){                  //判断是否移动完毕

echo "current node valid\n";

}else{

echo "current  node  invalid\n";

}

if($obj->valid()){               //可以直接用内置函数判断是不是指针移动完毕(判断节点是否有效)

echo "valid  list \n";

}

$obj->pop();                     //删除离top最近的节点

$obj->shift();                   //删除bottom所在位置的节点

双向链表总结:两头皆可操作

//堆栈               算是双向链表的衍生

3号圆盘         |

5号圆盘         |

7号圆盘         |

SqlStack类继承自SqlDoublyLinkedList类

操作:

push:压入堆栈(存入)

pop: 退出堆栈(取出)

代码实现:

$Stack = new SqlStack();

$stack->push('a');      //加入a,b,c

$stack->push('b');

$stack->push('c');

print_r($stack);

echo $stack->bottom;

echo $stack->top;

echo $stack->offsetSet(0,'C');       //堆栈的offset=0是top所在的位置,offset=1是靠近top所在的节点,而在双向链表中相反!!!

//将offset=0的键值对应的value设为C

$stack->rewind();

$stack->current();                   //rewind()之后,堆栈指向top位置,双向链表指向底部bottom

$stack->next();                      //会指向靠近bottom的方向

//遍历堆栈

$stck->rewind();

while($stck->valid()){

echo $stack->key()."=>".$stack->current()."\n";

$stack->next();

}

//删除堆栈数据

$popobj = $stack->pop();

echo "被删除的元素".$popobj;

堆栈总结:只能从top操作,很多函数如next,prev指向的方向与双向链表相反

//队列:排队打饭一样,先到先打,与堆栈恰恰相反

SqlQueue类也继承自SqlDoublyLinkedList类

enqueue:进入队列

dequeue:退出队列

代码实现:

$obj = new  SqlQueue();

$obj->enqueue('a');      //将abc加入到队列

$obj->enqueue('b');

$obj->enqueue('c');

echo "bottom: ".$obj->bottom."\n";

echo "top: ".$obj->top."\n";

$obj->offsetSet(0,'A');         //队列里面0为bottom

$obj->rewind();                 //队列里面指向bottom

遍历队列

while($obj->valid()){

echo %$obj->key()."=>".$obj->current()."\n";

$obj->next();

}

//删除

$delobj=>$obj->dequeue();

队列小结:一切以先来先出为原则。

/***************************************************************************************************************************

数据结构大总结:

双向链表,堆栈,队列的关系:

堆栈:先进后出

队列:先进先出

双向链表:两头都可以进出

****************************************************************************************************************************/

//******************************************SPL的常用迭代器************************************************************

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

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

常用的迭代器一:ArrayIterator-------------------------------------------------------------------------(用于遍历数组)

1: freach与while语句通过ArrayIterator遍历数组

2:seek跳过某些元素

3:ArrayIterator()进行排序

代码实现:

$fruits = array(

"apple"=>'apple  value',

"orange"=>'orange  value',

"grape"=>'grape  value',

"plum"=>'plum  value',

);

//一般遍历

foreach($fruits  as  $key=>$value){

echo $key.":".$value."\n";

}

//使用ArrayIterator迭代器遍历数组(相当于普通循环的详细化)

$obj = new  ArrayObject($fruits);

$it = $obj->getIterator();

foreach($it  as  $key=>$value){

echo echo $key.":".$value."\n";

}

//使用while之前需要调用rewind()

$it->rewind();

while($it->valid()){

echo $it->key().":".$it->value()."\n";

$it->next();

}

//跳过某些元素进行打印

$it->rewind();

if($it->valid()){

$it->seek(1);              //跳过position=1的元素

while($it->valid()){

echo $it->key().":".$it->current()."\n";

$it->next;

}

}

//排序打印

$it->ksort();     //按照key字母排序

foreach($it  as  $key=>$value){

echo $key.":".$value."\n";

}

//使用value排序

$it->asort();

foreach($it  as  $key=>$value){

echo $key.":".$value."\n";

}

常用的迭代器二:AppendIterator----------------------------------------------------------------------(按照顺序迭代访问几个不同的迭代器)

代码实现:

$array_a = new  ArrayIterator(array('a','b','c'));

$array_b = new  ArrayIterator(array('d','e','f'));

$it = new   AppendIterator();

$it->append($array_a);

$it->append($array_b);

foreach($it  as  $key=>$value){

echo $value."\n";

}

/*a

b

c

d

e

f*/

常用的迭代器三:MultipleIterator----------------------------------------------------------------------(将多个Iterator里面的数据组合成为一个整体来访问)

代码实现:

$idIter = new ArrayIterator(array('01','02','03'));

$nameIter = new ArrayIterator(array('张三','李四','王五'));

$ageIter = new ArrayIterator(array('21','23','25'));

$mit = new  MultipleIterator(MultipleIterator::MIT_KEY_ASSOC);

$mit->attachIterator($idIter,"ID");

$mit->attachIterator($nameIter,"NAME");

$mit->attachIterator($ageIter,"AGE");

foreach($mit  as  $value){

print_r($value);

}

/*

array(

[ID]=>01,

[NAME]=>张三,

[AGE]=>22

)

array(

[ID]=>02,

[NAME]=>李四,

[AGE]=>23

)

array(

[ID]=>03,

[NAME]=>王五,

[AGE]=>25

)

*/

常用的迭代器四:FilesystemIterator----------------------------------------------------------------------(遍历文件系统)

代码实现:

date_default_timezone_get('PRC');

$it = new  FilesystemIterator('.');    //.表示当前目录

foreach ($it  as  $finfo){

printf("%s\t%s%8s\t%s\n",

date("Y-m-d  H:i:s",$finfo->getMTime())."\n",     //打印出当前文件夹下的所有文件的格式化时间

$finfo->isDir()?

number_format($finfo->getSize()),                   //将文件大小格式化,每3位加逗号

$finfo->getFileName()

);

}

//******************************************SPL的基础接口************************************************************

1:理解Countable/OuterIterator/RecursiveIterator/SeekableIterator等4个接口的概念

2:熟练掌握Countable接口的使用

Countable:继承该接口的类可以直接调用count得到元素的个数

OuterIterator:如果想对迭代器进行一定的处理之后再返回,可以使用这个接口

RecursiveIterator:可以对多层结构的迭代器进行迭代,比如遍历一棵树

SeekableIterator:通过seek方法定位到集合里面的某一个特定元素

******************************************Countable接口*****************************************************

count(array('name'=>'Peter','id'=>'2'))

date_default_timezone_get('PRC')

$array=array (

array('name'=>'Jonathon','id'=>'2'),

array('name'=>'SEM','id'=>'2'),

array('name'=>'Tom','id'=>'2')

)

echo count($array);        //3  自数组个数

echo count($array[1]);     //2   第二个子数字的元素个数

class  CountMe   implements Countable {

protected   $_myCount=3;

public function  count(){

return   $this->_myCount;

}

}

$obj = new  CountMe();

echo count($obj);        //不加implements  Countable时显示1,加后显示为3!!!!!!!!!!

******************************************OuterIterator接口*****************************************************

如果想对迭代器进行一定的处理之后再返回,可以用这个接口

IteratorIterator类时OuterIterator类的实现,扩展的时候可以直接继承IteratorIterator

代码实现:

date_default_timezone_get('PRC');

$array=['Value1','Vlaue2','Vlaue3','Vlaue4'];

$outerObj = new OuterImpl(new Arrayi($array);

forach($outerObj  as  $key=>$value){

echo "++".$key."-".$vale."\n";            //$key会显示成Pre_0,$value会显示成Value1_tail

}

class  OuterImpl  extends   IteratorIterator{

public  function current(){                               //value

return  parent::current().'_tail';

}

public  function  key(){                             //key

return  "Pre_".parent::key();

}

}

******************************************RecursiveIterator接口*****************************************************

见doc的一张图,粗讲。

******************************************SeekableIterator接口*****************************************************

见doc的一张图,粗讲。

//******************************************SPL函数的使用************************************************************

1:

Autoload:为了初始化PHP中的类对象,需要通过一定的方法寻找类的定义。通常情况下,类会定义在一个单独的文件中。

Aotuload就是PHP找到这些类文件的方法。

class   Test{

public  function __construct(){

echo  "Loading   Class  libs/Test.php\n";

}

}

spl_autoload_extensions('.class.php,.php');                      //会自动加载Test.class.php,也可以设置为.php,两者也可俱在

set_include_path(get_include_path().PATH_SEPARATOR."libs/");     //将类的位置这只在libs/下

//设置autoload寻找定义的类文件的目录,多个目录用_PATH_SEPARATOR进行分割。

spl_autoload_register();                                         //PHP使用Autoload机制查找类定义

new   Test();

?>

2:

__autoload装载类

function  __autoload($class_name){

echo "__autoload  class :".$class_name."\n";

require_once("libs/".$class_name.'.php');

}

//也可以自定义一个类似__autoload方法

function  classLoader($class_name){

echo "classLoader  class :".$class_name."\n";

require_once("libs/".$class_name.'.php');

}

spl_autoload_register('classLoader');          //这样也就将__autoload方法重命名了,将__autoload方法顶替了

new  Test();

注:还可以将require_once替换成set_include_path顶替,代码实现如下:

function  classLoader($class_name){

echo "classLoader  class :".$class_name."\n";

set_include_path("libs/");

spl_autoload($class_name);         //当我们不用require或者require_once载入类文件的时候,而是想通过系统查找include_path来装载类时,必须显式调用spl_autoload函数,参数是类的名称来重启类文件的自动查找

}

spl_autoload_register('classLoader');

new  Test();

*************************************

总结:类载入的基本流程,参见doc文档一图。

*************************************

//******************************************SPL的文件处理类库************************************************************

两个类库

实现代码:

date_default_timezone_get("PRC");

$file = new  SqlFileInfo("tmp.txt");

echo "File  is  created   at".date("Y-m-d  H:i:s",$file->getCTime())."\n";     //查看文件的信息

echo "File  is  modified   at".date("Y-m-d  H:i:s",$file->getMTime())."\n";

//读取里面的内容

$fileObj = $file->openFile("r");             //以读的方式打开一个文件

while($fileObj->valid()){

echo $fileObj->fgets();          //fget获取文件里面的一行数据

}

$openObj = null;                   //用于关闭打开的文件

$file  null;

这里文件的读入方式是面向对象的,比fopen之类的函数要简洁,提倡使用!

****************************************************************************************************************

课程总结:略

****************************************************************************************************************

?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值