美文网首页
PHP里面的SPL函数

PHP里面的SPL函数

作者: followyounger1 | 来源:发表于2017-07-06 21:01 被阅读86次

    课程准备知识

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

    熟悉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;
    
     ?>

    相关文章

      网友评论

          本文标题:PHP里面的SPL函数

          本文链接:https://www.haomeiwen.com/subject/kzyucxtx.html