Variable + Wildcard image removal - php

I want to create a piece of code that will remove images based on set parameters and a wildcard.
The number of images and naming will vary, though the first two parameters will remain as a constant.
// Example of images to be deleted / removed.
/images/1-50-variablename-A.jpg
/images/1-50-variablename-B.jpg
/images/1-50-variablename-C.jpg
/images/1-50-variablename-D.jpg
/images/1-50-variablename-E.jpg
Essentially I am after a loop to make this happen though I am not too sure on the best logic to make this happen.
$menuid = "1";
$imageid = "50"
$fileName = "images/".$menuid."-".$imageid."-*.jpg";
if (file_exists ($fileName)) {
unlink ($fileName);
}

You can use the php glob function (http://php.net/manual/fr/function.glob.php). Feed it with your pattern (it supports wildcards) and then iterate over the result and unlink each file.
Hope it helped

Solution presented itself in Glob form.
$menuid ="9999";
$imageid="5";
array_map('unlink', glob("../images/".$menuid."-".$imageid."-*.jpg"));

Related

stripos vs glob for unlinking

I want to delete the files which are not appearing in this array. I know the name of file partially but don't know the size parameter suffixed after file name like filename-50x75.jpg, filename-100x77.jpg , filename-500x377.jpg.
I want to delete above images from a directory and don't want to delete below images.
$list_of_allowed_images=array("filename-50x50.jpg","filename-50x70.jpg","filename-90x50.jpg","filename-100x100.jpg","filename-150x150.jpg","filename-250x200.jpg","filename-300x250.jpg","filename-360x270.jpg","filename-390x250.jpg","filename-500x345.jpg","filename-768x576.jpg","filename-820x400.jpg","filename-1024x768.jpg");
I have the following snippet:
foreach(glob($base_path_del.$only_obs_img."[0-9][0-9]*x*.{jpg,gif,png}", GLOB_BRACE) as $file_to_del_now)
{
if(!in_array($file_to_del_now,$list_of_allowed_images))
{
unlink($file_to_del_now);
}
}
but I think it can be more efficient. Is another more efficient way to do this?
Here's what I recommend:
(untested code)
chdir($base_path_del);
$files = glob($only_obs_img."[0-9][0-9]*x*.{jpg,gif,png}", GLOB_BRACE);
$whitelist_regex = "/-(?:50x[57]0|90x50|100x100|150x150|250x200|300x250|360x270|390x250|500x345|768x576|820x400|1024x768)\.jpg$/i";
$removables = preg_grep($whitelist_regex, $files, PREG_GREP_INVERT);
foreach ($removables as $filename) {
unlink($filename);
}
So...
Change the current working directory so that glob() doesn't include the paths in the collection of qualifying files.
Invert preg_grep() so that files that don't match the whitelist regex requirements are retained.
Then just loop the naughty list and delete the lot.
The regex pattern boils down your whitelist array logic. The check starts at the last - in the filename, checks the dimensions, checks .jpg case-insensitively, then ensures that the filename has ended.
p.s. or array_map() if you don't want to break the functional style.
array_map('unlink', $removables);

Filtering filenames in PHP

I'm trying to group a bunch of files together based on RecipeID and StepID. Instead of storing all of the filenames in a table I've decided to just use glob to get the images for the requested recipe. I feel like this will be more efficient and less data handling. Keeping in mind the directory will eventually contain many thousands of images. If I'm wrong about this then the below question is not necessary lol
So let's say I have RecipeID #5 (nachos, mmmm) and it has 3 preparation steps. The naming convention I've decided on would be as such:
5_1_getchips.jpg
5_2_laycheese.jpg
5_2_laytomatos.jpg
5_2_laysalsa.jpg
5_3_bake.jpg
5_finishednachos.jpg
5_morefinishedproduct.jpg
The files may be generated by a camera, so DSC###.jpg...or the person may have actually named each picture as I have above. Multiple images can exist per step. I'm not sure how I'll handle dupe filenames, but I feel that's out of scope.
I want to get all of the "5_" images...but filter them by all the ones that DON'T have any step # (grouped in one DIV), and then get all the ones that DO have a step (grouped in their respective DIVs).
I'm thinking of something like
foreach ( glob( $IMAGES_RECIPE . $RecipeID . "-*.*") as $image)
and then using a substr to filter out the step# but I'm concerned about getting the logic right because what if the original filename already has _#_ in it for some reason. Maybe I need to have a strict naming convention that always includes _0_ if it doesn't belong to a step.
Thoughts?
Globbing through 1000s of files will never being faster than having indexed those files in a database (of whatever type) and execute a database query for them. That's what databases are meant for.
I had a similar issue with 15,000 mp3 songs.
In the Win command line dir
dir *.mp3 /b /s > mp3.bat
Used a regex search and replace in NotePad++ that converted the the file names and prefixed and appended text creating a Rename statement and Ran the mp3.bat.
Something like this might work for you in PHP:
Use regex to extract the digits using preg_replace to
Create a logic table(s) to create the words for the new file names
create the new filename with rename()
Here is some simplified and UNTESTED Example code to show what I am suggesting.
Example Logic Table:
$translation[x][y][z] = "phrase";
$translation[x][y][z] = "phrase";
$translation[x][y][z] = "phrase";
$translation[x][y][z] = "phrase";
$folder = '/home/user/public_html/recipies/';
$dir=opendir($folder);
while (false !== ($found=readdir($dir))){
if pathinfo($file,PATHINFO_EXTENSION) == '.jpg')
{
$files[]= pathinfo($file,PATHINFO_FILENAME);
}
}
foreach($files as $key=> $filename){
$digit1 = 'DSC(\d)\d\d\.jpg/',"$1", $filename);
$digit2 = 'DSC\d(\d)\d\.jpg',"$1", $filename);
$digit3 = 'DSC\d\d(\d)\.jpg',"$1", $filename);
$newName = $translation[$digit1][$digit2][$digit3]
ren($filename,$newfilename);
}

How can I bulk rename files in a photo folder with sequential numbers

This was a poorly worded question
My main goal was to display many images or even a range from a set arbitrarily, renaming the files to sequential numbers seemed like it would make the displaying or iterating through the files easier if they just differed by 1 rather than random strings.
-- anyway I'm going to read... seems glob is according to php manual ... The glob() function searches for all the pathnames matching pattern according to the rules used by the libc glob() function
The files have random names but they are all .jpg's
As an example, "this name".jpg is replaced with "i+1".jpg
So that I can display the photos lazily using a for loop incrementing the numbers. The primary purpose is to display the photos regardless of their file names.
You can use php glob and rename functions:
$num = 1;
foreach (glob("/path/to/images/*.jpg") as $filename) {
$fileNoExtension = basename($filename, ".jpg");
rename ($filename, "$fileNoExtension{$num}.jpg");
$num++;
}
Basically,
$count = 1;
foreach (glob('*.jpg') as $filename) {
#rename($filename, $count.'.jpg');
$count++;
}
echo 'Done';
All image files must be in the current folder (along with the script).
You can add a path manually, if you wish:
glob('/path/to/*.jpg')
rename('path/..'.$file etc. )

shell_exec() statement to pdftotext entire directory?

I'm at a loss as to how I could build a loop to pdftotext and entire directory through a shell_exec() statement.
Something like :
$pdfs = glob("*.pdf");
foreach($pdfs as $pdfs) {
shell_exec('pdftotext '.$pdfs.' '.$pdfs'.txt');
}
But I'm unsure how I can drop the .pdf extension the 2nd time I call $pdfs in my shell_exec() statement and replace that with .txt
Not really sure this loop is correct either....
Try
foreach(glob("*.pdf") as $src) {
// Manually remove file extension because glob() may return a dir path component
$parts = explode('.', $src);
$parts[count($parts) - 1] = 'txt';
$dest = implode('.', $parts);
// Escape shell arguments, just in case
shell_exec('pdftotext '.escapeshellarg($src).' '.escapeshellarg($dest));
}
Basically, loop the PDF files in the directory and execute the command for each one, using just the name component of the file name (extracted with pathinfo())see edit for the output file (so test.pdf becomes test.txt).
Using the result of glob() directly in foreach easily avoids the variable naming collision you had in the code above.
EDIT
I have change the above code to manually remove the file extension when generating the output file name. This is because glob() may return a directory component of the path strings, as well as just a file name. Using pathinfo() or basename() will strip this off, and since we know that a . will be present in the file name (the rule passed to glob() dictates this) we can safely remove everything after the last one. I have also added escapeshellarg() for good measure - it is highly unlikely (if not impossible) that a file name that already exists would fall foul of this, but it is best to be safe.
$pdfs = glob("*.pdf");
$fmt='/path/to/pdftotext "%s" "%s.txt"';
foreach($pdfs as $thispdf) {
shell_exec(sprintf($fmt, $thispdf, basename($thispdf, ".pdf")));
}

PHP - Open or copy a file when knowing only part of its name?

I have a huge repository of files that are ordered by numbered folders. In each folder is a file which starts with a unique number then an unknown string of characters. Given the unique number how can i open or copy this file?
for example:
I have been given the number '7656875' and nothing more.
I need to interact with a file called '\server\7656800\7656875 foobar 2x4'.
how can i achieve this using PHP?
If you know the directory name, consider using glob()
$matches = glob('./server/dir/'.$num.'*');
Then if there is only one file that should start with the number, take the first (and only) match.
Like Yacoby suggested, glob should do the trick. You can have multiple placeholders in it as well, so if you know the depth, but not the correct naming, you can do:
$matchingFiles = glob('/server/*/7656875*');
which would match
"/server/12345/7656875 foo.txt"
"/server/56789/7656875 bar.jpg"
but not
"/server/12345/subdir/7656875 foo.txt"
If you do not know the depth glob() won't help, you can use a RecursiveDirectoryIterator passing in the top most folder path, e.g.
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('/server'));
foreach($iterator as $fileObject) {
// assuming the filename begins with the number
if(strpos($fileObject->getFilename(), '7656875') === 0) {
// do something with the $fileObject, e.g.
copy($fileObject->getPathname(), '/somewhere/else');
echo $fileObject->openFile()->fpassthru();
}
}
* Note: code is untested but should work
DirectoryIterator return SplFileInfo objects, so you can use them to directly access the files through a high-level API.
$result = system("ls \server\" . $specialNumber . '\');
$fh = fopen($result, 'r');
If it's hidden below in sub-sub-directories of variable length, use find
echo `find . -name "*$input*"`;
Explode and trim each result, then hope you found the correct one.

Categories