I have a virtual random image using .htaccess file:
# .htaccess
<Files random.jpg>
RewriteEngine On
RewriteRule ^(.+)$ /random-image.php [QSA,L]
</Files>
and the following PHP:
<?php
// random-image.php
$images=glob("images/*.jpg");
$image=imagecreatefromjpeg($images[array_rand($images)]);
header('Content-Type: image/jpeg');
imagejpeg($image);
?>
and in HTML:
<img src="random.jpg">
This works well enough, but the browser has an annoying habit of caching the images, so I always get the same image rather than a new one.
I know that I can use JavaScript to append a random query string to the end of the src attribute, but that’s not always going to be an option.
Is there a way I can add additional headers, either in the PHP file or the .htaccess file to tell the browser not to cache the image and to always load from the server?
just put this inside tag in your .htaccess file
Header set Cache-Control "max-age=0"
Related
I am creating a hotel management project using procedural PHP. I am storing the name of the image in database and uploading the image to another server using ftp(This is located in htdocs/remote-media-storage/media/ folder). But when I try to add the image name with its domain prefix to src it doesn't work. However when I inspect source the source url is right and when I open it in the browser it still works. How do i fix this.
This is how I am adding to src
This is the view in browser
The page source when inspected shows the correct url
And the image also shows up in browser when i open the same url
This is the directory where the image is stored
<img src="<?php echo "http://domainaltered.infinityfreeapp.com/remote-image-storage/media/".$row["room_image"]; ?>" alt="<?= $row["room_image"]; ?>" />
What am I doing wrong?
What happens if you format your echo statement like the solutions offered here: How to echo <img src with PHP variables as values of the src attribute? Do you still get a broken image url?
Since you're using short tags in the alt, you could try this:
<img src="<?='http://thedomain.com/remote-image-storage/media/'.$row["room_image"];?>" />
I found out that this is an issue of CORB. My request is being blocked. I tried to add these overrides to .htaccess file.
# Always set these headers.
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "Content-Type"
Header set Access-Control-Allow-Methods "GET"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
# Added a rewrite to respond with a 200 SUCCESS on every OPTIONS request.
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
But I am facing the same issue.
I have a link in my localhost, which points to a jpg image. I want to keep using that same link, but I want to eventually replace the image with a word file. Or a pdf file. Or a gif file. Or any other extension that isn't a jpg image.
(Trust me, it makes sense in context, but the context is not important to the question, so I'll leave it out.)
How can I create a link to those files without having the file extension at the end? I could create a php page and have the image (or another file type) embedded there, but one requirement that I have is that the url needs to be the same as the image url. So specifically for jpg, png and gif files only (don't worry about other file types), I want to be able to right click it when I view it with my browser, go to "Copy image address" and get the same exact link as in the address bar of my browser, as if I'm viewing a regular image.
Is something like that possible?
To reiterate:
- I need to generate a link that can be any file type
- If the link points to a file that is an image (jpg, png, gif), the link you get from "Copy image address" should be the same as the link you're using to view it in your browser
Example:
This is the image I have saved on my PC:
C:\xampp\htdocs\my_projects\my_image.jpg
I can view it directly in my browser using this link:
localhost/my_projects/my_image.jpg
What I really want, however, is something like this:
localhost/my_projects/my_image
So I could replace the original jpg file with a png file for example:
C:\xampp\htdocs\my_projects\my_image.png
And, after editing whatever file is responsible in generating "localhost/my_projects/my_image" to point to the png image instead of the jpg image, I can still use the same link as before and get the png image this time:
localhost/my_projects/my_image
What is important to me is the following:
Hopefully this will make my question more clear.
If you know the directory or location of the file.
You can fetch file name with it's extension. you don't need to give file name in front-end.
$directory = 'folder';
if($handle = opendir($directory.'/')){
echo 'looking inside \''.$directory.'\':<br>';
while($file = readdir($handle)){
if($file!='.'&&$file!='..'){
echo ''.$file.'<br>';
}
}
}
either list them or download them.
You need to Rewrite Rules.
Create a .htaccess file in your directory.
Then add this code inside your .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.png-f
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ $1\.png
RewriteCond %{REQUEST_FILENAME}.jpg-f
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ $1\.jpg
RewriteCond %{REQUEST_FILENAME}.gif-f
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ $1\.gif
I hope this helps.
I've noticed in Facebook's source code, that images are links to a PHP file, safe_image.php (or rsrc.php; it changes every now and then), with the name of the selected file appended to the end, such as:
https://external-lax3-2.xx.fbcdn.net/safe_image.php?imagename1234
Or sometimes they're the usual JPEG files with a random token appended to the end:
https://scontent-lax3-2.xx.fbcdn.net/v/t1.0-9/17353408_410522555967800_2778489440067836960_n.jpg?oh=3e00f84c6767364c9304b34f8751114d&oe=5954DA1E
What, I'm wondering is how they get a custom image viewer on their website. Usually, it's just a white background, with the selected image in the top left corner. However, they have it set in the middle with a grey-ish background.
Not only that, the linked image is direct back to the viewed PHP file; how is this possible, and how do they do it?
Cheers.
EDIT: I've also noticed if you change the img src to an invalid link, it will print an error to the page:
The image " Insert image link here " cannot be displayed because it contains errors.
Jpeg files, to no ones surprise, do not take in arguments. However, PHP does. So, what is most likely Facebook did is use a rewrite rule to 'map' their .jpg?= URL to a PHP file, which can process the arguments. That PHP file then fetches the image data from a MYSQL (like) table. If you're wondering, yes you can have the .jpg file extension display in the URL, load data from PHP, and have the image display properly in browser.
This can be achieved via PHP and .htaccess.
Firstly, let's setup our .htaccess inside whatever folder we want to have our /img.jpg?= inside of:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^img.jpg(.*)$ imageBackground.php$1 [NC]
Yay, now we are mapping our img.jpg?image=bill to imageBackground.php?image=bill.
And then we are going to write our imageBackground.php. I wrote a very simple one, but basically all your doing is setting up headers (for which image format you're using) as well as display the image data. Obviously in practical application this would be more complicated, like maybe you're dynamically grabbing image data from a database (like Facebook).
<?php
if ($_GET['image'] == "bill") {
header("Content-type: image/pjpeg");
echo file_get_contents("bill.jpg");
}
?>
I'm trying to dynamically rename a jpeg image file as it's displayed to the user.
I have a file image_generate.php with the following code:
$file = $_GET['file'];
$imagepath = "path/to/image.jpg";
$image = imagecreatefromjpeg($imagepath);
header('Content-Type: image/jpeg');
$filename = "[site.com]_some_image_name_here";
header('Content-Disposition: attachment; filename="' . $filename . '.jpg"');
imagejpeg($image, NULL, 100);
imagedestroy($image); // Free up memory
And it's called by an html image tag like so:
<img src="image_generate.php?file=imagenamehere" />
So far, the output has the following results:
When I right-click on the image, and click "View Image," a download dialogue pops up and asks if I'd like to save the file "[site.com]_some_image_name_here.jpg" (I want this to happen)
If I right-click on the image, and click "Save Image As," or "Save Image," the filename that's to be saved shows up as the original filename (whatever the variable $file was able to fetch).
How can I fix the second part? I'd like to modify the filename of the image even when the user clicks "Save Image As" or "Save Image."
I DID try to change the code to this:
...
$rename = $filename . ".jpg";
imagejpeg($image, $rename, 100);
imagedestroy($image); // Free up memory
But the image fails to show up on the page with the html tag (shows up as a broken image).
I'm not very familiar with html headers and Content-Dispositions. I'm guessing there's an error in there somewhere..?
Any ideas?
Thank you for reading!
Edit: .htaccess below
<IfModule mod_rewrite.c>
RewriteEngine On
# Sends image download request to image_generate.php for parsing
RewriteRule ^path/from/img/tag/downloads/(.*).jpg$ path/to/image_generate.php?file=$1 [NC,L]
RewriteRule ^path/to/image_generate.php$ /home/path/to/image_generate.php [NC,L]
</IfModule>
Different browsers will have different behaviors.
For example, Internet Explorer doesn't try to fetch any header information before displaying the save file dialog when doing a Right Click > Save Image As (It automatically assumes you want to save the result of the request, regardless of what the result is). Neither does Firefox. Therefore, for IE & Firefox, it will be impossible to specify the filename by specifying it in the headers.
A more elegant and UA-compatible way of doing this would be by using Apache's mod_rewrite to do URL rewriting. URL rewriting allows you to reroute a request made to a URL towards another.
To set this up, you need to create a .htaccess file in the directory where image_generate.php is located containing the following:
RewriteEngine On
RewriteRule ^generated/([a-z0-9-]+)\.jpg$ generated_image.php?file=$1 [L]
Then, simply modify your HTML to point to your rewritten URL.
<img src="generated/imagenamehere.jpg" />
This also have the advantage of making your image generation completely seamless to the user (URL wise, it looks simply like a static image).
More information about mod_rewrite can be found here:
mod_rewrite - Apache HTTP Server
mod_rewrite Cheat Sheet (V2) - Added Bytes by Dave Child
i made an image resizer in php. When an image is resized, it caches a new jpg file with the new dimensions. Next time you call the exact img.php?file=hello.jpg&size=400 it checks if the new jpg has already been created.
If it has NOT been created yet, it creates the file and then prints the output (cool).
If it ALREADY exists, no new file needs to be generated and instead, it just calls the already cached file.
My question is regarding the second scenario. Which of these is faster?
redirecting: header('Location: cache/hello_400.jpg');die();
grabbing data and printing the cached file: $data = file_get_contents('cache/hello_400.jpg'); header('Content-type: '.$mime);
header('Content-Length: '.strlen($data));
echo $data;
Any other ways to improve this?
If someone wants the generated code, check this out:
http://egobits.com/misc/img.phps
Thanks to all for the help!
I would opt for never printing the data to the browser. Both scenarios should throw a permanent redirect to the generated image. Except if the image doesn't exist yet, it is created before the Location header is sent.
Edit:
Just to be clear about what I mean by permanent redirect...
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://path/to/image');
Maybe you could do the following:
Set some directory for these images.
Link to images in this directory (<a href="/img/resizable/hello_400.jpg>).
Set your webserver to redirect to your php script if the image doesn't exist yet. If you are on Apache, a simple .htaccess will do. In PHP, you have $_SERVER["REQUEST_URI"] from which you can tell which image you should resize.
Your script saves and echoes the image (but is called only for the first time).
This way, your get some benefits:
The image is cached (in a proxy or a browser) as any other static file.
PHP doesn't have to be called for every request just to redirect or output statical data.
You leave the implementation of If-modified-since and other cache-related headers to the webserver.
And the links look nicer :-)
Example .htaccess in your /img/resizable folder:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /img.php [L]
Any other ways to improve this?
Yes.
There is a way to send nothing but just an HTTP header: a conditional get.
You can take a look at the similar script, http://shiftingpixel.com/2008/03/03/smart-image-resizer/, for the implementation
As a third (more powerful) option: cache the image in a binary field in a database, and query the database for it.
Implement all three solutions and benchmark them.
I'm going to guess that the first option (redirect) will be the slowest in the real world, because it requires just as much effort as the second option (file_get_contents), but involves a second request and more overhead.
If possible in your case, you can also implement a function to directly set the url of the cached image in your html like:
<img src="<?php getImageUrl('hello.jpg', 400); ?>" />
getImageUrl() will return the url of the cached image if it exists else it will return the url to dynamically generate the resized image.