How to get only images using scandir in PHP? - php

Is there any way to get only images with extensions jpeg, png, gif etc while using
$dir = '/tmp';
$files1 = scandir($dir);

You can use glob
$images = glob('/tmp/*.{jpeg,gif,png}', GLOB_BRACE);
If you need this to be case-insensitive, you could use a DirectoryIterator in combination with a RegexIterator or pass the result of scandir to array_map and use a callback that filters any unwanted extensions. Whether you use strpos, fnmatch or pathinfo to get the extension is up to you.

The actual question was using scandir and the answers end up in glob. There is a huge difference in both where blob considerably heavy. The same filtering can be done with scandir using the following code:
$images = preg_grep('~\.(jpeg|jpg|png)$~', scandir($dir_f));
I hope this would help somebody.

Here is a simple way to get only images. Works with PHP >= 5.2 version. The collection of extensions are in lowercase, so making the file extension in loop to lowercase make it case insensitive.
// image extensions
$extensions = array('jpg', 'jpeg', 'png', 'gif', 'bmp');
// init result
$result = array();
// directory to scan
$directory = new DirectoryIterator('/dir/to/scan/');
// iterate
foreach ($directory as $fileinfo) {
// must be a file
if ($fileinfo->isFile()) {
// file extension
$extension = strtolower(pathinfo($fileinfo->getFilename(), PATHINFO_EXTENSION));
// check if extension match
if (in_array($extension, $extensions)) {
// add to result
$result[] = $fileinfo->getFilename();
}
}
}
// print result
print_r($result);
I hope this is useful if you want case insensitive and image only extensions.

I would loop through the files and look at their extensions:
$dir = '/tmp';
$dh = opendir($dir);
while (false !== ($fileName = readdir($dh))) {
$ext = substr($fileName, strrpos($fileName, '.') + 1);
if(in_array($ext, array("jpg","jpeg","png","gif")))
$files1[] = $fileName;
}
closedir($dh);

You can search the resulting array afterward and discard files not matching your criteria.
scandir does not have the functionality you seek.

If you would like to scan a directory and return filenames only you can use this:
$fileNames = array_map(
function($filePath) {
return basename($filePath);
},
glob('./includes/*.{php}', GLOB_BRACE)
);
scandir() will return . and .. as well as the files, so the above code is cleaner if you just need filenames or you would like to do other things with the actual filepaths

I wrote code reusing and putting together parts of the solutions above, in order to make it easier to understand and use:
<?php
//put the absolute or relative path to your target directory
$images = scandir("./images");
$output = array();
$filer = '/(.jpg|.png|.jpeg|.gif|.bmp))/';
foreach($images as $image){
if(preg_match($filter, strtolower($image))){
$output[] = $image;
}
}
var_dump($output);

Related

PHP: search recursively for specific file extensions, exclude certain directories

Clueless PHP coder here. I have a photo library structured as follows:
DIR
thumbnails
file1.jpeg
file1.NEF
file2.JPG
SUBDIR
thumbnails
file3.jpeg
file3.ARW
file4.NEF
I'd like my PHP script to find all *.jpeg files in all directories, except thumbnails.
Thanks to my amazing copy-pasting skills, I came up with this:
function rsearch($dir, $pattern_array) {
$return = array();
$iti = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
foreach(new RecursiveIteratorIterator($iti) as $file){
if (in_array(strtolower(array_pop(explode('.', $file))), $pattern_array)){
$return[] = $file;
}
}
return $return;
}
$files = rsearch("photos", array('jpeg', 'JPEG'));
It works, but it also returns result from all thumbnails subdirectories. And I can't for the live of me figure out how to exclude them. I'd be grateful for any suggestions.
Thank you in advance!
You just have to verify the $iti to check if its a file or a directory, if its a directory make sure its not one called thumbnails. Also cleaned up your file extension verification method.
function rsearch($dir, $pattern_array) {
$return = array();
$iti = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
foreach(new RecursiveIteratorIterator($iti) as $file => $details){
if(!is_file($iti->getBasename()) && ($iti->getBasename() != "thumbnails")) {
$file_ext = pathinfo($file, PATHINFO_EXTENSION);
if (in_array(strtolower($file_ext), $pattern_array)){
$return[] = $file;
}
}
}
return $return;
}
$files = rsearch("photos", array('jpg', 'jpeg'));
print_r($files);

How to get a file extension from path with any extension? Solved

Solved! "../pictures/uploads/profile" I changed to "./pictures/uploads/profile". My mistake, sorry! And I used answer from #Kunal Raut
I want to get extension of file in PHP from path. I have this code:
$fileName = "../pictures/uploads/profile".$id.".*";
$ext = pathinfo($fileName, PATHINFO_EXTENSION);
$sourceImg = "../pictures/uploads/profile".$id.".".$ext."?".mt_rand();
I have folder with pictures. They can be in png or jpg or jpeg. And php file is in another folder. So how do that?
$fileName = "../pictures/uploads/profile".$id.".*"; // <---- this is not a file,put a file name
$ext = pathinfo($fileName, PATHINFO_EXTENSION);
Try this:
$files = scandir("../pictures/uploads/");
foreach ($files as $fileName) {
$ext = pathinfo($fileName, PATHINFO_EXTENSION);
}
Just use the DirectoryIterator class.
foreach (new DirectoryIterator('../pictures/uploads') as $fileInfo) {
if ($fileInfo->isDot()) continue;
if (stripos($fileInfo->getFilename(), 'profile' . $id) !== false) {
var_dump($fileInfo->getExtension());
}
}
The DirectoryIterator class is available since PHP 5.3.6.
A more detailed example could be a DirectoryIterator instance used by a FilterIterator instance to just output the desired files. Th given example requires a minimum of PHP 7.4. If you 're using a PHP version smaller than 7.4 remove the type hints for the class properties.
class MyFileFilter extends FilterIterator
{
protected string $filename;
public function __construct(Iterator $iterator, $filename)
{
$this->filename = $filename;
parent::__construct($iterator);
}
public function accept(): bool
{
$info = $this->getInnerIterator();
return stripos($info->getFilename(), $this->filename) !== false;
}
}
The FilterIterator class is available since PHP 5.1. The above shown extension takes an Iterator and searches for a given filename and returns the SplFileInfo object, if the filename matches.
How to use it:
$directory = new DirectoryIterator('../pictures/uploads');
$filename = 'picture' . $id;
$filter = new MyFileFilter($directory, $filename);
foreach ($filter as $file) {
var_dump($file->getExtension());
}
The foreach loop is basically the filter, that only returns files, that match the given filename. Every returned file is a SplFileInfo instance. With this you can use the SplFileInfo::getExtension() method to get the file extension.
Last but not least comes the GlobIterator class which is available since PHP 5.3. It 's the easiest way to iteratate over a given path with placeholders.
$filesystem = new GlobIterator('../pictures/uploads/profile' . $id . '.*');
foreach ($filesystem as $file) {
var_dump($file->getExtension());
}
You can get all the extensions in the directory by using the function scandir() as
$fileName = scandir("../pictures/uploads/");
$ext = "";
foreach($fileName as $files) {
if($files !== '.' && $files !== '..') {
$ext = pathinfo($files, PATHINFO_EXTENSION);
}
}
echo $ext .'<br>';
Usually scandir() returns the first two values in the array as . and .. and by if condition mentioned in the answer you can delete these unwanted values and get the answer in the pure form.
Note : scandir() returns the values in the form of array.
i got it working see below

Get Image File Extension with PHP

The file name is known but the file extension is unknown. The images in thier folders do have an extension but in the database their names do not.
Example:
$ImagePath = "../images/2015/03/06/"; (Folders are based on date)
$ImageName = "lake-sunset_3";
Does not work - $Ext is empty:
$Ext = (new SplFileInfo($ImagePath))->getExtension();
echo $Ext;
Does not work either - $Ext is empty:
$Ext = (new SplFileInfo($ImagePath.$ImageName))->getExtension();
echo $Ext;
Does not work either - $Ext is still empty:
$Ext = (new SplFileInfo($ImagePath,$ImageName))->getExtension();
echo $Ext;
$Ext should produce ".jpg" or ".jpeg" or ".png" etc.
So my question is simple: What am I doing wrong?
Now, this is a bit of an ugly solution but it should work. Make sure that all your files have unique names else you'll have several of the same file, which could lead to your program obtaining the wrong one.
<?php
$dir = scandir($imagePath);
$length = strlen($ImageName);
$true_filename = '';
foreach ($dir as $k => $filename) {
$path = pathinfo($filename);
if ($ImageName === $path['filename']) {
break;
}
}
$Ext = $path['extension'];
?>
Maybe this might help you (another brute and ugly solution)-
$dir = '/path/to/your/dir';
$found = array();
$filename = 'your_desired_file';
$files = scandir($dir);
if( !empty( $files ) ){
foreach( $files as $file ){
if( $file == '.' || $file == '..' || $file == '' ){
continue;
}
$info = pathinfo( $file );
if( $info['filename'] == $filename ){
$found = $info;
break;
}
}
}
// if file name is matched, $found variable will contain the path, basename, filename and the extension of the file you are looking for
EDIT
If you just want the uri of your image then you need to take care of 2 things. First directory path and directory uri are not the same thing. If you need to work with file then you must use directory path. And to serve static files such as images then you must use directory uri. That means if you need to check files exists or what then you must use /absolute/path/to/your/image and in case of image [site_uri]/path/to/your/image/filename. See the differences? The $found variable form the example above is an array-
$found = array(
'dirname' => 'path/to/your/file',
'basename' => 'yourfilename.extension',
'filename' => 'yourfilename',
'extension' => 'fileextension'
);
// to retrieve the uri from the path.. if you use a CMS then you don't need to worry about that, just get the uri of that directory.
function path2url( $file, $Protocol='http://' ) {
return $Protocol.$_SERVER['HTTP_HOST'].str_replace($_SERVER['DOCUMENT_ROOT'], '', $file);
}
$image_url = path2url( $found['dirname'] . $found['basename'] ); // you should get the correct image url at this moment.
You are calling a file named lake-sunset_3. It has no extension.
SplFileInfo::getExtension() is not designed to do what you are requesting it to do.
From the php site:
Returns a string containing the file extension, or an empty string if the file has no extension.
http://php.net/manual/en/splfileinfo.getextension.php
Instead you can do something like this:
$path = $_FILES['image']['name'];
$ext = pathinfo($path, PATHINFO_EXTENSION);
getExtension() only returns the extension from the given path, which in your case of course doesn't have one.
In general, this is not possible. What if there is a file lake-sunset_3.jpg and a file lake-sunset_3.png?
The only thing you can do is scan the directory and look for a file with that name but any extension.
You're trying to call an incomplete path. You could try Digit's hack of looking through the directory for for a file that matches the name, or you could try looking for the file by adding the extensions to it, ie:
$basePath = $ImagePath . $ImageName;
if(file_exists($basePath . '.jpg'))
$Ext = '.jpg';
else if(file_exists($basePath . '.gif'))
$Ext = '.gif';
else if(file_exists($basePath . 'png'))
$Ext = '.png';
else
$Ext = false;
Ugly hacks aside, the question begging to be asked is why are you storing them without the extensions? It would be easier to strip off the extension if you need to than it is try and find the file without the extension

Get filenames of images in a directory

What should be done to get titles (eg abc.jpg) of images from a folder/directory using PHP and storing them in an array.
For example:
a[0] = 'ac.jpg'
a[1] = 'zxy.gif'
etc.
I will be using the array in a slide show.
It's certainly possible. Have a look at the documentation for opendir and push every file to a result array. If you're using PHP5, have a look at DirectoryIterator. It is a much smoother and cleaner way to traverse the contents of a directory!
EDIT: Building on opendir:
$dir = "/etc/php5/";
// Open a known directory, and proceed to read its contents
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
$images = array();
while (($file = readdir($dh)) !== false) {
if (!is_dir($dir.$file)) {
$images[] = $file;
}
}
closedir($dh);
print_r($images);
}
}
'scandir' does this:
$images = scandir($dir);
One liner :-
$arr = glob("*.{jpg,gif,png,bmp}", GLOB_BRACE)
glob in php - Find pathnames matching a pattern
<?php
//path to directory to scan
$directory = "../images/team/harry/";
//get all image files with a .jpg extension. This way you can add extension parser
$images = glob($directory . "{*.jpg,*.gif}", GLOB_BRACE);
$listImages=array();
foreach($images as $image){
$listImages=$image;
}
?>

Why is this Recursive Iterator for file sizes in php not correct?

I'm am trying to get file names, sizes and permissions in php using RecursiveIteratorIterator and RecursiveDirectoryIterator .
The code below works for outputting all files and directory names and sizes correctly, but the permissions are wrong ( using get $file->getPerms).
In this case all permissions being output are the same, 0666 which I suspect is the first file only.
Also note that if I do not use foreach(new RecursiveIteratorIterator($it) as $file) and instead just use foreach($it as $file) it works correctly, but it is not recursive ( aka it shows no sub-directories/files).
//remove some file types I don't want showing
$filetypes = array("jpg", "png", "css", "gif");
$it = new RecursiveDirectoryIterator("/root-directory");
foreach(new RecursiveIteratorIterator($it) as $file) {
//foreach($it as $file) {
// ^^This works but it's not recursive ?!
//remove files in $filetypes array
$filetype = pathinfo($file, PATHINFO_EXTENSION);
if (!in_array(strtolower($filetype), $filetypes)) {
//outputs file name correct
echo $file ;
//outputs wrong permissions
echo substr(sprintf('%o', $file->getPerms()), -4);
//outputs file size correct
echo number_format($file->getSize()/1024, 2) . " KB";
}
}
Simply put this does not seem to return accurate results on a Wamp stack, possibly a bug.

Categories