我需要从其他服务器上列出服务器上的所有文件。
我无法访问PHP配置,例如远程服务器的最大超时。 最大超时可能非常短,如30秒。在某些情况下,以下代码会给出Timeout问题,因为迭代器没有足够的时间来获取所有文件。
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;
}
我正在寻找一种方法来获得多次调用的结构。例如:myremotesite.com/api/v1/structrue?start=xxxx其中start是最后一次呼叫停止的点。
感谢您的帮助
答案 0 :(得分:1)
听起来你需要一个具有保存/恢复功能的目录...我可能会在SQLite中实现它,因为它具有默认的同步特性。
因为我很无聊..未经考验,但理论上应该有效。不要试图对这段代码实施beginTransaction()/ commit()优化,这会使整个"同步并且随时容忍崩溃"部分代码;
<?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();
}
然后继续调用该url直到它返回字符串&#34;完成!&#34;,然后你可以直接下载SQLite数据库,下载中不涉及php。