scandir to only show folders, not files - php

I have a bit of PHP used to pulled a list of files from my image directory - it's used in a form to select where an uploaded image will be saved. Below is the code:
$files = array_map("htmlspecialchars", scandir("../images"));
foreach ($files as $file) {
$filelist .= sprintf('<option value="%s">%s</option>' . PHP_EOL, $file, $file );
}
It works fine but shows all files and folders in 'images', does someone know a way to modify this code so that it only shows folder names found in the 'images' folder, not any other files.
Thanks

The easiest and quickest will be glob with GLOB_ONLYDIR flag:
foreach(glob('../images/*', GLOB_ONLYDIR) as $dir) {
$dirname = basename($dir);
}

Function is_dir() is the solution :
foreach ($files as $file) {
if(is_dir($file) and $file != "." && $file != "..") $filelist .= sprintf('<option value="%s">%s</option>' . PHP_EOL, $file, $file );
}

The is_dir() function requires an absolute path to the item that it is checking.
$base_dir = get_home_path() . '/downloads';
//get_home_path() is a wordpress function
$sub_dirs = array();
$dir_to_check = scandir($dir);
foreach ($dir_to_check as $item){
if ($item != '..' && $item != '.' && is_dir($base_dir . "/" . $item)){
array_push($sub_dirs, $item);
}
}

You could just use your array_map function combined with glob
$folders = array_map(function($dir) {
return basename($dir);
}, glob('../images/*', GLOB_ONLYDIR));
Yes, I copied a part of it of dev-null-dweller, but I find my solution a bit more re-useable.

I try this
<?php
$dir = "../";
$a = array_map("htmlspecialchars", scandir($dir));
$no = 0; foreach ($a as $file) {
if ( strpos($file, ".") == null && $file !== "." && $file !== ".." ) {
$filelist[$no] = $file; $no ++;
}
}
print_r($filelist);
?>

Related

how to count together the size of files when they are created in foreach loop

i am using a folder in which user can upload files. These files are outputted with the name and the size.
$dir = "users/$UserName";
$files = scandir($dir);
foreach ($files as $file) {
if ($file != '.' && $file != '..') {
echo sizeFormat(filesize($dir . '/' . $file));
}
So my output looks like this:
koala.jpg => 600kB
jellyfish.jpg => 600kB
tulips.jpg => 500kB
How can i count all the sizes together?
Something like: Toal size all files: 1700kB
Like this:
$dir = "users/$UserName";
$files = scandir($dir);
$total = 0;
foreach ($files as $file) {
if ($file != '.' && $file != '..') {
$total += filesize($dir . '/' . $file);
echo sizeFormat(filesize($dir . '/' . $file));
}
}
echo $total;
Uhm... just add the sizes together!?
Assuming your code works, here's a mockup how to do it:
$total = 0;
foreach ($files as $file) {
if ($file != '.' && $file != '..') {
$current = filesize($dir . '/' . $file);
$total += $current;
echo sizeFormat($current);
}
}
echo "total: ".sizeFormat($total);
Try this (assuming you have the sizeFormat function somewhere)
$dir = "users/$UserName";
$files = scandir($dir);
$size = 0;
foreach ($files as $file) {
if ($file != '.' && $file != '..') {
$size += filesize($dir . '/' . $file);
}
}
echo sizeFormat($size);

PHP: sort folder first and then files

$dir = '/master/files';
$files = scandir($dir);
foreach($files as $file){
if(($file != '.') && ($file != '..')){
if(is_dir($dir.'/'.$file)){
echo '<li class="folder">'.$file.'</li>';
}else{
echo '<li class="file">'.$file.'</li>';
}
}
}
From the script above, I get result:
images (folder)
index.html
javascript (folder)
style.css
How to sort the folder first and then files?
Try this :
$dir = '/master/files';
$directories = array();
$files_list = array();
$files = scandir($dir);
foreach($files as $file){
if(($file != '.') && ($file != '..')){
if(is_dir($dir.'/'.$file)){
$directories[] = $file;
}else{
$files_list[] = $file;
}
}
}
foreach($directories as $directory){
echo '<li class="folder">'.$directory.'</li>';
}
foreach($files_list as $file_list){
echo '<li class="file">'.$file_list.'</li>';
}
You don't need to make 2 loops, you can do the job with this piece of code:
<?php
function scandirSorted($path) {
$sortedData = array();
foreach(scandir($path) as $file) {
// Skip the . and .. folder
if($file == '.' || $file == '..')
continue;
if(is_file($path . $file)) {
// Add entry at the end of the array
array_push($sortedData, '<li class="folder">' . $file . '</li>');
} else {
// Add entry at the begin of the array
array_unshift($sortedData, '<li class="file">' . $file . '</li>');
}
}
return $sortedData;
}
?>
This function will return the list of entries of your path, folders first, then files.
Modifying your code as little as possible:
$folder_list = "";
$file_list = "";
$dir = '/master/files';
$files = scandir($dir);
foreach($files as $file){
if(($file != '.') && ($file != '..')){
if(is_dir($dir.'/'.$file)){
$folder_list .= '<li class="folder">'.$file.'</li>';
}else{
$file_list .= '<li class="file">'.$file.'</li>';
}
}
}
print $folder_list;
print $file_list;
This only loops through everything once, rather than requiring multiple passes.
I have a solution for N deep recursive directory scan:
function scanRecursively($dir = "/") {
$scan = array_diff(scandir($dir), array('.', '..'));
$tree = array();
$queue = array();
foreach ( $scan as $item )
if ( is_file($item) ) $queue[] = $item;
else $tree[] = scanRecursively($dir . '/' . $item);
return array_merge($tree, $queue);
}
Store the output in 2 arrays, then iterate through the arrays to output them in the right order.
$dir = '/master/files';
$contents = scandir($dir);
// create blank arrays to store folders and files
$folders = $files = array();
foreach ($contents as $file) {
if (($file != '.') && ($file != '..')) {
if (is_dir($dir.'/'.$file)) {
// add to folders array
$folders[] = $file;
} else {
// add to files array
$files[] = $file;
}
}
}
// output folders
foreach ($folders as $folder) {
echo '<li class="folder">' . $folder . '</li>';
}
// output files
foreach ($files as $file) {
echo '<li class="file">' . $file . '</li>';
}
Being a CodeIgniter lover, I have in fact modified the core directory_helper from that to include the ability to have certain files exempt from the scanning in addition to setting the depth and choosing if hidden files should be included.
All credit goes to the original authors of CI. I simply added to it
with the exempt array and building in the sorting.
It uses ksort to order the folders, as the folder name is set as the key and natsort to order the files inside each folder.
The only thing you may need to do is define what the DIRECTORY_SEPARATOR is for your environment but I don't think you will need to modify much else.
function directory_map($source_dir, $directory_depth = 0, $hidden = FALSE, $exempt = array())
{
if ($fp = #opendir($source_dir))
{
$folddata = array();
$filedata = array();
$new_depth = $directory_depth - 1;
$source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
while (FALSE !== ($file = readdir($fp)))
{
// Remove '.', '..', and hidden files [optional]
if ($file === '.' OR $file === '..' OR ($hidden === FALSE && $file[0] === '.'))
{
continue;
}
is_dir($source_dir.$file) && $file .= DIRECTORY_SEPARATOR;
if (($directory_depth < 1 OR $new_depth > 0) && is_dir($source_dir.$file))
{
$folddata[$file] = directory_map($source_dir.$file, $new_depth, $hidden, $exempt);
}
elseif(empty($exempt) || !empty($exempt) && !in_array($file, $exempt))
{
$filedata[] = $file;
}
}
!empty($folddata) ? ksort($folddata) : false;
!empty($filedata) ? natsort($filedata) : false;
closedir($fp);
return array_merge($folddata, $filedata);
}
return FALSE;
}
Usage example would be:
$filelist = directory_map('full_server_path');
As mentioned above, it will set the folder name as the key for the child array, so you can expect something along the lines of the following:
Array(
[documents/] => Array(
[0] => 'document_a.pdf',
[1] => 'document_b.pdf'
),
[images/] => Array(
[tn/] = Array(
[0] => 'picture_a.jpg',
[1] => 'picture_b.jpg'
),
[0] => 'picture_a.jpg',
[1] => 'picture_b.jpg'
),
[0] => 'file_a.jpg',
[1] => 'file_b.jpg'
);
Just keep in mind that the exempt will be applied to all folders. This is handy if you want to skip out a index.html file or other file that is used in the directories you don't want included.
Try
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
chdir ($path);
$dir = array_diff (scandir ('.'), array ('.', '..', '.DS_Store', 'Thumbs.db'));
usort ($dir, create_function ('$a,$b', '
return is_dir ($a)
? (is_dir ($b) ? strnatcasecmp ($a, $b) : -1)
: (is_dir ($b) ? 1 : (
strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION)) == 0
? strnatcasecmp ($a, $b)
: strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION))
))
;
'));
header ('content-type: text/plain');
print_r ($dir);
?>
public function sortedScanDir($dir) {
// scan the current folder
$content = scandir($dir);
// create arrays
$folders = [];
$files = [];
// loop through
foreach ($content as $file) {
$fileName = $dir . '/' . $file;
if (is_dir($fileName)) {
$folders[] = $file;
} else {
$files[] = $file;
}
}
// combine
return array_merge($folders, $files);
}

Pull all images from multiple directories and display them with PHP

I have a folder on my server called 'images', and within that folder I could have a single folder to as many as 10 folders that contain images.
Instead of writing a tag for each image
<img src="images/people/001.jpg">
<img src="images/landscape/001.jpg">
etc etc
Can I use PHP to get all the images in all the folders in the main directory 'images'?
I have VERY little experience with PHP, so this is something I am struggling with.
I need php to return an array of '<div class="box"><img src="images/FOLDER/IMAGENAME.jpg"></div>'
Maybe someone can help.
function ListFiles($dir) {
if($dh = opendir($dir)) {
$files = Array();
$inner_files = Array();
while($file = readdir($dh)) {
if($file != "." && $file != ".." && $file[0] != '.') {
if(is_dir($dir . "/" . $file)) {
$inner_files = ListFiles($dir . "/" . $file);
if(is_array($inner_files)) $files = array_merge($files, $inner_files);
} else {
array_push($files, $dir . "/" . $file);
}
}
}
closedir($dh);
return $files;
}
}
foreach (ListFiles('/path/to/images') as $key=>$file){
echo "<div class=\"box\"><img src=\"$file\"/></div>";
}
Something like this?
A simpler soluton. You can use built-in glob function. Assuming that all of your images are .jpg:
$result = array();
$dir = 'images/';
foreach(glob($dir.'*.jpg') as $filename) {
$result[] = "<div class=\"box\"><img src=\"$filename\"></div>";
}
Then you can echo each element of $result or whatever you want.

Listing all images in a directory using PHP [duplicate]

This question already has answers here:
Getting the names of all files in a directory with PHP
(15 answers)
Closed 6 months ago.
I have the code below that lists all the images in a folder, the problem is that it finds some files ( a . and a ..) that I am not sure what they are so I am not sure how to prevent them from showing up. I am on a windows XP machine, any help would be great, thanks.
Errors: Warning: rename(images/.,images/.) [function.rename]: No error
in C:\wamp\www\Testing\listPhotosA.php on line 14
Warning: rename(images/..,images/..) [function.rename]: No error in
C:\wamp\www\Testing\listPhotosA.php on line 14
Code:
<?php
define('IMAGEPATH', 'images/');
if (is_dir(IMAGEPATH)){
$handle = opendir(IMAGEPATH);
}
else{
echo 'No image directory';
}
$directoryfiles = array();
while (($file = readdir($handle)) !== false) {
$newfile = str_replace(' ', '_', $file);
rename(IMAGEPATH . $file, IMAGEPATH . $newfile);
$directoryfiles[] = $newfile;
}
foreach($directoryfiles as $directoryfile){
if(strlen($directoryfile) > 3){
echo '<img src="' . IMAGEPATH . $directoryfile . '" alt="' . $directoryfile . '" /> <br>';
}
}
closedir($handle); ?>
I like PHP's glob function.
foreach(glob(IMAGEPATH.'*') as $filename){
echo basename($filename) . "\n";
}
glob() is case sensitive and the wildcard * will return all files, so I specified the extension here so you don't have to do the filtering work
$d = 'path/to/images/';
foreach(glob($d.'*.{jpg,JPG,jpeg,JPEG,png,PNG}',GLOB_BRACE) as $file){
$imag[] = basename($file);
}
Use glob function.
<?php
define('IMAGEPATH', 'images/');
foreach(glob(IMAGEPATH.'*') as $filename){
$imag[] = basename($filename);
}
print_r($imag);
?>
You got all images in array format
To get all jpg images in all dirs and subdirs inside a folder:
function getAllDirs($directory, $directory_seperator) {
$dirs = array_map(function ($item) use ($directory_seperator) {
return $item . $directory_seperator;
}, array_filter(glob($directory . '*'), 'is_dir'));
foreach ($dirs AS $dir) {
$dirs = array_merge($dirs, getAllDirs($dir, $directory_seperator));
}
return $dirs;
}
function getAllImgs($directory) {
$resizedFilePath = array();
foreach ($directory AS $dir) {
foreach (glob($dir . '*.jpg') as $filename) {
array_push($resizedFilePath, $filename);
}
}
return $resizedFilePath;
}
$directory = "C:/xampp/htdocs/images/";
$directory_seperator = "/";
$allimages = getAllImgs(getAllDirs($directory, $directory_seperator));
Using balphp's scan_dir function:
https://github.com/balupton/balphp/blob/765ee3cfc4814ab05bf3b5512b62b8b984fe0369/lib/core/functions/_scan_dir.funcs.php
scan_dir($dirPath, array('pattern'=>'image'));
Will return an array of all files that are images in that path and all subdirectories, using a $path => $filename structure. To turn off scanning subdirectories, set the recurse option to false
Please use the following code to read images from the folder.
function readDataFromImageFolder() {
$imageFolderName = 14;
$base = dirname(__FILE__);
$dirname = $base.DS.'images'.DS.$imageFolderName.DS;
$files = array();
if (!file_exists($dirname)) {
echo "The directory $dirname not exists.".PHP_EOL;
exit;
} else {
echo "The directory $dirname exists.".PHP_EOL;
$dh = opendir( $dirname );
while (false !== ($filename = readdir($dh))) {
if ($filename === '.' || $filename === '..') continue;
$files[] = $dirname.$filename;
}
uploadImages( $files );
}
}
Please click here for detailed explanation.
http://www.pearlbells.co.uk/code-snippets/read-images-folder-php/
You can use OPP oriented DirectoryIterator class.
foreach (new DirectoryIterator(IMAGEPATH) as $fileInfo) {
// Removing dots
if($fileInfo->isDot()) {
continue;
}
// You have all necessary data in $fileInfo
echo $fileInfo->getFilename() . "<br>\n";
}
while (($file = readdir($handle)) !== false) {
if (
($file == '.')||
($file == '..')
) {
continue;
}
$newfile = str_replace(' ', '_', $file);
rename(IMAGEPATH . $file, IMAGEPATH . $newfile);
$directoryfiles[] = $newfile;
}

displaying files and DIRECTORIES via php?

i have a propably rather simple question:
I'm using the following script to read a folder?
$count = 0;
if ($handle = opendir(PATH)) {
$retval = array();
while (false !== ($file = readdir($handle))) {
$ext = pathinfo($file, PATHINFO_EXTENSION);
if ($file != '.' && $file != '..' && $file != '.DS_Store' && $file != 'Thumbs.db') {
$retval[$count] = $file;
$count = $count + 1;
} else {
//no proper file
}
}
closedir($handle);
}
if a file is an image I print it as an image: print "";
However i wonder how i can display FOLDERS? If i have a subfolder inside of the folder i'm currently running through? how can i print that one?
use glob instead of scandir
$dirs = glob(PATH."/*", GLOB_ONLYDIR);
$images = glob(PATH."/*.[jJ][pJ][gG]");
foreach ($dirs as $name) echo "<b>$name</b><br>\n";
foreach ($images as $name) echo $name."<br>\n";
Use scandir instead of readdir. http://us.php.net/manual/en/function.scandir.php

Categories