dongliang1893 2016-09-07 10:17
浏览 17
已采纳

在一个巨大的站点中使用PHP的所有文件的列表

I need to do a list of all files on a server from an other server.

I don't have access to PHP config like maximum timeout of the remote server. The maximum timeout could be very short like 30s. In some case, the following code gives a Timeout issue, because the iterator don't have enough time to get all the files.

public function getStructure($path)
    {
        $structure = new \stdClass();
        $structure->dirs = array();
        $structure->files = array();
        $iterator = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::SELF_FIRST);
        foreach ($iterator as $file)
        {
            if ($file->isDir())
            {
                $structure->dirs[] = $file->getRealpath();
            }
            else
            {
                $structure->files[] = $file->getRealpath();
            }
        }

        return $structure;
    }

I'm looking for a way to get the structure in multiple calls. Something like : myremotesite.com/api/v1/structrue?start=xxxx where start is the point where the last call stop.

Thanks for your help

  • 写回答

1条回答 默认 最新

  • duandi1919 2016-09-07 12:02
    关注

    sounds like you need a dir with save/resume functionality... i would probably implement it in SQLite, due to its synchronous-by-default nature.

    since i was bored.. UNTESTED, but should work in theory. DO NOT try to implement beginTransaction() / commit() optimizations to this code, that would defeat the whole "synchronous and tolerates crashing at any moment" part of the code;

    <?php 
    //will return bool(true) when it's finished creating the database.
    //should be timeout/unstable system resistant, 
    //relying on SQLite's syncronous-by-default nature.
    function dirToSQLite($dir,$sqldb){
        if(!is_readable($dir)){
            throw new InvalidArgumentException('argument 1 must be a readable dir, but is not readable.');      
        }
        if(!is_dir($dir)){
            throw new InvalidArgumentException('argument 1 is not a valid dir');
        }
    $db=new PDO('sqlite:'.$sqldb,'','',array(PDO::ATTR_EMULATE_PREPARES => false,PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
    $db->exec('CREATE TABLE IF NOT EXISTS `dir` (`id` INTEGER PRIMARY KEY,`path` TEXT UNIQUE,`type` TEXT);');
    $db->query('INSERT OR IGNORE INTO `dir` (`path`,`type`) VALUES('.$db->quote($dir).',\'dirUnexplored\');');
    $stm=$db->prepare('INSERT INTO `dir` (`path`,`type`) VALUES(:path,:type);');
    $stmExplored=$db->prepare('UPDATE `dir` SET `type` = \'dir\' WHERE id = ? ');
    $path='';
    $type='';
    $stm->bindParam(':path',$path,PDO::PARAM_STR);
    $stm->bindParam(':type',$type,PDO::PARAM_STR);
    while(true){
        $found=false;
        foreach($db->query('SELECT `id`,`path` FROM `dir` WHERE `type` = \'dirUnexplored\'') as $res)
        {
            $found=true;
            $di=new DirectoryIterator($res['path']);
            foreach($di as $file){
                if($file->isDot()){
                    continue;
                } else
                if($file->isLink()){
                    $type='link';
                } else
                if($file->isDir()){
                    $type='dirUnexplored';
                } else
                if($file->isFile()){
                    $type='file';
                } else
                {
                    $type='unknown';
                }
                $path=$file->getPathname();
                $stm->execute();
            }
            $stmExplored->execute(array($res['id']));
        }
        if(!$found){
            break;
        }
    }
    return true;
    }
    if(true===dirToSqlite('/home/foo','homefoo.db3')){
    echo "finished!";
    }else {
    throw new Exception();
    }
    

    then just keep calling that url until it returns the string "finished!", then you can download the SQLite database directly, no php involved in the download.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 mmocr的训练错误,结果全为0
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀