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

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);

Related

PHP find a specific file in directories listed

I am making an article system and I need to include all articles in directories listed in a directory. Example:
Find directories in directory "articles"
Find files called "article.php" in directories in the directory "articles"
include files called "article.php"
As I am new to PHP I don't know how to do this. All help appreciated!
Here's a solution for you:
$base_dir = './articles';
$filename = 'article.php';
// Listing all directories in $base_dir
$directories = scandir($base_dir);
// Looping over the directories
foreach($directories as $directory) {
if (! in_array($directory, array('.', '..'))) {
$filepath = $base_dir.'/'.$directory.'/'.$filename;
// if the file exists, we include it
if (is_file($filepath)) {
include_once($filepath);
}
}
}
Quick and dirty...
$data = '';
$dir = "path_to_your_articles";
$dirHandle = opendir($dir);
$lookForThis = 'article.php';
while ($file = readdir($dirHandle)) {
if(!is_dir($file)){
if($file == $lookForThis){
$data .= $file;
}
}
}
closedir($dirHandle);
echo $data;
Hope this is of some use...

PHP Remove all Files From a Directory - Exclude File Extension

I am trying for the life of me to find the best way to delete all files in a single directory excluding a single file extension, ie anything that is not .zip
The current method I have used so far which successfully deletes all files is:
$files = glob('./output/*');
foreach($files as $file)
{
if(is_file($file))
unlink($file); // delete file
}
I have tried modifying this like so:
$files = glob('./output/**.{!zip}', GLOB_BRACE);
foreach($files as $file)
{
if(is_file($file))
unlink($file); // delete file
}
However, I am not hitting the desired result. I have changed the line as follows which has deleted only the zip file itself (so I can do the opposite of desired).
$files = glob('./output/*.{zip}', GLOB_BRACE);
I understand that there are other methods to read directory contents and use strpos/preg_match etc to delete accordingly. I have also seen many other methods, but these seem to be quite long winded or intended for recursive directory loops.
I am certainly not married to glob(), I would simply like to know the simplest/most efficient way to delete all files in a single directory that are not a .zip file.
Any help/advice is appreciated.
$exclude = array("zip");
$files = glob("output/*");
foreach($files as $file) {
$extension = pathinfo($file, PATHINFO_EXTENSION);
if(!in_array($extension, $exclude)) unlink($file);
}
This code works by having an array of excluded extensions, it loads up all files in a directory then checks for the extension of each file. If the extension is in the exclusion list then it doesn't get deleted. Else, it does.
This should work for you:
(I just use array_diff() to get all files which are different to *.zip and then i go through these files and unlink them)
<?php
$files = array_diff(glob("*.*"), glob("*.zip"));
foreach($files as $file) {
if(is_file($file))
unlink($file); // delete file
}
?>
How about calling to the shell? So in Linux:
$path = '/path/to/dir/';
$shell_command = escapeshellcmd('find ' . $path .' ! -name "*.zip" -exec rm -r {}');
$output = shell_exec($shell_command);
I would simply like to know the simplest/most efficient way to delete all files in a single directory that are not a .zip file.
SPL Iterators are very effective and efficient.
This is what I would use:
$folder = __DIR__;
$it = new FilesystemIterator($folder, FilesystemIterator::SKIP_DOTS);
foreach ($it as $file) {
if ($file->getExtension() !== 'zip') {
unlink($file->getFilename());
}
}
Have you tried this:
$path = "dir/";
$dir = dir($path);
while ($file = $dir->read()) {
if ($file != "." && $file != ".." && substr($file, -4) !== '.zip') {
unlink($file);
}
}

Deleting ".part" files from folder with PHP

I'm using the following to delete all files from the specified directory.
$files = glob('path/to/temp/*');
foreach($files as $file){
if(is_file($file))
unlink($file);
}
It removes everything other than partially uploaded files eg : myfile.mp3.part
I've tried specifying .part in the file path just to see if I can force it that way :
$files = glob('path/to/temp/*.part');
But that doesn't work either.
Am I missing something here? Is there a different method for deleting non-active partial files?
$files = scandir('/path/to/temp');
foreach($files as $key => $file) {
if ( preg_match('/.*?\.part$/', $file) ) {
unlink($file);
}
}
I'm using something likes this to delete all files in a folder.
$dir = "/path/to/temp";
$files = scandir($dir);
foreach($files as $file){
$path = $dir."/".$file;
if(is_file($path)) unlink($path);
}

List with array only some formats files n folder and subdirectory php on Ubuntu Server

I need to list all files for example mp4 or avi in my folder /Files and relative subdirectories and after that insert into <a href={$filename}><\a> tag so I need a array i suppose.
I tried with find command but I receive a string and not a Array so I've to split the string and this isn't practical.
Any suggestion?
or use class RecursiveDirectoryIterator - For example :
$dir_iterator = new RecursiveDirectoryIterator(dirname(__FILE__));
$iterator = new RecursiveIteratorIterator($dir_iterator);
foreach ($iterator as $filename)
{
if (dirname($filename) != dirname(__FILE__))
{
if(is_file($filename)) {
$path_parts = pathinfo($filename);
if($path_parts['extension'] == 'mp4' )
{
print ''.basename($filename)."<br />";
}
}
}
}
<?php
$dir ="/Files";
$files = scandir($dir);
foreach($files as $file) {
$fullname = "/Files/" . $file;
echo '<a href='.$fullname.'>File</a>;
}
This should work for you.

How to get only images using scandir in 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);

Categories