2016-09-07 4 views
-1

他のサーバーからサーバー上のすべてのファイルのリストを作成する必要があります。巨大なサイトにPHPがあるすべてのファイルのリスト

リモートサーバーの最大タイムアウトのようなPHP設定にアクセスできません。 最大タイムアウトは30秒と非常に短い場合があります。場合によっては、イテレータにすべてのファイルを取得するのに十分な時間がないため、次のコードでタイムアウトの問題が発生します。

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

'ini_set( 'max_execution_time'、1000);' – RiggsFolly

+0

@RiggsFolly彼は実行時間を編集できない愚かな共有ホスティングサービスを使用していると確信しています。 (そして実際、多くの人がphpスクリプトを常時監視し、30秒以上実行しているphpスクリプトで 'kill -s SIGKILL pid'を実行するデーモンを実行しています(byethost、000webhost、freewebhost.comなど)hell、evenプレミアムPAIDホスティングプロバイダの中にはproisp.noのようなものがあります – hanshenrik

+0

リモートサーバへのコンフィグレーションアクセスがないと言ったので、返事をありがとうございます。これは完全なPHPソリューションを探している理由です。 *)もロックされています。 –

答えて

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を呼び出し続ける「完成を!」、そして、あなたは直接SQLiteデータベース、ダウンロードに関与していないPHPをダウンロードすることができます。

+0

ありがとう、これは非常に巧妙なアプローチです。私はすでにMySQLのアクセスを持っているので、私はそれを使用します。 –

関連する問題