I would like to list all .jpg files from folders and subfolders.
I have that simple code:
<?php
// directory
$directory = "img/*/";
// file type
$images = glob("" . $directory . "*.jpg");
foreach ($images as $image) {
echo $image."<br>";
}
?>
But that lists .jpg files from img folder and one down.
How to scan all subfolders?
Php coming with the DirectoryIterator which can be very useful in that case.
Please note that this simple function can be easly improved by adding the whole path to a file instead the only file name, and maybe use something else instead of the reference.
/*
* Find all file of the given type.
* #dir : A directory from which to start the search
* #ext : The extension. XXX : Dont call it with "." separator
* #store : A REFERENCE to an array on which store the element found.
* */
function allFileOfType($dir, $ext, &$store) {
foreach(new DirectoryIterator($dir) as $subItem) {
if ($subItem->isFile() && $subItem->getExtension() == $ext)
array_push($store, $subItem->getFileName());
elseif(!$subItem->isDot() && $subItem->isDir())
allFileOfType($subItem->getPathName(), $ext, $store);
}
}
$jpgStore = array();
allFileOfType(__DIR__, "jpg", $jpgStore);
print_r($jpgStore);
As a directotry can contain subdirectories, and in their turn contains subdirectories, so we should use a recursive function. glob() is here not sufficient. This might work for you:
<?php
function getDir4JpgR($directory) {
if ($handle = opendir($directory)) {
while (false !== ($entry = readdir($handle))) {
if($entry != "." && $entry != "..") {
$str1 = "$directory/$entry";
if(preg_match("/\.jpg$/i", $entry)) {
echo $str1 . "<br />\n";
} else {
if(is_dir($str1)) {
getDir4JpgR($str1);
}
}
}
}
closedir($handle);
}
}
//
// call the recursive function in the main block:
//
// directory
$directory = "img";
getDir4JpgR($directory);
?>
I put this into a file named listjpgr.php. And in my Chrome Browser, it gives this capture:
A little stuck on this and hoping for some help. I'm trying to get the last modified dir from a path in a string. I know there is a function called "is_dir" and I've done some research but can't seem to get anything to work.
I don't have any code i'm sorry.
<?php
$path = '../../images/';
// echo out the last modified dir from inside the "images" folder
?>
For example: The path variable above has 5 sub folders inside the "images" dir currently right now. I want to echo out "sub5" - which is the last modified folder.
You can use scandir() instead of is_dir() function to do it.
Here is an example.
function GetFilesAndFolder($Directory) {
/*Which file want to be escaped, Just add to this array*/
$EscapedFiles = [
'.',
'..'
];
$FilesAndFolders = [];
/*Scan Files and Directory*/
$FilesAndDirectoryList = scandir($Directory);
foreach ($FilesAndDirectoryList as $SingleFile) {
if (in_array($SingleFile, $EscapedFiles)){
continue;
}
/*Store the Files with Modification Time to an Array*/
$FilesAndFolders[$SingleFile] = filemtime($Directory . '/' . $SingleFile);
}
/*Sort the result as your needs*/
arsort($FilesAndFolders);
$FilesAndFolders = array_keys($FilesAndFolders);
return ($FilesAndFolders) ? $FilesAndFolders : false;
}
$data = GetFilesAndFolder('../../images/');
var_dump($data);
From above example the last modified Files or Folders will show as Ascending order.
You can also separate your files and folder by checking is_dir() function and store the result in 2 different arrays like $FilesArray=[] and $FolderArray=[].
Details about filemtime() scandir() arsort()
Here's one way you can accomplish this:
<?php
// Get an array of all files in the current directory.
// Edit to use whatever location you need
$dir = scandir(__DIR__);
$newest_file = null;
$mdate = null;
// Loop over files in directory and if it is a subdirectory and
// its modified time is greater than $mdate, set that as the current
// file.
foreach ($dir as $file) {
// Skip current directory and parent directory
if ($file == '.' || $file == '..') {
continue;
}
if (is_dir(__DIR__.'/'.$file)) {
if (filemtime(__DIR__.'/'.$file) > $mdate) {
$newest_file = __DIR__.'/'.$file;
$mdate = filemtime(__DIR__.'/'.$file);
}
}
}
echo $newest_file;
This will work too just like the other answers. Thanks everyone for the help!
<?php
// get the last created/modified directory
$path = "images/";
$latest_ctime = 0;
$latest_dir = '';
$d = dir($path);
while (false !== ($entry = $d->read())) {
$filepath = "{$path}/{$entry}";
if(is_dir($filepath) && filectime($filepath) > $latest_ctime) {
$latest_ctime = filectime($filepath);
$latest_dir = $entry;
}
} //end loop
echo $latest_dir;
?>
I'm a bit confused.
I'm building a PHP function to loop out images in a specified dir.
PHP
$dir = "bilder/".$objekt[0]['objekt_nr']."/thumbnail/";
$thumbnails = scandir($dir);
print_r($thumbnails);
foreach ($thumbnails as $value) {
echo "<img src='".$dir.$value. "'>";
}
array
(
[0] => .
[1] => ..
[2] => bjornc.jpg
[3] => test_bild3.jpg
)
HTML
<img src='bilder/22159/thumbnail/.'>
<img src='bilder/22159/thumbnail/..'>
<img src='bilder/22159/thumbnail/bjornc.jpg'>
<img src='bilder/22159/thumbnail/test_bild3.jpg'>
How can i get rid of theese dots?
I guess it´s the directorie dots..
UPDATE
The most easy way was found in php.net manual
$thumbnails = array_diff(scandir($dir), array('..', '.'));
The dot directory is the current directory. Dot-dot is the parent directory.
If you want to create a list of files in a directory you should really skip those two, or really any directory starting with a leading dot (on POSIX systems like Linux and OSX those are supposed to be hidden directories).
You can do that by simply check if the first character in the file name is a dot, and if it is just skip it (i.e. you continue the loop).
You can skip it by using in_array as
foreach ($thumbnails as $value) {
if (!in_array($value, array(".", ".."))) {
echo "<img src='" . $dir . $value . "'>";
}
}
You can also use this
foreach ($thumbnails as $value) {
if ( $value !='.' && $value !='..')
{
echo "<img src='".$dir.$value. "'>";
}
}
If you are looking for a specific file type, such as images, you are better off using glob.
It allows you to pass a pattern of extensions.
This way you can be sure you fetch only the files you are looking for.
Example for multiple file types, .jpg and .png
$dir = "bilder/".$objekt[0]['objekt_nr']."/thumbnail/";
$files = glob("*.{jpg,png}", GLOB_BRACE);
print_r($files);
GLOB_BRACE - Expands {a,b,c} to match 'a', 'b', or 'c'
Example for a single file type, .jpg
$dir = "bilder/".$objekt[0]['objekt_nr']."/thumbnail/";
$files = glob("*.jpg");
print_r($files);
they are directory and parent directory, they can be removed with following code:
<?php
$dir = "downloads/";
if (is_dir($dir)){
if ($dir_handler = opendir($dir)){
while (($file = readdir($dir_handler)) !== false){
if ($file!="."&&$file!="..") {
//your code
}
}
closedir($dir_handler);
}
}
?>
#joachim Pileborg answer is correct, By the way you can also use glob()
$thumbnails = glob("$dir/*.jpg");
foreach ($thumbnails as $value) {
echo "<img src='$value'/>";
}
Need help for a php script / page for generating links to folders.
Have a homepage with photos that I upload using Lightroom – each album in a separate folder.
The structure is:
mysite.com
|--images
|--folder1
|--folder2
|--folder3
.
.
So I would like to end up with a dynamic index.php file that generates links to all the subfolders of “images” instead of the static index.html file I got in the root of mysite.com:
<html>
<body>
folder1
folder2
folder3
.
.
</body>
</html>
Thanx in advance
<?php
$files = scandir();
$dirs = array(); // contains all your images folder
foreach ($files as $file) {
if (is_dir($file)) {
$dirs[] = $file;
}
}
?>
use dirs array for dynamically generating links
Maybe something like this:
$dir = "mysite.com/images/";
$dh = opendir($dir);
while ($f = readdir($dh)) {
$fullpath = $dir."/".$f;
if ($f{0} == "." || !is_dir($fullpath)) continue;
echo "$f\n";
}
closedir($dh);
When I need everything (i.e., something/*), I prefer readdir() over glob() because of speed and less memory consumption (reading a directory file by file, instead of getting the whole thing in an array).
If I'm not mistaken, glob() does omit .*files and has no need for the $fullpath variable, so if you're after speed, you might want to do some testing.
Try something like this:
$contents = glob('mysite.com/images/*');
foreach ($contents as content) {
$path = explode('/', $content);
$folder = array_pop($path);
echo '' . $folder . '';
}
Or also this:
if ($handle = opendir('mysite.com/images/') {
while (false !== ($content = readdir($handle))) {
echo echo '' . $content . '';
}
closedir($handle);
}
For example I had a folder called `Temp' and I wanted to delete or flush all files from this folder using PHP. Could I do this?
$files = glob('path/to/temp/*'); // get all file names
foreach($files as $file){ // iterate files
if(is_file($file)) {
unlink($file); // delete file
}
}
If you want to remove 'hidden' files like .htaccess, you have to use
$files = glob('path/to/temp/{,.}*', GLOB_BRACE);
If you want to delete everything from folder (including subfolders) use this combination of array_map, unlink and glob:
array_map( 'unlink', array_filter((array) glob("path/to/temp/*") ) );
This call can also handle empty directories ( thanks for the tip, #mojuba!)
Here is a more modern approach using the Standard PHP Library (SPL).
$dir = "path/to/directory";
if(file_exists($dir)){
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ( $ri as $file ) {
$file->isDir() ? rmdir($file) : unlink($file);
}
}
foreach (new DirectoryIterator('/path/to/directory') as $fileInfo) {
if(!$fileInfo->isDot()) {
unlink($fileInfo->getPathname());
}
}
This code from http://php.net/unlink:
/**
* Delete a file or recursively delete a directory
*
* #param string $str Path to file or directory
*/
function recursiveDelete($str) {
if (is_file($str)) {
return #unlink($str);
}
elseif (is_dir($str)) {
$scan = glob(rtrim($str,'/').'/*');
foreach($scan as $index=>$path) {
recursiveDelete($path);
}
return #rmdir($str);
}
}
$dir = 'your/directory/';
foreach(glob($dir.'*.*') as $v){
unlink($v);
}
Assuming you have a folder with A LOT of files reading them all and then deleting in two steps is not that performing.
I believe the most performing way to delete files is to just use a system command.
For example on linux I use :
exec('rm -f '. $absolutePathToFolder .'*');
Or this if you want recursive deletion without the need to write a recursive function
exec('rm -f -r '. $absolutePathToFolder .'*');
the same exact commands exists for any OS supported by PHP.
Keep in mind this is a PERFORMING way of deleting files. $absolutePathToFolder MUST be checked and secured before running this code and permissions must be granted.
See readdir and unlink.
<?php
if ($handle = opendir('/path/to/files'))
{
echo "Directory handle: $handle\n";
echo "Files:\n";
while (false !== ($file = readdir($handle)))
{
if( is_file($file) )
{
unlink($file);
}
}
closedir($handle);
}
?>
The simple and best way to delete all files from a folder in PHP
$files = glob('my_folder/*'); //get all file names
foreach($files as $file){
if(is_file($file))
unlink($file); //delete file
}
Got this source code from here - http://www.codexworld.com/delete-all-files-from-folder-using-php/
unlinkr function recursively deletes all the folders and files in given path by making sure it doesn't delete the script itself.
function unlinkr($dir, $pattern = "*") {
// find all files and folders matching pattern
$files = glob($dir . "/$pattern");
//interate thorugh the files and folders
foreach($files as $file){
//if it is a directory then re-call unlinkr function to delete files inside this directory
if (is_dir($file) and !in_array($file, array('..', '.'))) {
echo "<p>opening directory $file </p>";
unlinkr($file, $pattern);
//remove the directory itself
echo "<p> deleting directory $file </p>";
rmdir($file);
} else if(is_file($file) and ($file != __FILE__)) {
// make sure you don't delete the current script
echo "<p>deleting file $file </p>";
unlink($file);
}
}
}
if you want to delete all files and folders where you place this script then call it as following
//get current working directory
$dir = getcwd();
unlinkr($dir);
if you want to just delete just php files then call it as following
unlinkr($dir, "*.php");
you can use any other path to delete the files as well
unlinkr("/home/user/temp");
This will delete all files in home/user/temp directory.
Another solution:
This Class delete all files, subdirectories and files in the sub directories.
class Your_Class_Name {
/**
* #see http://php.net/manual/de/function.array-map.php
* #see http://www.php.net/manual/en/function.rmdir.php
* #see http://www.php.net/manual/en/function.glob.php
* #see http://php.net/manual/de/function.unlink.php
* #param string $path
*/
public function delete($path) {
if (is_dir($path)) {
array_map(function($value) {
$this->delete($value);
rmdir($value);
},glob($path . '/*', GLOB_ONLYDIR));
array_map('unlink', glob($path."/*"));
}
}
}
Posted a general purpose file and folder handling class for copy, move, delete, calculate size, etc., that can handle a single file or a set of folders.
https://gist.github.com/4689551
To use:
To copy (or move) a single file or a set of folders/files:
$files = new Files();
$results = $files->copyOrMove('source/folder/optional-file', 'target/path', 'target-file-name-for-single-file.only', 'copy');
Delete a single file or all files and folders in a path:
$files = new Files();
$results = $files->delete('source/folder/optional-file.name');
Calculate the size of a single file or a set of files in a set of folders:
$files = new Files();
$results = $files->calculateSize('source/folder/optional-file.name');
<?
//delete all files from folder & sub folders
function listFolderFiles($dir)
{
$ffs = scandir($dir);
echo '<ol>';
foreach ($ffs as $ff) {
if ($ff != '.' && $ff != '..') {
if (file_exists("$dir/$ff")) {
unlink("$dir/$ff");
}
echo '<li>' . $ff;
if (is_dir($dir . '/' . $ff)) {
listFolderFiles($dir . '/' . $ff);
}
echo '</li>';
}
}
echo '</ol>';
}
$arr = array(
"folder1",
"folder2"
);
for ($x = 0; $x < count($arr); $x++) {
$mm = $arr[$x];
listFolderFiles($mm);
}
//end
?>
For me, the solution with readdir was best and worked like a charm. With glob, the function was failing with some scenarios.
// Remove a directory recursively
function removeDirectory($dirPath) {
if (! is_dir($dirPath)) {
return false;
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
if ($handle = opendir($dirPath)) {
while (false !== ($sub = readdir($handle))) {
if ($sub != "." && $sub != ".." && $sub != "Thumb.db") {
$file = $dirPath . $sub;
if (is_dir($file)) {
removeDirectory($file);
} else {
unlink($file);
}
}
}
closedir($handle);
}
rmdir($dirPath);
}
public static function recursiveDelete($dir)
{
foreach (new \DirectoryIterator($dir) as $fileInfo) {
if (!$fileInfo->isDot()) {
if ($fileInfo->isDir()) {
recursiveDelete($fileInfo->getPathname());
} else {
unlink($fileInfo->getPathname());
}
}
}
rmdir($dir);
}
I've built a really simple package called "Pusheh". Using it, you can clear a directory or remove a directory completely (Github link). It's available on Packagist, also.
For instance, if you want to clear Temp directory, you can do:
Pusheh::clearDir("Temp");
// Or you can remove the directory completely
Pusheh::removeDirRecursively("Temp");
If you're interested, see the wiki.
I updated the answer of #Stichoza to remove files through subfolders.
function glob_recursive($pattern, $flags = 0) {
$fileList = glob($pattern, $flags);
foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
$subPattern = $dir.'/'.basename($pattern);
$subFileList = glob_recursive($subPattern, $flags);
$fileList = array_merge($fileList, $subFileList);
}
return $fileList;
}
function glob_recursive_unlink($pattern, $flags = 0) {
array_map('unlink', glob_recursive($pattern, $flags));
}
This is a simple way and good solution. try this code.
array_map('unlink', array_filter((array) array_merge(glob("folder_name/*"))));