当前位置:首页>

文章详细页

PHP标准库SPL实例

分类:PHP


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


递归寻找指定目录中的所需文件

双向链表

栈的应用 - 检测数学表达式

//迭代器-递归树


迭代是常见设计模式之一,普遍应用于一组数据中的统一的遍历操作。可以毫不夸张的说,SPL提供了所有你需要的对应数据类型的迭代器。


===================遍历目录

常规的做法就是使用 scandir ,然后跳过 . 和 .. ,以及其它未满足条件的文件。例如你需要遍历个某个目录抽取其中的图片文件,就需要判断是否是 png、md 结尾。

下面的代码就是使用 SPL 的迭代器执行上述递归寻找指定目录中的所需文件的例子


<?php
class RecursiveFileFilterIterator extends FilterIterator {
    // 满足条件的扩展名
    protected $ext = array('png','md');
    //提供 $path 并生成对应的目录迭代器
    public function __construct($path) {
        parent::__construct(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)));
    }
    //检查文件扩展名是否满足条件
    public function accept() {
        $item = $this->getInnerIterator();
        if ($item->isFile() && in_array(pathinfo($item->getFilename(), PATHINFO_EXTENSION), $this->ext)){
            return TRUE;
        }
    }

}


// 实例化
foreach (new RecursiveFileFilterIterator('./') as $item) {
    echo $item."<br>";

}

/*
.\1.png
.\2.png
.\README.md

*/


/*
 * ===================SPL-双向链表
 * 运行要求:PHP7+
 *
 * SplDoublyLinkedList
 */

$nameList = new SplDoublyLinkedList();

$nameList->push("ccw");
$nameList->push("ccy");
$nameList->push("cct");
$nameList->push("ccm");
$nameList->add(1,"ccd");
$nameList->add(4,"ccp");

for($nameList->rewind();$nameList->valid();$nameList->next()){   
    echo $nameList->current()."\n";
}
/*
ccw
ccd
ccy
cct
ccp
ccm
*/



/*
 * ===================栈的应用 - 检测数学表达式
 */

function expressionChecker(string $expression): bool {
    $valid = TRUE;//有效性
    $stack = new SplStack();
    //循环表达式-入栈检测
    for ($i = 0; $i < strlen($expression); $i++) {
        $char = substr($expression, $i, 1);
        switch ($char) {
            case '(':
            case '{':
            case '[':
                $stack->push($char);//入栈
                break;
            case ')':
            case '}':
            case ']':
                if ($stack->isEmpty()) {//如果栈为空,无效
                    $valid = FALSE;
                } else {
                    $last = $stack->pop();
                    if ( ($char == ")" && $last != "(") || ($char == "}" && $last != "{") || ($char == "]" && $last != "[") ) {
                        $valid = FALSE;
                    }
                }
                break;
        }
        //如果有效性不为真-跳至下一循环
        if (!$valid)
            break;
    }

    if (!$stack->isEmpty()) {
        $valid = FALSE;
    }
    return $valid;
}
//测试
$expressions = [];
$expressions[] = "8 * (9 -2) + { (4 * 5) / ( 2 * 2) }";
$expressions[] = "5 * 8 * 9 / ( 3 * 2 ) )";
$expressions[] = "[{ (2 * 7) + ( 15 - 3) ]";

foreach ($expressions as $expression) {
    $valid = expressionChecker($expression);

    if ($valid) {
    echo "Expression is valid \n";
    } else {
    echo "Expression is not valid \n";
    }
}
/*
Expression is valid
Expression is not valid
Expression is not valid
*/


//===================迭代器-递归树
$teams = array(
    'Popular Football Teams',
    array(
        'La Lega',
        array('Real Madrid', 'FC Barcelona', 'Athletico Madrid', 'Real Betis', 'Osasuna')
    ),
    array(
        'English Premier League',
        array('Manchester United', 'Liverpool', 'Manchester City', 'Arsenal', 'Chelsea',
            array('Manchester United', 'Liverpool')
        )
    )
);

$tree = new RecursiveTreeIterator(
    new RecursiveArrayIterator($teams), null, null, RecursiveIteratorIterator::LEAVES_ONLY
);

foreach ($tree as $leaf)
    echo $leaf . PHP_EOL;
/*

|-Popular Football Teams
| |-La Lega
|   |-Real Madrid
|   |-FC Barcelona
|   |-Athletico Madrid
|   |-Real Betis
|   \-Osasuna
  |-English Premier League
    |-Manchester United
    |-Liverpool
    |-Manchester City
    |-Arsenal
    |-Chelsea
      |-Manchester United
      \-Liverpool

*/