Lo que busca también se llama directorio recursivo que atraviesa. Lo que significa que está revisando todos los directorios y listando subdirectorios y archivos allí. Si hay un subdirectorio, también se recorre y así sucesivamente, por lo que es recursivo.
Como puedes imaginar, esto es algo común que necesitas cuando escribes un software y PHP te apoya con eso. Ofrece un RecursiveDirectoryIterator
para que los directorios se puedan iterar recursivamente y el estándar RecursiveIteratorIterator
para realizar el recorrido. A continuación, puede acceder fácilmente a todos los archivos y directorios con un simple iteración, por ejemplo a través foreach
:
$rootpath = '.';
$fileinfos = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rootpath)
);
foreach($fileinfos as $pathname => $fileinfo) {
if (!$fileinfo->isFile()) continue;
var_dump($pathname);
}
Este ejemplo en primer lugar especifica el directorio en el que quiere realizar el desplazamiento.Yo he estado tomando el actual:
$rootpath = '.';
La siguiente línea de código es un poco largo, no una instancia the directory iterator y luego the iterator-iterator manera que la estructura en forma de árbol se puede recorrer en un solo bucle/apartamento :
$fileinfos = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rootpath)
);
Estos $fileinfos
son entonces itera con un simple foreach
:
foreach($fileinfos as $pathname => $fileinfo) {
interior de eso, hay una prueba para omitir todos los directorios de salida. Esto se hace utilizando el objeto SplFileInfo
que se itera. Es provisto por el iterador de directorio recursivo y contiene muchas propiedades y métodos útiles cuando se trabaja con archivos. También puede, por ejemplo, devolver la extensión de archivo, la información del nombre de base sobre el tamaño y la hora, etc., etc.
if (!$fileinfo->isFile()) continue;
Finalmente acabo de salida de la ruta que es la ruta completa al archivo:
var_dump($pathname);
Una salida ejemplar sería el siguiente (en este caso en un sistema operativo Windows):
string(12) ".\.buildpath"
string(11) ".\.htaccess"
string(33) ".\dom\xml-attacks\attacks-xml.php"
string(38) ".\dom\xml-attacks\billion-laughs-2.xml"
string(36) ".\dom\xml-attacks\billion-laughs.xml"
string(40) ".\dom\xml-attacks\quadratic-blowup-2.xml"
string(40) ".\dom\xml-attacks\quadratic-blowup-3.xml"
string(38) ".\dom\xml-attacks\quadratic-blowup.xml"
string(22) ".\dom\xmltree-dump.php"
string(25) ".\dom\xpath-list-tags.php"
string(22) ".\dom\xpath-search.php"
string(27) ".\dom\xpath-text-search.php"
string(29) ".\encrypt-decrypt\decrypt.php"
string(29) ".\encrypt-decrypt\encrypt.php"
string(26) ".\encrypt-decrypt\test.php"
string(13) ".\favicon.ico"
Si hay un subdirectorio al que no se puede acceder, lo siguiente arrojaría una excepción. Este comportamiento se puede controlar con algunas banderas cuando una instancia del RecursiveIteratorIterator
:
$fileinfos = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('.'),
RecursiveIteratorIterator::LEAVES_ONLY,
RecursiveIteratorIterator::CATCH_GET_CHILD
);
espero que esto era informativo. También puede ajustar esto en una clase propia y también puede proporcionar un FilterIterator
para mover la decisión de si un archivo debe aparecer o no en el registro foreach
.
El poder de la combinación RecursiveDirectoryIterator
y RecursiveIteratorIterator
sale de su flexibilidad. Lo que no se cubrió anteriormente se llama FilterIterator
s. Pensé que agregué otro ejemplo que está haciendo uso de dos escritos por ellos mismos, colocados uno dentro del otro para combinarlos.
- Uno es para filtrar todos los archivos y directorios que empiezan por un punto (los que se consideran los archivos ocultos en los sistemas UNIX lo que no debe dar esa información al exterior) y
- Otro que está filtrando el lista solo para archivos Ese es el cheque que anteriormente era dentro de el foreach.
Otro cambio en este ejemplo de uso es hacer uso de la getSubPathname()
function que devuelve el subtrazado partir de ruta_raíz de la iteración, por lo que el que usted está buscando.
También me explícitamente agregar el SKIP_DOTS
flag que evita atravesar .
y ..
(técnicamente no realmente necesario porque los filtros podrían filtrar esos también, ya que son directorios, sin embargo, creo que es más correcto) y la devuelve como caminos como UNIX_PATHS
por lo que las cadenas de caminos son caminos siempre Unix, independientemente del sistema operativo subyacente que normalmente es una buena idea si se solicitan esos valores a través de HTTP tarde como en su caso:
$rootpath = '.';
$fileinfos = new RecursiveIteratorIterator(
new FilesOnlyFilter(
new VisibleOnlyFilter(
new RecursiveDirectoryIterator(
$rootpath,
FilesystemIterator::SKIP_DOTS
| FilesystemIterator::UNIX_PATHS
)
)
),
RecursiveIteratorIterator::LEAVES_ONLY,
RecursiveIteratorIterator::CATCH_GET_CHILD
);
foreach ($fileinfos as $pathname => $fileinfo) {
echo $fileinfos->getSubPathname(), "\n";
}
Este ejemplo es similar al anterior uno, aunque cómo el $fileinfos
is build está configurado de forma diferente. Especialmente la parte sobre los filtros es nuevo:
new FilesOnlyFilter(
new VisibleOnlyFilter(
new RecursiveDirectoryIterator($rootpath, ...)
)
),
Así que el iterador directorio se pone en un filtro y el filtro en sí se pone en otro filtro. El resto no cambió.
El código para estos filtros es bastante sencillo, trabajan con la función accept
que es ya sea true
o false
que se va a tomar o para filtrar:
class VisibleOnlyFilter extends RecursiveFilterIterator
{
public function accept()
{
$fileName = $this->getInnerIterator()->current()->getFileName();
$firstChar = $fileName[0];
return $firstChar !== '.';
}
}
class FilesOnlyFilter extends RecursiveFilterIterator
{
public function accept()
{
$iterator = $this->getInnerIterator();
// allow traversal
if ($iterator->hasChildren()) {
return true;
}
// filter entries, only allow true files
return $iterator->current()->isFile();
}
}
Y eso es todo de nuevo. Naturalmente, puede utilizar estos filtros para otros casos también. P.ej. si tiene otro tipo de listado de directorio.
Y otra salida ejemplar con la $rootpath
corta distancia:
test.html
test.rss
tests/test-pad-2.php
tests/test-pad-3.php
tests/test-pad-4.php
tests/test-pad-5.php
tests/test-pad-6.php
tests/test-pad.php
TLD/PSL/C/dkim-regdom.c
TLD/PSL/C/dkim-regdom.h
TLD/PSL/C/Makefile
TLD/PSL/C/punycode.pl
TLD/PSL/C/test-dkim-regdom.c
TLD/PSL/C/test-dkim-regdom.sh
TLD/PSL/C/tld-canon.h
TLD/PSL/generateEffectiveTLDs.php
No más .git
o .svn
recorrido de directorio o lista de archivos como .builtpath
o .project
.
Nota para FilesOnlyFilter
y LEAVES_ONLY
: El filtro niega explícitamente el uso de directorios y enlaces basados en el SplFileInfo
objeto (only regular files that do exist). Entonces es un filtrado real basado en el sistema de archivos.
Otro método para obtener únicamente entradas que no sean de directorio se envía con RecursiveIteratorIterator
debido al valor predeterminado LEAVES_ONLY
flag (aquí también se usa en los ejemplos). Este indicador no funciona como un filtro y es independiente del iterador subyacente. Simplemente especifica que la iteración no debe devolver las ramas (aquí: directorios en el caso del iterador del directorio).
Entiendo la estructura de carpetas que tiene. Ahora, ¿cuál quiere que sea su resultado? ¡Actualice su ** resultado deseado ** en su pregunta! :) –
¿por qué le gustaría hacer eso? Tengo poca experiencia con php pero en mi opinión eso mataría a tu servidor deficiente. ¡Imagine a 5000 personas haciendo las lecturas de su estructura de directorios! – Tanmay
Bueno, porque quiero hacerlo es porque tengo un script en flash as3 que puede descargar un archivo a la vez. Flash no puede descargar una carpeta y sus contenidos, por lo que me gustaría que php cree una cadena de todos los contenidos de las carpetas/subcarpetas y la envíe a Flash y pueda comenzar a descargar el contenido en la aplicación. :) –