Lets say I'm building a image gallery using PHP, where users would be able to upload their photos.
Every user would have 1 folder on server side with all their images there.
Now lets say I need to provide information in browser. Users would be able to browse images and should see lots of information about them, like image size, image dimensions, even EXIF information etc.
I could do this in 2 ways:
Save all information about image into database when uploading image.
Use PHP functions to browse through folder, and get information from every image.
I have something like file manager class, that can do all manipulations with files on server side, like deleteDir, deleteFile, countItems, getFileSize, getDirSize.
And it would be easy to only write one more class that would inspect images, and then I could just upload images, and get their information right from the folders without a need for relation database.
And now the question you all been waiting for is: ... :)
What would be faster, first or second solution? Lets say that site gets loads of traffic.
What solution would be better if I want it to be fast, and not to stress server to much?
actually, I got this situation like yours, this is my solution:
Save all information about image into database when uploading image.
Why?
I tested 2 ways:
Using php to get the image info for 1000 times.
Getting image info from database for 1000 times.
And the result is :
Getting image info from database is faster and faster.
Last but not least:
What would you do if you want to do a image info analystics?
If you save all info in database ,you can easily get them and analyse them ,but if you using php to get the info? it's hard to image.
So, just save all information about image into database when uploading image.
Good luck.
storing it in the database once
reading the data from the database and store it in cache,
redoing things always costs especially if it happens all the time
Depending on the size of these images, you probably want to show thumbnails instead of the original when people are browsing, which means you need to generate them. I would generate the thumbnail on upload and grab all the file info. Then save the file info in the database and put the original and thumbnail in the file system. If you get a lot of traffic, throw memcache on there too.
Storing data in separate places has a way of creating maintenance headache. I would just serialize the metadata for images in each folder and dump it to a file there. If you use gzip compression on the file, retrieval and storage should be very fast.
Related
Lets say I have a file called "getimage.php" to obtain an image all we need to do is getimage.php?imgid=1
My Server guy is warning me that pages with multiple images become very processor heavy. So would you suggest making a copies on the file server of theses image? and have a cron job delete files not being used after x amount of time?
or can I some how make 1 MYSQL query to obtain all the images? would this be less heavy then the getimage.php calling 1 SQL per image?
Any other suggestions?
I don't think you can get all the images in one shot from the database. In any case, is there any reason on why you're storing images in the database? This move has its benefits but, on the other hand, it has its drawbacks.
The only huge advantage I personally see from storing images in the database is when these images are subject to permissions (e.g. some users can see those images, some can't).
I am working on a PHP web application in which I have to introduce a cache layer over my database.
Specifically to store images in the cache layer taken from the db, the images are large in size: 4-8 MP. What would be the best way to do this? What data sources should I use?
Here's a suggestion for a scheme:
Create three folders - thumbnails, display images and original images. In these you'll store cached versions of thumbnails, resized versions for web display, and your original image.
When an image is uploaded assign it a unique name in your file system and store it there. Store the original name and the unique name in your database, along with any other pertinent information.
Assuming you have some sort of image browser to select from these images...
Retrieve image data from the database. Use that to locate thumbnails, display versions or originals.
When an image is browsed look for an existing thumbnail. If you have one, send it. If you don't, create one, store it in your thumbnails folder, and send it.
When an image is enlarged for display in the browser, check for a display version, etc. as for thumbnails. Use a resized version for display since 4-8Mp is a lot of data to send just for a web browser.
When an image is selected for download, send the original.
You need to be careful with cache-control in all this - PHP output won't automatically be cached, so you need to add the headers yourself. Doing this properly can dramatically speed up your application.
You can play with this to add sub folders if that's justified, adjust the size of your cached resized images, etc.
Good luck!
First of all as suggested by everyone storing images in DB is not a good idea... I think here by "Caching Layer" you mean not to fire a query to database if image is already present in filesystem.. if thats the case ...
Keep all the final images which you have created from using script in a directory. Then use a rewrite rule which serves the image if present, otherwise pass off the creation to PHP.
More explanation..
http://www.sitepoint.com/forums/showthread.php?719010-PHP-image-caching-in-server
First off designate a directory for your cache to live in ... this should be writable by the web server.
Then map your request parameters to a filename in that directory.
$filename = $_GET["id"]."_".$_GET["width"].".jpg";
Then you will basically follow this pattern.
if (!file_exists($cache_dir.$filename)){
// do your db query get the image and resize it to the width and then
// save it to $cache_dir.$filename
}
header("Content-Type: image/jpeg");
header("Content-Size: ".filesize($cache_dir.$filename));
readfile($cache_dir.$filename);
You may also want to add a check to see if the cache record has expired (time vs modified time) along with the file_exists check.
To manually flush something from the cache you can just delete the files from the cache directory and they will be regenerated, you may want to perform this when a database record is updated with a new file to keep the cache up to date.
recently i have tried to store images in Mysql database (use BLOB data type), using php and web to upload and store it. It works fine, except when loading large enough image , it is going to load very slowly. Is there any way to load this image faster ?
note : my friend suggests me to use force caching to this image ( he says something about change the content-header of image ), but i don't know how to do it. and i doubt it will bring significantly better performance.
Thanks in advance
The images should definitely be cached. I think this can be done mostly just by making sure the image url you make is always the same for the same picture. What I think your problem is though is you need to change max_allowed_packet. If this is too small it won't be able to send much data over the network at one time. Also if the pictures are truly that big I'd also consider changing the quality of the picture to maybe 70%? All the resize image functions have a way to change it. ie: http://php.net/manual/en/function.imagejpeg.php. Hope that helps. I'd also look into YSlow. It'll help point out what exactly is wrong with your images that is making it load slowly. Whether it is quality, cache, compression or w/e it may be.
Caching the images could be used when images stored on filesystem. If they are dynamically popped and printed from the database they will be fetched each time the PHP code ask for them.
It could be that images are fetched in a dozens of ms, but a 3MB image data could be downloaded to clients browser for 5 seconds to 1 minute (depending on the connection speed). There is not much to do with it (even less on common shared hostings).
I would suggest storing the images on a filesystem so they could be cached by the browser, or You could even set a memcache on Apache server so until the expire they would be served from the cache.
I guess that caching can be good or not. Instead of I suggest you to upload images or other files to a folder and save on DB just the information about file: name, type, size, folder, etc...
If you don't have any requisite that requires you to store an image in the database, images are better inside a folder and what you should store in the database is the path or the name of each of them.
This would make them load normally. Just depending on the size of the image, of course.
That's what you will find in almost all web applications.
I'm creating a blog with a featured image on each post. I have a dilemma, I'm unsure what to do with my image data...
Should I insert image data into my MYSQL database using BLOB?
Or should I just create an uploader which makes a directory into the users images folder and upload the photo that way...then just reference it directly in the image field when adding a Blog Post?
Is there a standardised way?
Kind regards,
adam
Upload the files to your server and save the location of the file in your database. Less strain on your DB and your HTTP daemon is better at serving images than MySQL.
The general approach is not to store files in DB, unless you understand why do you need it to be stored there. So, since you are not sure, it's much simplier storing them in upload folder.
But, just in case you decide you need storing files (no matter images or some other) in DB, you have to declare BLOB field and then save it using some BLOB-supporting DB mechanism. 'PHP's MySQLi extension: Storing and retrieving blobs' is a good example of how it can be made
You should store images in folder. Click on below link from where you can get idea how to crop different-different size images and store images name in to database table:
How can I upload images in a normal insert form (MySql)? after upload the image should have three versions of different sizes and different names
convert the image data to base64. This can be done within PHP:
<?
$image=file_get_contents("image.png");
$image=base64_encode($image);
?>
Storing images in a DB is a good idea for secure images.
Always store images, music files etc in system files on disk, and then store the urls to them in the database. That will make it
1) faster
2) easier to configure security settings
3) better in any ways I can imagine
Disadvantage
If file system is corrupted you will have hard time recovering.
You can also use third party Image hosting sites too, you can use Amazon S3 or Mosso Cloud Files.
Problem with file system is it is difficult to scale.
Facebook uses cassandra to store images.
Since it is blog you can store images in filesystem.
Both are valid approaches.
They have different advantages/disadvantages.
Storing it in the database means you need to add extra code to change the image to a representation which will fit inside a INSERT/UPDATE statement (base64 is one approach, and requires equivalent decode, but you could just use mysql_real_escape_string()). Although you can't query the image directly (other than finding exact matches) it may reduce the number of seek and I/O operations required to retrieve the data compared with looking up the path in the database then retrieving the file.
It's also a lot simpler to set up replication of a database compared with setting up replication of the database AND the filesystem if you run on multiple nodes. And there's the issue og keeping filesystem and database backups synchronized.
OTOH, using a filesystem makes your data tables much smaller, and therefore faster to retrieve records from.
which makes a directory into the users images folder
You certainly don't want to allow users to upload content directly into your webserver's document tree - regardless of which route you take, the data should be stored in a location not directly accessible by the webserver but accessible by your code.
which is a better place to upload images to? A database or in the web directory? And why?
You should only store images in your database if you have a specific need to, like security, or like an absolute to-die-for need to keep all custom data in a database.
Other than that, getting large files into databases usually isn't worth the trouble. Storing and retrieving the file get that much more complicated to implement, and database updates/upgrades/conversions have that many more things that can go wrong.
I don't see that there is an advantage storing images in a database. There is certainly no inherent security in this. Files are for the filesystem so store your images in there.
I don't think you can "upload" an image to a database. You can store the image's string value in the database and stream it via "header("Content-Type")" later on. That saves space in your web server, but obviously takes space on your database.
If I were you, I'd upload to a web directory, that way you have the image for a regular URL request later on. If you don't have it in a regular directory, you'll have to connect to the database every time the image is requested, and stream it then.
Well It depends on your requirement.
If you are considering security as a major issue then definitely you should store it in db other wise nothing will leads you to store images in db.
Also retieving images from database is quite complicated as in database images are stored as binary data. So if you have specific need then only store images in database other wise storing images in directory would be fine.
As you can see there are many reasons why to use/why not to use the database for image storage. Personally I prefer not to use the database for storage of files (images, documents etc), except when I'm ordered to store them.
-Sometimes you're tired and screw up a query, something like "SELECT * FROM images", this will kill the server if there are too many images with huge size (2MB and more) in the database.
-The security issue: you can still save the files in the disk and still be secure, how? Well save the files outside the web directory, whenever the file is requested read the file and give it to the user.
-If by any chance you are using MySQL: if your database has got to big (say 2-3 GB), and you are using a shared hosting, well good luck making that backup or trying to restore that image database.
It's just my point of view