[英]PHP List Directory structure and exclude some directories
我有這個 PHP 代碼:
$rootpath = '../admin/';
$inner = new RecursiveDirectoryIterator($rootpath);
$fileinfos = new RecursiveIteratorIterator($inner);
foreach ($fileinfos as $pathname => $fileinfo)
{
$pathname2 = substr($pathname,2);
$sql = "SELECT * from admin_permissions where page_name = '$pathname2'";
$rs = mysql_query($sql,$conn);
if (mysql_num_rows($rs) == 0)
{
if (!$fileinfo->isFile()) continue;
$sql2 = "INSERT into admin_permissions (page_name) values ('$pathname2')";
$rs2 = mysql_query($sql2,$conn);
echo "$pathname<br>";
}
}
即顯示我的目錄結構並將目錄和文件名插入數據庫(刪除前 2 個字符..
)。
由於RecursiveDirectoryIterator
遍歷所有目錄中的所有文件,如何排除整個目錄,包括其中的所有文件?
本質上,我的回答與Thomas的回答沒有太大區別。 但是,他沒有正確理解以下幾點:
RecursiveCallbackFilterIterator
正確語義要求您返回true
以遞歸到子目錄中。.
和..
每個子目錄中的目錄in_array
檢查並不完全符合他的預期所以,我寫了這個答案。 這將正常工作,假設我明白你想要什么:
編輯:他已經修復了這三個問題中的兩個; 第三個可能不是問題,因為他寫條件支票的方式,但我不太確定。
<?php
$directory = '../admin';
// Will exclude everything under these directories
$exclude = array('.git', 'otherDirToExclude');
/**
* @param SplFileInfo $file
* @param mixed $key
* @param RecursiveCallbackFilterIterator $iterator
* @return bool True if you need to recurse or if the item is acceptable
*/
$filter = function ($file, $key, $iterator) use ($exclude) {
if ($iterator->hasChildren() && !in_array($file->getFilename(), $exclude)) {
return true;
}
return $file->isFile();
};
$innerIterator = new RecursiveDirectoryIterator(
$directory,
RecursiveDirectoryIterator::SKIP_DOTS
);
$iterator = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator($innerIterator, $filter)
);
foreach ($iterator as $pathname => $fileInfo) {
// do your insertion here
}
我建議使用 RecursiveCallbackFilterIterator。
$directory = '../admin/';
$filter = array('.git');
$fileinfos = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
$directory,
RecursiveDirectoryIterator::SKIP_DOTS
),
function ($fileInfo, $key, $iterator) use ($filter) {
return $fileInfo->isFile() || !in_array($fileInfo->getBaseName(), $filter);
}
)
);
foreach($fileinfos as $pathname => $fileinfo) {
//...
}
我的建議是嘗試使用 Symfony 的 finder 庫,因為它使很多事情變得更容易,並且可以通過 Composer 輕松安裝這里是文檔
http://symfony.com/doc/current/components/finder.html
這是一個簡單的例子,類似於我認為你在問什么
<?php
use Symfony\Component\Finder\Finder;
/**
* @author Clark Tomlinson <fallen013@gmail.com>
* @since 12/6/13, 12:52 PM
* @link http://www.clarkt.com
* @copyright Clark Tomlinson © 2013
*
*/
require_once('vendor/autoload.php');
$finder = new Finder();
$directories = $finder->directories()
->in(__DIR__)
->ignoreDotFiles(true)
->exclude(array('one', 'two', 'three', 'four'))
->depth(0);
foreach ($directories as $dir) {
echo '<pre>';
print_r($dir->getRealPath());
echo '</pre>';
}
該示例將返回所有目錄,而無需遍歷它們以更改該更改或刪除深度。
要獲取該目錄中的所有文件,請執行與此類似的操作
<?php
use Symfony\Component\Finder\Finder;
/**
* @author Clark Tomlinson <fallen013@gmail.com>
* @since 12/6/13, 12:52 PM
* @link http://www.clarkt.com
* @copyright Clark Tomlinson © 2013
*
*/
require_once('vendor/autoload.php');
$finder = new Finder();
$directories = $finder->directories()
->in(__DIR__)
->ignoreDotFiles(true)
->exclude(array('one', 'two', 'three', 'four'))
->depth(0);
foreach ($directories as $dir) {
$files = $finder->files()
->ignoreDotFiles(true)
->in($dir->getRealPath());
foreach ($files as $file) {
echo '<pre>';
print_r($file);
echo '</pre>';
}
}
您可以使用 RecursiveFilterIterator 來過濾目錄,並且在 fooreach 循環中您只接受目錄。
class MyDirFilter extends RecursiveFilterIterator {
public function accept() {
$excludePath = array('exclude_dir1', 'exclude_dir2');
foreach($excludePath as $exPath){
if(strpos($this->current()->getPath(), $exPath) !== false){
return false;
}
}
return true;
}
}
$rootpath = '../admin/';
$dirIterator = new RecursiveDirectoryIterator($rootpath);
$filter = new MyDirFilter($dirIterator);
$fileinfos = new RecursiveIteratorIterator($filter);
foreach($fileinfos as $pathname => $fileinfo)
{
// only accepted dirs in loop
}
我會讓它更簡單,有一些基本的 php 函數,易於閱讀(沒有三十部分,沒有對其他對象的委托),還有這幾行。
首先,您創建一個函數,它接收您要探索的目錄,以及一個可選的數組或排除的文件名
function getFiles($dir , $exclude=array()){
$acceptedfiles=array();
$handle=opendir($dir );
//reads the filenames, one by one
while ($file = readdir($handle)) {
if ($file!="." && $file!=".." && is_file($file) && !in_array($file, $exclude))
$acceptedfiles[]=$file;
}
closedir($handle);
return $acceptedfiles;
}
現在,你只需要調用函數
$files= getFiles($rootpath) ;
或者如果你想排除一些存在的文件,你可以調用
$files= getFiles($rootpath, array(".htaccess","otherfile", "etc")) ;
我會這樣做:
$excludes = array(
'files' => array('file1.ext','file2.ext','fileN.ext'),
'dirs' => array('dir1','dir2','dirN')
);
foreach ($directories as $current_dir) {
if (!in_array($current_dir,$excludes['dirs'])) {
// directory method
foreach ($files as $current_file) {
if (!in_array($current_file,$excludes['files'])) {
// files method
}
}
}
}
如果我猜對了你,那么你只想添加到文件的基本路徑,而不是目錄。
只需在 foreach 中用於檢查函數is_file
例如
foreach ($fileinfos as $pathname => $fileinfo)
{
if (!is_file($pathname))
{
continue;// next step
}
$pathname2 = substr($pathname,2);
...
}
我覺得其他一些答案很好,但比他們需要的要冗長。 這是一些簡單的代碼。 我的示例僅過濾.git
目錄,但您可以輕松將其擴展到其他項目:
<?php
$f_filter = fn ($o_file) => $o_file->getFilename() == '.git' ? false : true;
$o_dir = new RecursiveDirectoryIterator('.');
$o_filter = new RecursiveCallbackFilterIterator($o_dir, $f_filter);
$o_iter = new RecursiveIteratorIterator($o_filter);
foreach ($o_iter as $o_file) {
echo $o_file->getPathname(), "\n";
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.