Set img src without knowing extension - php

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.

Related

What is the best way to get the parameters in PHP?

I will completely clarify my question, sorry to everybody.
I have code writed in files from a website that now is not working, the html code is on pages with php extension, in a folder of a Virtual Host in my PC using Wampserever. C:\wamp\1VH\PRU1, when the site was online there was a folder where was a file called image.php. This file was called from other pages inside the site like this: (a little code of a file, C:\wamp\1VH\PRU1\example.php)
"<div><img src="https://www.example.com/img/image.php?f=images&folder=foods&type=salads&desc=green&dim=50&id=23" alt="green salad 23"></div>"
And the result was that the images was showed correctly.
Now, like i have this proyect in local, and i HAVE NOT the code of that image.php file i must to write it myself, this way the images will be showed the same way that when the site was online.
When the site was online and i open a image returned by that image.php file the URL was, following the example, https://example.com/images/foods/salads/green_50/23.png.
Now how the site is only local and i have not that image.php file writed because i'm bot sure how to write it, the images obviously are not showed.
In C:\wamp\1VH\PRU1\example.php the code of files was changed deleting "https://www.example.com/img/image.php?" for a local path "img/image.php?".
And in the same folder there is anothers: "img" folder (here must be allocated the image.php file), and "images" folder, inside it /foods/salads/green_50/23.png, 24.png.25.png..............
So i have exactly the same folder architecture that the online site and i changed the code that i could only, for example replacing with Jquery "https://www.example.com/img/image.php?" for "img/image.php?" but wich i can not do is replace all the code after the image.php file to obtain a image file.
So i think that the easiest way to can obtain the images normally is creating that IMAGE.PHP file that i have not here in my virtual host.
I'd like to know how to obtain the parameters and return the correct URL in the image,php file.
The image of the DIV EXAMPLE must be C:/wamp/1VH/PRU1/images/foods/salads/green_50/23.png
I have in my PC the correct folders and the images, i only need to write the image.php file.
Note that there are "&" and i must to unite the values of "desc=green&dim=50&" being the result: green_50 (a folder in my PC).
TVM.
You probably want something like this.
image.php
$id = intval($_GET['id']);
echo '<div><img src="images/foods/salads/green_50/'.$id.'.png" alt="green salad '.$id.'"></div>';
Then you would call this page
www.example.com/image.php?id=23
So you can see here in the url we have id=23 in the query part of the url. And we access this in PHP using $_GET['id']. Pretty simple. In this case it equals 23 if it was id=52 it would be that number instead.
Now the intval part is very important for security reasons you should never put user input directly into file paths. I won't get into the details of Directory Transversal attacks. But if you just allow anything in there that's what you would be vulnerable to. It's often overlooked, so you wouldn't be the first.
https://en.wikipedia.org/wiki/Directory_traversal_attack
Now granted the Server should have user permissions setup properly, but I say why gamble when we can be safe with 1 line of code.
This should get you started. For the rest of them I would setup a white list like this:
For
folder=foods
You would make an array with the permissible values,
$allowedFolders = [
'food',
'clothes'
'kids'
];
etc...
Then you would check it like this
///set a default
$folder = '';
if(!empty($_GET['folder'])){
if(in_array($_GET['folder'], $allowedFolders)){
$folder = $_GET['folder'].'/';
}else{
throw new Exception('Invalid value for "folder"');
}
}
etc...
Then at the end you would stitch all the "cleaned" values together. As I said before a lot of people simply neglect this and just put the stuff right in the path. But, it's not the right way to do it.
Anyway hope that helps.
You essentially just need to parse the $_GET parameters, then do a few checks that the file is found, a real image and then just serve the file by setting the appropriate content type header and then outputting the files contents.
This should do the trick:
<?php
// define expected GET parameters
$params = ['f', 'folder', 'type', 'desc', 'dim', 'id'];
// loop over parameters in order to build path: /imagenes/foods/salads/green_50/23.png
$path = null;
foreach ($params as $key => $param) {
if (isset($_GET[$param])) {
$path .= ($param == 'dim' ? '_' : '/').basename($_GET[$param]);
unset($params[$key]);
}
}
$path .= '.png';
// check all params were passed
if (!empty($params)) {
die('Invalid request');
}
// check file exists
if (!file_exists($path)) {
die('File does not exist');
}
// check file is image
if (!getimagesize($path)) {
die('Invalid image');
}
// all good serve file
header("Content-Type: image/png");
header('Content-Length: '.filesize($path));
readfile($path);
https://3v4l.org/tTALQ
use $_GET[];
<?php
$yourParam = $_GET['param_name'];
?>
I can obtain the values of parameters in the image.php file tis way:
<?php
$f = $_GET['f'];
$folder = $_GET['folder'];
$type = $_GET['type'];
$desc = $_GET['desc'];
$dim = $_GET['dim'];
$id = $_GET['id'];
?>
But what must i do for the image:
C:/wamp/1VH/PRU1/images/foods/salads/green_50/23.png
can be showed correctly in the DIV with IMG SRC atribute?

Is it safe to display a image using $_GET for path?

Is it safe to display a image using $_GET for path?
For example using this format: image.php?path=/images/example.jpg
Yes you can, just make sure you use isset so that it doesn't throw undefined index if someone fiddles with your URL, also you need to check whether the path is valid else show some other image, like image not found by writing text in alt attribute
if(isset($_GET['index'])) {
echo '';
}
Points to be looked for:-
Anybody can tinker URL
You'll have to sanitize the value
Often path's will be changed so be sure you use alt text if image is not found
If you don't sanitize, will lead to easy intrusion for hackers
Inshort I suggest you NOT TO DO SO
Its perfectly safe if you check the path exists after using basename($_GET['path']) on the file name, also define your path to the images folder.
Then check that it is an image with getimagesize($path). If any fail, change the filename to a not found image or such.
<?php
$path_to_images = '/images/';
$not_found_img = './path/to/not_found_image.jpg';
// check path is set and not empty
if(empty($_GET['path'])){
$path = $not_found_img;
}else{
$path = $path_to_images.basename($_GET['path']);
// check that image exists
if(!file_exists($path)){
$path = $not_found_img;
}else{
//Check if image
if($img_size = getimagesize($path)) {
//alls good $path validated
}else{
$path = $not_found_img;
}
}
}
// do somthing with your $path
?>
Completely yes. There are no problems, hackers can't give there bad code, what can hack your page or work with your database. But take care on some other elements.

PHP include image file with changing filename

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

image displaying issue

I have an image url but there is not image or the image name has been renamed, so i am not able to view the image in this case i want to show a default custom image. any idea on how to do it
thanks in advance
If it's the same site, you can use any of PHP filesystem functions to see if an image file still on it's place. is_readable() is my favorite one for that purpose.
Sure, not URL but a filesystem path should be used.
If it's just a hotlinks to other sites - forget it. You can't check it for reasonable price.
if the image is one your server ie. if you know the path to the image file, you can use the php function file_exists
if (file_exists($imageFilePath)){
$url = $imageUrl;
} else {
$url = $customImageUrl;
}
if the file is located on your server
<?php
$filename = '/path/to/file.jpg';
if (!file_exists($filename)) {
$filename = '/path/to/default.jpg'
}
?>
otherwise you can try using GetImageSize
if(#GetImageSize($remoteImageURL)){
//image exists!
}

How can I improve this PHP code?

I have the php code below which help me get a photo's thumbnail image path in a script
It will take a supplied value like this from a mysql DB '2/34/12/thepicture.jpg'
It will then turn it into this '2/34/12/thepicture_thumb1.jpg'
I am sure there is a better performance way of doing this and I am open to any help please
Also on a page with 50 user's this would run 50 times to get 50 different photos
// the photo has it is pulled from the DB, it has the folders and filename as 1
$photo_url = '2/34/12/thepicture_thumb1.jpg';
//build the full photo filepath
$file = $site_path. 'images/userphoto/' . $photo_url;
// make sure file name is not empty and the file exist
if ($photo_url != '' && file_exists($file)) {
//get file info
$fil_ext1 = pathinfo($file);
$fil_ext = $fil_ext1['extension'];
$fil_explode = '.' . $fil_ext;
$arr = explode($fil_explode, $photo_url);
// add "_thumb" or else "_thumb1" inbetween
// the file name and the file extension 2/45/12/photo.jpg becomes 2/45/12/photo_thumb1.jpg
$pic1 = $arr[0] . "_thumb" . $fil_explode;
//make sure the thumbnail image exist
if (file_exists("images/userphoto/" . $pic1)) {
//retunr the thumbnail image url
$img_name = $pic1;
}
}
1 thing I am curious about is how it uses pathinfo() to get the files extension, since the extension will always be 3 digits, would other methods of getting this value better performance?
Is there a performance problem with this code, or are you just optimizing prematurely? Unless the performance is bad enough to be a usability issue and the profiler tells you that this code is to blame, there are much more pressing issues with this code.
To answer the question: "How can I improve this PHP code?" Add whitespace.
Performance-wise, if you're calling built-in PHP functions the performance is excellent because you're running compiled code behind the scenes.
Of course, calling all these functions when you don't need to isn't a good idea. In your case, the pathinfo function returns the various paths you need. You call the explode function on the original name when you can build the file name like this (note, the 'filename' is only available since PHP 5.2):
$fInfo = pathinfo($file);
$thumb_name = $fInfo['dirname'] . '/' . $fInfo['filename'] . '_thumb' . $fInfo['extension'];
If you don't have PHP 5.2, then the simplest way is to ignore that function and use strrpos and substr:
// gets the position of the last dot
$lastDot = strrpos($file, '.');
// first bit gets everything before the dot,
// second gets everything from the dot onwards
$thumbName = substr($file, 0, $lastDot) . '_thumb1' . substr($file, $lastDot);
The best optimization for this code is to increase it's readability:
// make sure file name is not empty and the file exist
if ( $photo_url != '' && file_exists($file) ) {
// Get information about the file path
$path_info = pathinfo($file);
// determine the thumbnail name
// add "_thumb" or else "_thumb1" inbetween
// the file name and the file extension 2/45/12/photo.jpg
// becomes 2/45/12/photo_thumb.jpg
$pic1 = "{$path_info['dirname']}/{$path_info['basename']}_thumb.{$fil_ext}";
// if this calculated thumbnail file exists, use it in place of
// the image name
if ( file_exists( "images/userphoto/" . $pic1 ) ) {
$img_name = $pic1;
}
}
I have broken up the components of the function using line breaks, and used the information returned from pathinfo() to simplify the process of determining the thumbnail name.
Updated to incorporate feedback from #DisgruntledGoat
Why are you even concerned about the performance of this function? Assuming you call it only once (say, when the "main" filename is generated) and store the result, its runtime should be essentially zero compared to DB and filesystem access. If you're calling it on every access to re-compute the thumbnail path, well, that's wasteful but it's still not going to be significantly impacting your runtime.
Now, if you want it to look nicer and be more maintainable, that's a worthwhile goal.
The easiest way to fix this is to thumbnail all user profile pics before hand and keep it around so you don't keep resizing.
$img_name = preg_replace('/^(.*)(\..*?)$/', '\1_thumb\2', $file);
Edit: bbcode disappeared with \.

Categories