回顾
上一篇文章我们讲到实战 PHP 数据结构基础之递归. 来回顾下什么是递归?
一般来说, 递归被称为函数自身的调用.
递归在开发中的实际运用
N 级分类
无限级的分类在平常的开发中是常见的需求, 并且在不少面试题中都会碰到. 不管你做什么项目, 应该都碰到过类似的问题. 下面, 我们就使用递归的思想, 实战一把.
SQL 结构
- CREATE TABLE `categories` ( `id` int(11) NOT NULL AUTO_INCREMENT,
- `categoryName` varchar(100) NOT NULL,
- `parentCategory` int(11) DEFAULT '0',
- `sortInd` int(11) NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
然后我们虚拟出一些数据出来, 最后长这个样子.
下面 我们直接看代码实现.
- <?php
- $dsn = "mysql:host=127.0.0.1;port=3306;dbname=light-tips;charset=UTF8;";
- $username = 'root';
- $password = 'admin';
- $pdo = new PDO($dsn, $username, $password);
- $sql = 'SELECT * FROM `categories` ORDER BY `parentCategory`, `sortInd`';
- $result = $pdo->query($sql, PDO::FETCH_OBJ);
- $categories = [];
- foreach ($result as $category) {
- $categories[$category->parentCategory][] = $category;
- }
- function showCategoryTree($categories, $n)
- {
- if (isset($categories[$n])) {
- foreach ($categories[$n] as $category) {
- echo str_repeat('-', $n) . $category->categoryName . PHP_EOL;
- showCategoryTree($categories, $category->id);
- }
- }
- return;
- }
- showCategoryTree($categories, 0);
可以看到, 我们首先获取到了所有的数据, 然后按照父级 ID 归类. 这是一个非常棒的数据结构. 想象一下, 我们把展示顶级目录下所有子目录的问题分解成了展示自己的类目标题和展示数据中 parentCategory 为当前目录 id 的子目录, 然后使用开始递归调用. 最后的输出是这个样子的.
无限嵌套评论
先来看下这个 无限嵌套评论长什么样子. 如图:
上面的栗子, 又是一个经典的可以使用递归解决的案例. 还是来看下数据结构.
- CREATE TABLE `comments` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `comment` varchar(500) NOT NULL,
- `username` varchar(50) NOT NULL,
- `datetime` datetime NOT NULL,
- `parentID` int(11) NOT NULL,
- `postID` int(11) NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
大家可以自己实践一遍, 先不要看下面的内容.
- <?php
- $dsn = "mysql:host=127.0.0.1;port=3306;dbname=light-tips;charset=UTF8;";
- $username = 'root';
- $password = 'admin';
- $pdo = new PDO($dsn, $username, $password);
- $sql = 'SELECT * FROM `comments` WHERE `postID` = :id ORDER BY `parentId`, `datetime`';
- $stmt = $pdo->prepare($sql);
- $stmt->setFetchMode(PDO::FETCH_OBJ);
- $stmt->execute([':id' => 1]);
- $result = $stmt->fetchAll();
- $comments = [];
- foreach ($result as $comment) {
- $comments[$comment->parentID][] = $comment;
- }
- function showComments(array $comments, $n)
- {
- if (isset($comments[$n])) {
- foreach ($comments[$n] as $comment) {
- echo str_repeat('-', $n) . $comment->comment . PHP_EOL;
- showComments($comments, $comment->id);
- }
- }
- return;
- }
- showComments($comments, 0);
文件扫描
使用递归进行目录文件的扫描的栗子.
- <?php
- function showFiles(string $dir, array &$allFiles)
- {
- $files = scandir($dir);
- foreach ($files as $key => $value) {
- $path = realpath($dir . DIRECTORY_SEPARATOR . $value);
- if (!is_dir($path)) {
- $allFiles[] = $path;
- } else if ($value != "." && $value != "..") {
- showFiles($path, $allFiles);
- $allFiles[] = $path;
- }
- }
- return;
- }
- $files = [];
- showFiles('.', $files);
- foreach ($files as $file) {
- echo $file . PHP_EOL;
- }
更多内容
PHP 基础数据结构专题系列目录地址: https://github.com/xx19941215/light-tips 主要使用 PHP 语法总结基础的数据结构和算法. 还有我们日常 PHP 开发中容易忽略的基础知识和现代 PHP 开发中关于规范, 部署, 优化的一些实战性建议, 同时还有对 Javascript 语言特点的深入研究.
来源: https://juejin.im/post/5b3e1fa55188251b134e54aa