Image Caching - The Second
hello david - hello all,
i´m proud to be a pricetapestryer now and glad about my choice purchasing this great solution from one of the best coders.
i have a good feeling and i´m shure getting my script-wishes reality.
after installation i purchased a pricetapestrytemplates.com ajax-template.
the guy behind (dave) is a support-perfectionist like david.
my script works well but i need help changing some code for image caching.
<a href='<?php print $mainProduct["image_url"]; ?>' title='<?php print $mainProduct["name"]; ?>' rel='nofollow' id='gallery'><img class='productimg' src='<?php print ($mainProduct["image_url"]); ?>' alt='<?php print $mainProduct["name"]; ?>' title='<?php print $mainProduct["name"]; ?>' /></a></p>i downloaded imageCache.php
as disclaimed on
http://www.pricetapestry.com/node/279
and changed in my new html/product.php
src='<?php print ($mainProduct["image_url"]); ?>'to
src='/imageCache.php?src=<?php print urlencode($mainProduct["image_url"]); ?>'but i only get an empty entree and nothing is cached
cache folder rights are ok
what now?
warm regard
hade
hi david,
not wget is my problem. it´s the code.
by the way - i got it cached - but no images turn back
so let´s takea look onto my problem...
imageCache.php works...
cache folder too.. i got this file b2bdfea0265be9049fbe61557b177e7d.
correct...
my
product.php (ready and works)
{code saved}
my search
searchresults.php (ready and works)
{code saved}
the code avoids empty images as you can see
thank you for help dave...
warm regards
hade
Hello Hade,
It looks like your imageCache.php is working, like you say, but there are no modifications in your html/products.php or html/searchresults.php to use the imageCache.php URLs instead of the image_url field in the product record.
In your html/product.php, where you have this line at the top:
<?php $mainProduct = $product["products"][0]; ?>REPLACE that with:
<?php $mainProduct = $product["products"][0]; ?>
<?php if ($mainProduct["image_url"]) $mainProduct["image_url"] = $config_baseHREF."imageCache.php?src=".urlencode($mainProduct["image_url"]); ?>And in your search.php, you have this code at line 7:
<?php $rowcounter=1; foreach($searchresults["products"] as $product): ?>REPLACE that with:
<?php $rowcounter=1; foreach($searchresults["products"] as $product): ?>
<?php if ($product["image_url"]) $product["image_url"] = $config_baseHREF."imageCache.php?src=".urlencode($product["image_url"]); ?>Hope this helps!
Cheers,
David.
dave,
i don´t know if you can see "full" unmodified working script (without caching).
it seems, your form shows only 80% of it.
maybe i forgot to use code tags
i tried some modified combinations but without results...
{code saved}
Hello Hade,
Did you see my reply above (this post) - where I posted changes I think
you need to make to both your html/product.php and
html/searchresults.phpemail me your modified files I'll check them out for you...!
Cheers,
David.
hi david,
thanks for your reply to this - it's in your mailbox ;-)
thank you david,
you must not be sorry about anything... ;-)
seems it works!
but ! in the case of an error - f.ex. - product image url responses no image, ... only an ugly image link appears instead of the message (Image not available) i like to place instead
my thought was proofing imagelink via getimagesize:
if ($product["image_url"] && @getimagesize($product["image_url"])):
<?php else: ?>
<div class='noimage' >
<?php print translate("Image not available"); ?></div>
<?php endif; ?>thanks a lot and the good communication
hade
Hello Hade,
As getimagesize would invoke an additional request to imageCache.php, can I suggest a different approach, which would be to return a default "Image not available" image off your server in the case of an invalid image or no image URL present?
To do this, in your imageCache.php, look for the following section:
// as an error occured, delete the empty file so it is retried next time
unlink($filename);
// return false
return false;..and REPLACE with:
// as an error occured, delete the empty file so it is retried next time
unlink($filename);
$img = file_get_contents("images/noimage.gif");
header("Content-Type: image");
print $img;
exit();Additionally, the code to display images/noimage.gif would be required in html/searchresults.php and html/product.php - it's probably easiest if I modify the last versions I sent to you which I do now..
You would need to create your images/noimage.gif file before the above will work of course - and fingers crossed that should give neat results...
Cheers,
David.
Hi David,
I'm having some issues with this script - hopefully you'll be able to help!
My pricetapestry installation is in www.domainname.tld/mobile-phones
I uploaded imageCache.php to my mobile-phones/cache directory and set it to 777.
It seems to create the cached image on first load of the page, but when i click 'refresh' to see that page again, it's not showing an image, and when I view the image source, it appears to have the /mobile-phones/imageCache.php?src= value twice. It's almost as if the script is including the config_basehref value when building the image url.
Any ideas about a workaround for this?
Thanks!
Hi,
That sounds like the code to switch the image_url to the imageCache.php version has been included twice. Can you double check that the following line only exists once in each case:
html/product.php
<?php if ($mainProduct["image_url"]) $mainProduct["image_url"] = $config_baseHREF."imageCache.php?src=".urlencode($mainProduct["image_url"]); ?>html/searchresults.php
<?php if ($product["image_url"]) $product["image_url"] = $config_baseHREF."imageCache.php?src=".urlencode($product["image_url"]); ?>If you're not sure, if you could email me your modified html/ files, imageCache.php and if possible a link to your site I'll check it out for you...
Cheers,
David.
Hello Hade,
Thank you for your comments!
Working with other customers I have made some small changes to imageCache.php since the original post was published, which I have now updated. This involves making sure that the URL is correctly decoded, and that a Content-Type: image header is sent before the image data. In the first instance, please try this version:
imageCache.php
<?phpfunction cacheFetch($url,$age)
{
// directory in which to store cached files, must be writable by PHP
$cacheDir = "cache/";
// cache filename constructed from MD5 hash of URL
$filename = $cacheDir.md5($url);
// default to fetch the file
$fetch = true;
// but if the file exists, don't fetch if it is recent enough
if (file_exists($filename))
{
$fetch = (filemtime($filename) < (time()-$age));
}
// fetch the file if required
if ($fetch)
{
$maxRetry = 2;
do
{
// shell to wget to fetch the file, storing the exit code in $error
exec("wget -N -O ".$filename." \"".$url."\"",$output,$error);
// update timestamp to now
exec("touch ".$filename);
// keep trying if wget failed and not reached $maxRetry
} while( $error && $maxRetry--);
}
// return the filename only if wget did not fail
if (!$error)
{
return $filename;
}
else
{
// as an error occured, delete the empty file so it is retried next time
unlink($filename);
// return false
return false;
}
}
$src = $_GET["src"];
$src = str_replace(" ","%20",$src);
$src = cacheFetch($src,604800);
$img = file_get_contents($src);
header("Content-Type: image");
print $img;
?>
Now, if that doesn't work, the most likely problem is that PHP running on your hosting account is not configured to be allowed to run wget, which is used to fetch the image remotely. However, it is becoming more common now for CURL to be installed, which can be used instead. Here is an alternative version using CURL to fetch the image:
imageCache.php (using CURL)
<?phpfunction cacheFetch($url,$age)
{
// directory in which to store cached files, must be writable by PHP
$cacheDir = "cache/";
// cache filename constructed from MD5 hash of URL
$filename = $cacheDir.md5($url);
// default to fetch the file
$fetch = true;
// but if the file exists, don't fetch if it is recent enough
if (file_exists($filename))
{
$fetch = (filemtime($filename) < (time()-$age));
}
// fetch the file if required
if ($fetch)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
if (strlen($data))
{
$fp = fopen($filename,"w");
fwrite($fp,$data);
fclose($fp);
$error = false;
}
else
{
$error = true;
}
}
// return the filename only if wget did not fail
if (!$error)
{
return $filename;
}
else
{
// as an error occured, delete the empty file so it is retried next time
unlink($filename);
// return false
return false;
}
}
$src = $_GET["src"];
$src = str_replace(" ","%20",$src);
$src = cacheFetch($src,604800);
$img = file_get_contents($src);
header("Content-Type: image");
print $img;
?>
Hope this helps!
Cheers,
David.