Delete specific filenames in an array using PHP - php

I have a list of PDFs and I would like to delete them. Can someone please explain to a beginner how this is done? At this point, I can do this in Excel a number of different ways but how can I simply do this in PHP?

Most simple solution:
<?php
$dir = '/files_directory/';
$files_to_delete = array('file1.pdf', 'file3.pdf', 'file4.pdf');
foreach($files_to_delete as $file)
{
$file_path = $dir . $file;
if(is_file($file_path))
{
unlink($file_path);
}
}

Use PHP to search for the folder, do a loop through the files there and add some conditional statements to the loop. If they are true or false, act on those results.
As you have not typed any code for us, I am not going to type any code back to you.

The most simple way I could think of doing it:
array_map('unlink', $array_with_files_to_delete);
$array_with_files_to_keep = array_diff($list_with_pdfs, $array_with_files_to_delete);

Related

Remove files which have not filename duplicates

For each document (.pdf, .txt, .docx ecc) I have also a corresponding json file with the same filename.
Example:
file1.json,
file1.pdf,
file2.json,
file2.txt,
filex.json,
filex.pdf,
But I got also some json files which are not accompanied with the corresponding document.
I want to delete all json files which have no corresponding document. Im really stucked because I cant find a proper solution to my problem.
I know how to scandir() get the filename, extensions from pathinfo() ecc. but the issue is that for each json file I find in directory I have to perform another foreach on that directory excluding all json files and see If the same filename exists or not so than I can decide to delete it. (This is how I think to solve it).
The problem here is with performance since there are millions of files and for each json I have to run a foreach on millions of files.
Can anyone guide me to a better solution?
Thank you!
Edit: Since no one will help without first posting a piece of code (and this approach in stackoverflow is definitively wrong) here is how I'm trying.:
<?php
$dir = "2000/";
$files = scandir($dir);
foreach ($files as $file) {
$fullName = pathinfo($file);
if ($fullName['extension'] === 'json') {
if (!in_array($fullName['filename'].'.pdf', $files)){
unlink($dir.$file);
}
}
}
Now as you can see I can only search only for one type of document (.pdf in this case). I want to search for every extension excluding .json and also I don't want that for each json file to run a foreach/in_array() but achieving all this in just one foreach.
Maybe you should consider it in another way? I mean, iterate through all files, and try to find corresponding files to json, if not found remove it.
It would look like follows:
$dir = "2000/";
foreach (glob($dir . "*.json") as $file) {
$file = new \SplFileInfo($dir . $file);
if (count(glob($dir . $file->getBasename('.' . $file->getExtension()) . ".*")) === 1) {
unlink($dir . $file->getFilename());
}
}
Manual
PHP: SplFileInfo
PHP: glob

Rename all files in directory using PHP and creation date

i have a problem/challenge on my Synology NAS. I have a IPcam connected which takes pictures with file names like:
00A8F700CB18()_1_20140107000224_3674.jpg
Now i would like to rename all those files to something like:
Tue 07-01-2014_11-17-26.jpg (containing date & time)
And here's the kicker: I've seen (PHP) scripts using "jhead" or "stat -c", unfortunately those are not an option on the Synology!
I cooked something up which works when i use a single file, now i would like to run this script on all the files in a directory!
Please help, i'm not an experienced PHP programmer and i take much joy in the explanation lines in the scrips, gives me and anybody who is whatching this post a learning curve ;)
The script u could use on a single file is something like this:
<?php
$stat = stat('/volume1/Ipcam/_Test/00A8F700CB18()_1_20140107000223_3673.jpg');
$motdate = ($stat['ctime']);
$newname = (gmdate("D d-m-Y_H-i-s", $motdate));
rename("/volume1/Ipcam/_Test/00A8F700CB18()_1_20140107000223_3673.jpg" . "/volume1/Ipcam/_Test/" . $newname . ".jpg");
?>
any help would be appreciated!
Read into scandir or readdir php functions.
They read a bunch of files in a specified directory and returns an array of file names.
You can then loop through these files and apply the above code to each file.
The examples on php.net are pretty easy to use and modify :)
You can use this modification of your code
<?php
$dir = '/volume1/Ipcam/_Test/';
$files = scandir($dir);
foreach($files as $file) {
$stat = stat($file);
$motdate = ($stat['ctime']);
$newname = (gmdate("D d-m-Y_H-i-s", $motdate));
rename($file, $dir . $newname . ".jpg");
}
?>

unlink files with a case-insensitive (glob-like) pattern

I have two folders, in one i have the videos and in the second one the configuration files for each video(3 files per video). Now if i want to delete a video i have to delete files by hand.
I found this :
<?php
$filename = 'name.of.the.video.xml';
$term = str_replace(".xml","", $filename);
$dirPath = ("D:/test/");
foreach (glob($dirPath.$term.".*") as $removeFile)
{
unlink ($removeFile);
}
?>
A echo will return:
D:/test/name.of.the.video.jpg
D:/test/name.of.the.video.srt
D:/test/name.of.the.video.xml
Is ok and it help me a lot, but i have a problem here.
Not all files are the same ex:
Name.of.The.video.jpg
Name.Of.The.Video.xml
If i echo the folder looking for that string and is not identic with the $filename will return empty.
So, my question is, how can i make that search Case insensitive?
Thank you.
You are making use of the glob function which is case sensitive. You are using the wrong function therefore to get the list of files.
You should therefore first normalize the filenames in the directory so they all share the same case (e.g. all lowercase). Or you need to use another method to get the directory listing case-insensitive. I suggest the first, however if that is not an option, why don't you glob for all files first and then filter the list of files using preg_grep which allows to specify patterns that are case-insensitive?
Which leads me to the point that it's more practicable to use DirectoryIterator with a RegexIterator:
$filename = 'name.of.the.video.xml';
$term = basename($filename, ".xml");
$files = new DirectoryIterator($dirPath);
$filesFiltered = new RegexIterator($files, sprintf('(^%s\\..*$)i', preg_quote($term)));
foreach($filesFiltered as $file)
{
printf("delete: %s\n", $file);
unlink($file->getPathname());
}
A good example of the flexibility of the Iterators code are your changed requirements: Do that for two directories at once. You just create two DirectoryIterators and append the one to the other with an AppendIterator. Job done. The rest of the code stays the same:
...
$files = new AppendIterator();
$files->append(new DirectoryIterator($dirPath1));
$files->append(new DirectoryIterator($dirPath2));
...
Voilá. Sounds good? glob is okay for some quick jobs that need just it. For everything else with directory operations start to consider the SPL. It has much more power.
Is strcasecmp() a valid function for this? Its a case insensitive str comparison function?
Surely if you know the file name and you can echo it out, you can pass this to unlink()?

All available images under a domain

I'd like to make a gallery of all images i have under my domain (my internet root folder). All these images are in different folders. What's the best way to 'browse' through all the folders and return the images?
Use Google Image Search with site: www.mydomainwithimages.com as the search term and this will show you all your indexed images. This should be everything in your domain as long as your robots.txt file doesn't exclude the Google crawler.
Take a look at opendir you would want to write a function that gets called in a recursive loop, the function could loop through the files in the specific directory, check the file extension and return the files as an array which you would merge with a global array.
Depends on hosting system, you could use command line with exec or passthru
find /path/to/website/root/ -type f -name '*.jpg'
If you can't do such a thing, as fire said, opendir is the way to go.
I would give PHP's DirectoryIterator a spin.
This is untested pseudo-code, but it should work a little bit like this:
function scanDirectoryForImages($dirPath)
{
$images = array();
$dirIter = new DirectoryIterator($dirPath);
foreach($dirIter as $fileInfo)
{
if($fileInfo->isDot())
continue;
// If it's a directory, scan it recursively
elseif($fileInfo->isDir())
{
$images = array_merge(
$images, scanDirectoryForImages($fileInfo->getPath())
);
}
elseif($fileInfo->isFile())
{
/* This works only for JPEGs, oviously, but feel free to add other
extensions */
if(strpos($fileInfo->getFilename(), '.jpg') !== FALSE)
{
$images[] = $fileInfo->getPathname();
}
}
}
return $images;
}
Please don't sue me if this doesn't work, it's really kinda from the top of my hat, but using such a function would be the most elegant way to solve your problem, imho.
// edit: Yeah, that's basically the same as fire pointed out.

Searching for specific file extensions in a folder/directory (PHP)

I'm trying to design a program in PHP that would allow me to find files with specific file extensions (example .jpg, .shp etc) in a known directory which consists of multiple folders.
Sample code, documentation or information about what methods I will be required to use will be much appreciated.
glob is pretty easy:
<?php
foreach (glob("*.txt") as $filename) {
echo "$filename size " . filesize($filename) . "\n";
}
?>
There are a few suggestions for recursive descent at the readdir page.
Take a look at PHP's SPL DirectoryIterator.
I believe PHP's glob() function is exactly what you are looking for:
http://php.net/manual/en/function.glob.php
Use readdir to get a list of files, and fnmatch to work out if it matches your required filename pattern. Do all this inside a function, and call your function when you find directories. Ask another question if you get stuck implementing this (or comment if you really have no idea where to start).
glob will get you all the files in a given directory, but not the sub directories. If you need that too, you will need to: 10. get recursive, 20. goto 10.
Here's the pseudo pseudocode:
function getFiles($pattern, $dir) {
$files = glob($dir . $pattern);
$folders = glob($dir, GLOB_ONLYDIR);
foreach ($folders as $folder) {
$files = $files + getFiles($folder);
}
return $files;
}
The above will obviously need to be tweaked to get it working, but hopefully you get the idea (remember not to follow directory links to ".." or "." or you'll be in infinite loop town).

Categories