PHP include image file with changing filename - php

I am completely new to PHP so forgive me if this question seems very rudimentry. And thank you in advance.
I need to include a jpg that is generated from a webcam on another page. However I need to include only the latest jpg file. Unfortunately the webcam creates a unique filename for each jpg. How can I use include or another function to only include the latest image file?
(Typically the filename is something like this 2011011011231101.jpg where it stands for year_month_date_timestamp).

Easy way is to get the latest image with the help of the below code
$path = "/path/to/my/dir";
$latest_ctime = 0;
$latest_filename = '';
$d = dir($path);
while (false !== ($entry = $d->read())) {
$filepath = "{$path}/{$entry}";
// could do also other checks than just checking whether the entry is a file
if (is_file($filepath) && filectime($filepath) > $latest_ctime) {
$latest_ctime = filectime($filepath);
$latest_filename = $entry;
}
}
}
// now $latest_filename contains the filename of the newest file
give the source of latest image to <img> tag

Since the images are named via pattern which relates to the date, you should be able to just use:
$imgs = glob('C:\images\*.jpg');
rsort($imgs);
$newestImage = $imgs[0];

This is fairly straightforward, since your file names are in order.
The first thing you need is a list of files in the directory. The readdir (doc) function is what you are looking for. Example script that uses it: http://www.liamdelahunty.com/tips/php_list_a_directory.php
Once you have that, use substr() (doc) to chop off the file name extensions.
You're left with an array of numbers, essentially. From here, do a sort (doc) and specify the SORT_NUMERIC flag. Grab the number on the end, stick a .jpg back on it, and you have the last file.
Alternate Solution: Read the timestamps of files to get the last one. This would generally be a better answer, but perhaps not in your situation if you plan to edit any of the files.

I guess you will have to know a way to determine what the latest image file is called. Maybe you can make a textfile or something where every time a new image is created the webcam writes the latest filename in the text file (so the only text in the text file is the file name of the latest image file if it makes any sense). Of course you will have to have access to the script that generates the php file.

addition to #ken 's post, it's probably sorting alphabetically instead of numerically. perhaps you could try:
$imgs = glob('C:\images\*.jpg');
rsort($imgs, SORT_NUMERIC);
$newestImage = $imgs[0];

Related

Set img src without knowing extension

So I have a few images in the server (public_html/img/profile_pictures/).
This is how I currently set the image:
echo "<img src='img/profile_pictures/main_photo.png'/>";
The main_photo can change each day, but if it changes to main_photo.jpg insted, it wont show (because the extension is hardcoded on that line(.png)). Is it possible to display the photo without knowing the extension for the image file?
If you want a PHP code, then try this. This code will look for main_photo.* inside your folder and automatically set the extension upon finding one.
Remember to set the path properly
<?php
$yourPhotoPath = "img/profile_pictures/";
foreach (glob($yourPhotoPath.'main_photo.*') as $filename) {
$pathInfo = pathinfo($filename);
$extension = $pathInfo['extension'];
$fileName = chop($pathInfo['basename'], $extension);
echo "<img src='".$yourPhotoPath.$fileName.$extension."'/>";
}
?>
if a Photo isn't loaded, it's width and size is null.
Although I would advise you to write a class that checks and loads images, I get a feeling you want a simple solution. so, given by the premise that the photo is either
<img src='img/profile_pictures/main_photo.png'/>
or
<img src='img/profile_pictures/main_photo.jpg'/>
and that neither this path nor this filename ever changes and in the folder is only one picture,
you could simply echo both.
The img of the one that is empty will not be shown.
A better way was to write a class that loads your photo and checks if the photo is really there, like
$path = 'img/profile_pictures/main_photo.png';
if(!file_exists('img/profile_pictures/main_photo.png'))
{
//use the jpg path
$path = 'img/profile_pictures/main_photo.jpg';
}
You can ofc just inline this if case, but it's bad practise to intermix buisinesslogic and format logic, so I advice you to write a class for it.

How to find file without specific file extension in laravel storage?

How to find file by name without specific extension in laravel Storage?
like this "filename.*"
Storage::get("filename.*")
I tried this but seems not to work. It searches for specific file with specific extension.
Storage::get() takes a file path as a parameter and returns the content of a single file identified by this path or throws FileNotFoundException if file can't be found.
Wildcards are not supported in the path - one reason for that could be that there might be multiple files that match the path with wildcards which would break the rule that content of a single file is returned from Storage::get(). Scanning the whole folder would also be much slower, especially with remote storages.
However, you could get what you want using other functionality that Storage facade offers. First, list the content of your storage - that will give you the list of all available files. Then filter the list yourself to get the list of matching files.
// list all filenames in given path
$allFiles = Storage::files('');
// filter the ones that match the filename.*
$matchingFiles = preg_grep('/^filename\./', $allFiles);
// iterate through files and echo their content
foreach ($matchingFiles as $path) {
echo Storage::get($path);
}
Accepted solution works. However I've found this other and I like it more:
$matchingFiles = \Illuminate\Support\Facades\File::glob("{$path}/*.log");
See reference here:
http://laravel-recipes.com/recipes/143/finding-files-matching-a-pattern
Minor change to jedrzej.kurylo's answer and combining wogsland's answer using laravel 8:
'/^filename\./' or '/filename\./' pattern does not work in my case.
// From:
$matchingFiles = preg_grep('/^filename./', $allFiles);
// To:
$allFiles = Storage::disk('yourStorageDisk')->files('folder/path');
$allowedMimeTypes = ['image/jpeg', 'image/png', 'image/webp'];
$matchingFiles = preg_grep('{'.$image.'}', $allFiles);
foreach ($matchingFiles as $path) {
// get real mime type
$contentType = image_type_to_mime_type(exif_imagetype(asset($path)));
// compare it with our allowed mime types
if (in_array($contentType, $allowedMimeTypes)) {
// do something here...
}
}
This way we can fetch files or images safely.
Dont trust what you see. Get inside and get the ext for your file
$pic = 'url/your.file';
$ext = image_type_to_mime_type(exif_imagetype($pic));
$ext = explode('/',$ext);
echo $ext[1];

PHP copy a file to multiple child folders with random names

I have an HTML form and one of the inputs creates a folder. The folder name is chosen by the website visitor. Every visitor creates his own folder on my website so they are randomly generated. They are created using PHP Code.
Now I would like to write a PHP code to copy a file to all of the child directories regardless the quantity of directories being generated.
I do not wish to stay writing a PHP line for every directory that is created - i.e. inserting the filename name manually (e.g. folder01, xyzfolder, folderabc, etc...) but rather automatically.
I Googled but I was unsuccessful. Is this possible? If yes, how can I go about it?
Kindly ignore security, etc... I am testing it internally prior to rolling out on a larger scale.
Thank you
It is sad I cannot comment so go on...
//get the new folder name
$newfolder = $_POST['newfoldername'];
//create it if not exist
if(!is_dir("./$newfolder")) {
mkdir("./$newfolder", 0777, true);
}
//list all folder
$dirname = './';
$dir = opendir($dirname);
while($file = readdir($dir)) {
if(($file != '.' OR $file != '..') AND is_dir($dirname.$file))
{
//generate a randomname
$str = 'yourmotherisveryniceABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$randomname = str_shuffle($str);
$actualdir = $dirname.$file;
//copy of the file
copy($uploadedfile['tmp_name'], $actualdir.$randomname);
}
}
closedir($dir);
I just want to say, you seem to be lazy by looking for what you want to do. because when I read "I would like to write a PHP code to copy" the answer is in your sentence: copy PHP and list of folders regarless how many? Then just simply list it !
Maybe you need to learn how to use google... If you search "I would like to write a PHP code to copy a file to all of the child directories regardless the quantity of directories being generated" Sure you will never find.

Auto Numbering File on Upload

I have edited the title, so I hope this one will be helpful...
Case:
I have many images and have uploaded it to a server. I was manually change their names with numbers. Of course I remember the last number of the file but could anyone help me with upload script that enable me to check the last number existed on the server folder and rename the file I'm gonna upload so that the name of the file is last_number_exist_on_server+1?
Ah, helping on generating the thumbnail to a specific folder and size will be appreciated also.
Last but not least, I am using PHP. No database... and the image file type is JPG.
Sorry, newbie's question.
Note: there is zero error checking here. Add some before you use in production! :)
<?php
// get the next number for our filename
// returns an array of files and directories in descending alpha-order
$files = scandir("./images", SCANDIR_SORT_DESCENDING);
$last_filename = array_shift($files);
$last_number = (int)substr($last_filename, 0, strrpos($last_filename, "."));
$next_number = $last_number++;
// now rename your file...
?>

I made an upload script in PHP. How do I avoid overwriting files?

I've made an image upload script using the move_uploaded_file function. This function seems to overwrite any preexisting file with the new one. So, I need to check if the target location already has a file. If it does then I need to append something to the filename(before the extension so that the file name is still valid) so the filename is unique. I'd like to have the change be minimal instead of something like appending the datetime, if possible.
How can I do this with PHP?
When uploading files I will nearly always rename them. Typically there will be some kind of database record for that file. I use the ID of that to guarantee uniqueness of the file. Sometimes I'll even store what the client's original filename was in the database too but I'll never keep it or the temporary name because there is no guarantee that information is good, that your OS will support it or that it's unique (which is your issue).
So just rename it to some scheme of your own devising. That's my advice.
If you don't have any database reference, then you could use file_exists() for this but there's no guarantee that between the time of checking if something exists and moving it that something else won't use that same filename that you'll then overwrite. This is a classic race condition.
http://us3.php.net/manual/en/function.file-exists.php
Don't use file_exists() for the reason that it returns true (on *nix systems at least, since directories are specialized files) if the value is a directory. Use is_file() instead.
For example, say something fails and you have a string like:
$path = "/path/to/file/" . $file; // Assuming $file is an empty value, if something failed for example
if ( true === file_exists($path) ) { echo "This returns true"; }
if ( true === is_file($path) ) { echo "You will not read this"; }
It's caused a few problems in the past for me, so I always use is_file() rather than file_exists().
I use date and time functions to generate a random file name based on the time of upload.
Let's assume you are submitting a file from a form where you have an input named incomingfile like this:
<input type="file" id="incomingfile" name="incomingfile" />
First of all I use to "depure" the filename and copy it from the default temporary directory to a temporary directory. This is necessary to deal with special characters. I had troubles when I didn't adopt this practice.
$new_depured_filename = strtolower(preg_replace('/[^a-zA-Z0-9_ -.]/s', '_', $_FILES["incomingfile"]["name"]));
copy($_FILES["incomingfile"]["tmp_name"], 'my_temp_directory/'.$new_depured_filename);
With the following piece of code I check if the file exists, if so, I find a new name and finally copy it. For example if I want to write a file called myimage.jpg and it already exists I rename the pending file to myimage__000.jpg. If this exists as well I rename the pending file to myimage__001.jpg and so on until I find a non-existing filename.
$i=0; // A counter for the tail to append to the filename
$new_filename = $new_depured_filename;
$new_filepath='myfiles/music/'.$new_filename;
while(file_exists($new_filepath)) {
$tail = str_pad((string) $i, 3, "0", STR_PAD_LEFT); // Converts the integer in $i to a string of 3 characters with left zero fill.
$fileinfos = pathinfo($new_filepath); // Gathers some infos about the file
if($i>0) { // If we aren't at the first while cycle (where you have the filename without any added strings) then delete the tail (like "__000") from the filename to add another one later (otherwise you'd have filenames like myfile__000__001__002__003.jpg)
$previous_tail = str_pad((string) $i-1, 3, "0", STR_PAD_LEFT);
$new_filename = str_replace('__'.$previous_tail,"",$new_filename);
}
$new_filename = str_replace('.'.$fileinfos['extension'],"",$new_filename); // Deletes the extension
$new_filename = $new_filename.'__'.$tail.'.'.$fileinfos['extension']; // Append our tail and the extension
$new_filepath = 'myfiles/music/'.$new_filename; // Crea il nuovo percorso
$i++;
}
copy('my_temp_directory/'.$new_depured_filename, $new_filepath); // Finally we copy the file to its destination directory
unlink('my_temp_directory/'.$new_depured_filename); // and delete the temporary one
Used functions:
strtolower
preg_replace
copy
file_exists
str_pad
pathinfo
str_replace
unlink
To check if a file exists, you can use the file_exists function.
To cut the filename, you can use the pathinfo function.
I use
$file_name = time() . "_" . $uploaded_file_name;

Categories