zoukankan      html  css  js  c++  java
  • php spl标准库简介(SPL是Standard PHP Library(PHP标准库)(直接看代码实例,特别方便)

    php spl标准库简介(SPL是Standard PHP Library(PHP标准库)(直接看代码实例,特别方便)

    一、总结

    直接看代码实例,特别方便易懂

    thinkphp控制器利眠宁不支持(说明差文件引入么),但是view里面支持(也就是原生php支持),

    二、php spl标准库简介

    SPL简介

    SPL是用于解决典型问题(standard problems)的一组接口与类的集合。

    SPL是Standard PHP Library(PHP标准库)的缩写。
    目前在使用中,SPL更多地被看作是一种使object(对象)模仿array(数组)行为的interfaces和classes

    SPL的常用数据结构

    什么是数据结构?

    • 数据结构是计算机存储、组织数据的方式。是指相互之间存在的一种或多种特定关系的数据元素的集合。
    • 解决的是软件开发过程中的数据如何存储的问题

    数据结构之双向链表

    双向链表简介

    • Bottom:节点,第一个节点称Bottom
    • Top:最后添加的链表的节点称Top
    • 链表指针:可以指向任意节点;
    • 当前节点:链表指针指向的节点称为当前节点;
    • 节点细化成节点名称,和节点数据;

    数据结构之SplDoublyLinkedList

    SplDoublyLinkedList类提供了一个双向链表的主要功能
    当前节点操作:

    • rewind:将链表的当前指针指向第一个元素
    • current:链表当前指针,当节点被删除后,会指向空节点
    • prev:上一个
    • next:下一个

    增加节点操作:

    • push 在双向链表的结尾处将元素压入
    • unshift 前置双链表元素,预备值在双链表的开始

    删除节点操作:

    • pop 从双向链表的结尾弹出一个节点,不会改变指针位置
    • shift从双向链表的开头弹出一个节点,不会改变指针位置

    定位操作:

    • bottom 返回当前双向链表的第一个节点的值,当前指针不变
    • top返回当前双向链表的最后一个节点的值,当前指针不变

    特定节点操作:

    • offsetExists 理解为key是否存在
    • offsetGet将key节点拿出来
    • offsetSet把数据刷新
    • offsetUnset删除

    代码实现双向链表
    SplDoublyLinkedList.php

    <?php
    /**
    *SplDoublyLinkedList 类学习
    */
    $obj = new SplDoublyLinkedList();
    $obj -> push(1);//把新的节点添加到链表的顶部top
    $obj -> push(2);
    $obj -> push(3);
    $obj -> unshift(10);//把新节点添加到链表底部bottom
    print_r($obj);
    $obj ->rewind();//rewind操作用于把节点指针指向Bottom所在节点
    
    $obj -> prev();//使指针指向上一个节点,靠近Bottom方向
    echo 'next node :'.$obj->current().PHP_EOL;
    $obj -> next();
    $obj -> next();
    echo 'next node :'.$obj->current().PHP_EOL;
    
    $obj -> next();
    if($obj -> current())
            echo 'current node valid'.PHP_EOL;
    else
            echo 'current node invalid'.PHP_EOL;
    $obj ->rewind();
    //如果当前节点是有效节点,valid返回true
    if($obj->valid())
            echo 'valid list'.PHP_EOL;
    else
            echo 'invalid list'.PHP_EOL;
    print_r($obj);
    echo 'pop value :'.$obj -> pop().PHP_EOL;
    print_r($obj);
    echo 'next node :'.$obj ->current().PHP_EOL;
    $obj ->next();//1
    $obj ->next();//2
    $obj -> pop();//把top位置的节点从链表中删除,并返回,如果current正好指>向top位置,那么调用pop之后current()会失效
    echo 'next node:'.$obj -> current().PHP_EOL;
    print_r($obj);
    
    $obj ->shift();//把bottom位置的节点从链表中删除,并返回
    print_r($obj);

    数据结构之堆栈

    堆栈简介

    先进后出 first in last out

    继承自SplDoublyLinkedList类的SplStack类
    操作:

    • push压入堆栈
    • pop弹出堆栈

      代码示例

    <?php
    $stack = new SplStack();
    
    $stack -> push('a');
    $stack -> push('b');
    $stack -> push('c');//入栈
    
    print_r($stack);
    echo 'bottom:'.$stack -> bottom().PHP_EOL;
    echo "top:".$stack->top().PHP_EOL;
    //堆栈的offset=0,是TOP所在位置(即栈的末尾),offset=1是top位置节点靠近bottom位置的相连节点
    $stack -> offsetSet(0,'C');
    
    print_r($stack);
    
    //双向链表的rewind和堆栈的rewind,相反,堆栈的rewind使得当前指针指向top所在位置,而双向链表调用之后指向bottom所在位置
    $stack -> rewind();
    
    echo 'current:'.$stack->current().PHP_EOL;
    
    $stack ->next();//堆栈的next操作使指针指向靠近bottom位置的下一个节点,而双向链表是靠近top的下一个节点
    echo 'current:'.$stack ->current().PHP_EOL;
    
    //遍历堆栈
    
    $stack -> rewind();
    while ($stack->valid()) {
        echo $stack->key().'=>'.$stack->current().PHP_EOL;
        $stack->next();//不从链表中删除元素
    }
    
    //删除堆栈数据
    $popObj = $stack -> pop();//弹出最后一个元素,并删除该节点
    echo 'pop object:'.$popObj.PHP_EOL;
    print_r($stack);

    数据结构之队列

    • 队列和堆栈刚好相反,最先进入队列的元素会最新走出队列
    • 继承自SplDoublyLinkedList类的SplQueue类

      代码示例

    <?php
    
    $obj = new SplQueue();
    
    $obj -> enqueue('a');
    $obj -> enqueue('b');
    $obj -> enqueue('c');
    print_r($obj);
    
    echo 'bottom:'.$obj -> bottom().PHP_EOL;
    
    echo 'top:'.$obj -> top().PHP_EOL;
    //队列里的offset=0是指向bottom位置,offset=1是top方向相连的节点
    $obj -> offsetSet(0,'A');
    valid()
    print_r($obj);
    //队列里的rewind使得指针指向bottom所在位置的节点
    $obj -> rewind();
    echo 'current:'.$obj->current().PHP_EOL;
    
    while ($obj ->valid()) {
    
        echo $obj ->key().'=>'.$obj->current().PHP_EOL;
        $obj->next();//
    }
    //dequeue操作从队列中提取bottom位置的节点,并返回,同时从队列里面删除该元素
    echo 'dequeue obj:'.$obj->dequeue().PHP_EOL;
    
    print_r($obj);
    

    SPL的常用迭代器

    迭代器概述

    ArrayIterator

    • 熟悉使用seek()跳过元素
    • 熟悉使用asort,ksort排序
    <?php
    
    $fruits =  array(
            'apple'=>'apple value',
            'orange' => 'orange value',
            'grape' => 'grape value',
            'pear' => 'pear value'
        );
    
    print_r($fruits);//打印数组
    echo '*******user fruits directly'.PHP_EOL;
    foreach ($fruits as $key => $value) {
        # code...
        echo $key.':'.$value.PHP_EOL;
    }
    //使用ArrayIterator遍历数组
    $obj = new ArrayObject($fruits);
    $it = $obj -> getIterator();//获得迭代器
    echo '*******user ArrayIterator in for'.PHP_EOL;
    foreach ($it as $key => $value) {
        # code...
        echo $key.':'.$value.PHP_EOL;
    }
    echo '*******user ArrayIterator in while'.PHP_EOL;
    $it -> rewind();//调用current之前一定要先调用rewind
    while ($it -> valid()) {
        echo $it -> key().':'.$it->current().PHP_EOL;
        $it -> next();//这个必须加上,要不然死循环
    }
    
    //跳过某些元素进行打印
    echo '*******user seek before while'.PHP_EOL;
    $it ->rewind();
    if($it->valid()){
        $it->seek(1);//跳过第一个元素
        while ($it -> valid()) {
            echo $it -> key().':'.$it->current().PHP_EOL;
            $it -> next();//这个必须加上,要不然死循环
        }
    }
    echo '*******user ksort'.PHP_EOL;
    $it->ksort();//对key字典排序
    foreach ($it as $key => $value) {
        # code...
        echo $key.':'.$value.PHP_EOL;
    }
    echo '*******user asort'.PHP_EOL;
    $it->asort();//对value字典排序
    foreach ($it as $key => $value) {
        # code...
        echo $key.':'.$value.PHP_EOL;
    }

    AppendIterator

    能陆续遍历几个迭代器

    • -按顺序迭代几个不同的迭代器,例如,希望在一次循环中迭代访问两个或多个组合
    <?php
    
    $array_a = new ArrayIterator(array('a','b','c','d'));
    
    $array_b = new ArrayIterator(array('e','f','e','g'));
    
    $it = new AppendIterator();
    $it ->Append($array_a);
    //通过append方法把迭代器对象添加到AppendIterator对象中
    $it -> append($array_b);
    foreach ($it as $key => $value) {
        # code...
        echo $value.PHP_EOL;
    }

    MultipleIterator

    一个迭代器,依次遍历所有附加的迭代器

    • 用于把多个Iterator里面的数据组合成一个整体来访问
    <?php
     ini_set('display_errors', '1');
     error_reporting(E_ALL);
    $id_iter = new ArrayIterator(array('01','02','03'));
    
    $name_iter = new ArrayIterator(array('张三','李四','王五'));
    
    $age_iter = new ArrayIterator(array('21','22','23'));
    
    $mit = new MultipleIterator (MultipleIterator::MIT_KEYS_ASSOC);
    
    $mit -> attachIterator($id_iter,'ID');
    
    $mit -> attachIterator($name_iter,'name');
    $mit -> attachIterator($age_iter,'age');
    
    foreach ($mit as $key => $value) {
        # code...
        print_r($value);
    }

    FilesystemIterator

    遍历文件系统

    <?php
    //显示当前目录下的所有文件、大小、创建时间
    
    $it = new FileSystemIterator('.');
    date_default_timezone_set('PRC');
    foreach ($it as $key => $file_info){
        # code...
        printf('%s	%s	%8s	%s
    ',
               date('Y-m-d H:i:s',$file_info->getMTime()),
               $file_info->isDir() ? "<dir>" : '',
               number_format($file_info->getsize()),
               $file_info->getFileName()
              );
    }

    SPL基础接口

    接口简介

    • 理解Countable、OuterIterator、RecursiveIterator和SeekableIterator接口的概念
    • 掌握Countable接口的使用
      SPL的基础接口里面定义了最常用的接口
    • Countable继承了该接口的类可以直接调用count()得到元素的个数
    • OuterIterator如果想对迭代器进行一定的处理之后再返回,可以用这个接口
    • RecursiveIterator可以对多层结构的迭代器进行迭代,比如遍历一棵树
    • SeekableIterator可以通过seek方法定位到集合里面的某个特定的元素

    Countable接口

    类实现 Countable 可被用于 count() 函数.

    <?php 
    //Example One, BAD :( 
    
    class CountMe 
    { 
    
        protected $_myCount = 3; 
    
        public function count() 
        { 
            return $this->_myCount; 
        } 
    
    } 
    
    $countable = new CountMe(); 
    echo count($countable); //result is "1", not as expected 
    echo $countable->count;//result is "3"
    //Example Two, GOOD :) 
    
    class CountMe implements Countable 
    { 
    
        protected $_myCount = 3; 
    
        public function count() 
        { 
            return $this->_myCount; 
        } 
    
    } 
    
    $countable = new CountMe(); 
    echo $countable->count();//result is "3"
    echo count($countable); //result is "3" as expected 
    ?>

    OuterIterator接口

    • OuterIterator如果想对迭代器进行一定的处理之后再返回,可以用这个接口
    • IteratorIterator类是OuterIterator的实现,扩展的时候可以直接继承IteratorIterator
    <?php
    
    
    /**
    *  
    */
    class outerImpl extends IteratorIterator
    {
    
        public function current()
        {
            # code...
            return parent::current().'_tail';
        }
        public function key()
        {
            return 'pre_'.parent::key();
        }
    }
    
    $array = ['value1','value2','value3','value4'];
    
    $outerObj = new outerImpl(new ArrayIterator($array));
    
    foreach ($outerObj as $key => $value) {
        # code...
        echo '++'.$key.'-'.$value.PHP_EOL;
    }
    

    RecursiveIterator接口

    • 可以对多层结构的迭代器进行迭代,比如遍历一棵树
    • 所有具有层次结构特点的数据都可以用这个接口遍历,如文件夹
    • 关键方法
      • hasChildren方法可以用于判断当前节点是否存在子节点
      • getChildren方法用于得到当前节点子节点的迭代器
    • SPL中实现该接口的类
    • RecursiveArrayIterator,RecuriveCachingIterator等以Recurive开头的类都可以进行多层次结构化遍历

    SeekableIterator接口

    • SeekableIterator
      • 可以通过seek方法定位到集合里面的某个特定的元素
      • seek方法的参数是元素的位置,从0开始计算
    • SPL中实现该接口的类
      • ArrayIterator、DirectoryIterator、FilesystemIterator、GlobIterator、RecursiveArrayIterator、RecursiveDirectoryIterator

    SPL函数的使用

    使用spl_autoload_register装载类

    <?php
    
    /**
    * libs/Test.class.php 
    */
    class Test 
    {
    
        function __construct()
        {
            # code...
            echo 'loading class libs/Test.class.php
    ';
        }
    }
    
    
    /**
    * autoload.php 
    */
    //设置autoload寻找php定义的类文件的扩展名,多个扩展名用逗号分隔,前面的扩展名优先匹配
    spl_autoload_extensions('.class.php,.php');
    //设置autoload寻找PHP定义的类文件的目录,多个目录用PATH_SEPARATOR进行分隔
    set_include_path(get_include_path().PATH_SEPARATOR.'libs/');
    //提示PHP使用autoload机制查找类定义
    spl_autoload_register();
    new Test();
    
    

    __autoload装载类

    <?php
    
    function __autoload($class_name){
        //定义autoload函数,可以在不调用spl_autoload_register函数的情况下完成类的装载
        echo '__autoload class :'.$class_name.PHP_EOL;
        require_once 'libs/'.$class_name.'.php';//装载类
    }
    //定义一个替换__autoload函数的类文件装载函数
    function classLoader($class_name){
        echo 'classloader() load class : '.$class_name.PHP_EOL;
        require_once 'libs/'.$class_name.'.php';//装载类
    }
    //传入定义好的装载类的函数的名称替换__autoload函数
    spl_autoload_register('classLoader');
    
    new Test();

    自定义__autoload函数装载类

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

    SPL函数调用过程

    SPL其他函数

    SPL的文件处理类

    <?php
    
    date_default_timezone_set('PRC');
    
    $file = new SplFileInfo('tmp.txt');
    
    echo 'file is created at '.date('Y-m-d H:i:s',$file->getCTime()).PHP_EOL;
    
    echo 'file is modifyed at '.date('Y-m-d H:i:s',$file->getMTime()).PHP_EOL;
    
    echo 'file size is '.$file->getSize().'bytes'.PHP_EOL;
    
    //读取文件里的内容
    $fileObj = $file -> openFile('r');
    
    while ($fileObj ->valid()) {
        # code...
        echo $fileObj->fgets();
    }
    //销毁对象
    $fileObj = null;
    $file  = null;
  • 相关阅读:
    3 面向过程与面向对象进一步比较
    2 类、实例、属性、方法详解
    1 面向对象介绍
    CentOS5、6 NFS的安装配置及mount方法
    js 冒泡 捕获
    js定义类或对象
    new Option()——实现时间联动
    js闭包(转)
    (转)大型网站系统架构的演化
    30款最好的 Bootstrap 3.0 免费主题和模板
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/9034289.html
Copyright © 2011-2022 走看看