递归练习题

注意: 递归层数不宜太深,否则会消耗很多资源。

1. 创建级联目录

  • 方法一(用递归):
function mdir($path)
{
   if(is_dir($path)||@mkdir($path)){
       echo "创建{$path}成功<br>";
   }
   else{
       $p=dirname($path);
       mdir($p);
       if(@mkdir($path)){//此行为重点部分
        echo "创建{$path}成功<br>";
};
   }
}
mdir('q/w/e/r');
  • 方法二(用函数):
if (mkdir('./q/w/f',0777,true)){
    echo '创建成功';
}
else{
    echo '创建失败';
}
  • 方法三(用迭代):
function diedai($dir)
{
    if (is_dir($dir)) {
        echo '该目录已存在';
    }
    $mk = [];
    while (!is_dir($dir)) {
        $mk[] = $dir;
        $dir = dirname($dir);
    }
    $count = count($mk);
    for ($i = $count - 1; $i >= 0; $i--) {
            mkdir($mk[$i]);
            echo $mk[$i] . "创建成功<br>";
    }
}

2. 递归删除目录

function undir($path)
{
    if ($path == '/' || $path == '../') return false;
    if (is_dir($path)) {
        $diff = array_diff(scandir($path), ['..', '.']);
        foreach ($diff as $value) {
            $p = $path . '\\' . $value;
            undir($p);
        }
        @rmdir($path);//此行为重点部分


    } else {
        unlink($path);
        echo '已删除文件' . $path;
    }
}

2019/04/18 16:44 修改代码如下

function rm($file)
{
    if (is_file($file)) {
        if (unlink($file)) {
            echo "删除文件{$file}成功<br>";
        }
    } elseif (is_dir($file)) {
        $diff = array_diff(scandir($file), ['.', '..']);
        if (empty($diff)) {
            if (rmdir($file)) {
                echo "删除文件夹{$file}成功<br>";
            }
        } else {
            print_r($diff);
            foreach ($diff as $value) {
                rm("{$file}/" . $value);
                //修改的内容如下:
                array_shift($diff);
                if (empty($diff)) {
                    if (rmdir($file)){
                        echo "删除文件夹{$file}成功<br>";
                    }
                }
            }
        }

    }
}

解释: 修改的地方主要在于:把方法二中的@rmdir($path)修改了一下。

3. 递归打印级联目录

function scan($dir, $level = 0)
{
    if (file_exists($dir)) {
        echo str_repeat('|&nbsp;&nbsp;', $level) . '|' .basename( $dir) . '<br>';
        if (is_dir($dir)) {
            $diff = array_diff(scandir($dir), ['.', '..']);
            if ($diff) {
                foreach ($diff as $value) {
                    scan($dir . '/' . $value, $level + 1);
                }
            }
        }
    }
}

4. 无限级分类

2019-06-05补充: 其实就是根据pid字段把数组元素重新排序。

/**
 * @param $array 分类数据
 * @param int $pid 父ID
 * @param int $level 分类级别
 * @return array $list 分类好的数组,直接遍历即可,$level可以用来遍历缩进
 */


function wuxian($array,$pid=0,$level=0)
{
    //声明静态数组,避免递归调用时,多次声明导致数组覆盖
    static $list=[];
    foreach ($array as $key => $value) {
        //第一次遍历,找到父节点为根节点的节点 也就是pid=0的节点
        if ($value['pid'] == $pid) {
            //父节点为根节点的节点,级别为0,也就是第一级
            $value['level']=$level;
            //把数组放到list中
            $list[]=$value;
            //把这个节点从数组中移除,减少后续递归消耗
            unset($array[$key]);
            //开始递归,查找父ID为该节点ID的节点,级别则为原级别+1
            wuxian($array, $value['id'],$level+1);
        }

    }
    return $list;
}
$data = array(
    1 => array('id' => 1, 'pid' => 0, 'name' => '中国'),
    2 => array('id' => 2, 'pid' => 0, 'name' => '美国'),
    3 => array('id' => 3, 'pid' => 1, 'name' => '广东省'),
    4 => array('id' => 4, 'pid' => 3, 'name' => '广州市'),
    5 => array('id' => 5, 'pid' => 4, 'name' => '天河区'),
    6 => array('id' => 6, 'pid' => 1, 'name' => '湖南省'),
    7 => array('id' => 7, 'pid' => 2, 'name' => '洛杉矶'),
    8 => array('id' => 8, 'pid' => 6, 'name' => '长沙市'),
    9 => array('id' => 9, 'pid' => 2, 'name' => '华盛顿'),
);
 /*
 * 获得递归完的数据,遍历生成分类
  */
$re = wuxian($data);
foreach ($re as $value){
    echo str_repeat('&emsp;&emsp;',$value['level']),$value['name'],'<br>';
}

结果如下图:
在这里插入图片描述
参考:php无限级分类两种方式

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值