We are working on a website that has tons of images and one of the requirement is to have ALT text for each image (JPG, JPEG, PNG, GIF etc). So whenever the HTML shows and image the ALT text for that image is also written to HTML along with IMG SRC.
After our discussion with developers the solutions that turned up are
1) Create a new table to hold all these image names. Then each time the image is used a db lookup is done and appropriate ALT text is added.
2) Another solution is to write some EXIF info into each file and each time they are used the EXIF info of the file is read and added to HTML as required.
Any suggestions on how to proceed. There are a lot of images so we are looking for the best solution with least load on server and loading time.
Additional info - We run PHP on our server to select images etc.
Thanks
I'ld rule out EXIF as it does not support PNG and GIF.
The db lookup sounds okay (to me) and would scale okay (as long as you did it cleverly). For example you should try to reduce lookups as much as possible.
You might even already have some of this data, and it would be useful to have data about the images anyways
I would recommend storing it in the database because I am sure you have to maintain records of these images, adding another column to a table is little work. Also, if its inside the database you can perform searches on the alt text in case you want to have such a feature.
If you wan't to give the images an alt text, it should be something that works correctly if the image is not there.
I shouldn't be "image's alt text", or "image.jpg". Rather it should be something like "Stackoverflow.com has a lot of questions and answers." when showing a SO screenshot. But if your image can't have a meaningful alt text, then just make alt="", and move on, sometimes it's simply better to give no alt text than giving a bad alt text.
Because of this, you should store the alt text for every image that means something, and not put meaningless alt text (ruling out EXIF information).
If you can live with the alt tags matching the name of the file, you can use some javascript to get all the images and add an alt tag based on the name of the file.
Something like this:
//get all the img tags
var images = document.getElementsByTagName('img');
for (i=0;i<images.length;i++)
{
//get the filename from the src
filename = images[i].src.substring(images[i].src.lastIndexOf('/')+1,images[i].src.lastIndexOf('.'));
//do any formatting here
filename = filename.replace('_',' ');
//set alt/title tags
images[i].setAttribute('alt', filename);
images[i].setAttribute('title', filename);
}
I would avoid option 2 because if you wanted to update the alt text you would need to write to the image file each time, also, if you wanted to process the images eg. generate thumbnails, the meta-data might be lost.
Option 1 seems the most logical, and if you're querying for filenames from a DB, then just get the alt text at the same time.
Maybe third option:
store ALT text in filename :)
While both solutions seem fine to me the question about required load is a bit tricky: if you get the images from a database anyway I'd store the alt tag values in the database as well. If the files are served from a directory it depends on if you are using a database at all. If you don't use a database going the EXIF route sounds like a reasonable alternative, but might create more load than using an additional database as you need to open each file to retrieve the EXIF data.
In short, go the database route if you already use a database.
I would suggest the database option, because the EXIF option will become a problem if somehow an image has to be switched with another image (transferring EXIF data is not trivial), plus parsing a lot of image files on each request would be very resource consuming.
But be it with the database or the EXIF option, I would strongly suggest that you generate a php file acting as a cache, with an associative array of image_name => alt_text, because you don't want 30 sql queries on each page load. The php file would be included as a bootstrap, so every script would have acces to the associative array, via a global variable for example.
And you would have a script that generates this file, so whenever an alt text is changed, you can easily regenerate the cache file containing the associative array.
Honest question: do you really even need to create a new table? If you're using a PHP upload mechanism anyway, couldn't you simply add a new field to the database and add the alt text, then link it as a variable as needed? The PHP would be very simple from there. Just a thought!
If you already have a database (which I presume you do), then don't add a whole new table, just add a column to the existing table where your images are. Then you can just get all the information with the same query you populate your page with. I believe this is the best option.
When you say "a lot of images", how many are we talking about? Hundreds, or thousands?
If you're in the hundreds, I would just create a PHP file with an array of the imagePath/altText pair. Then include this PHP file wherever you are referencing the image. To abstract the implementation, have a method in the PHP file to return the altText given the complete image path.
$texthash = array(
"/some/path/imageName.png" => "some alt text"
, "/some/path/imageName2.png" => "some other alt text"
);
function get_alt_text($imgpath) {
return $texthash($imgpath);
}
This strategy is fast and will not slow down your pages as long as the number of images is still relatively small. The only tricky part is making sure you keep the array sorted by image path as new images are added.
Once the number of images gets large enough that this method is slowing down performance, move the information to the database, and change the method in the PHP file to query the database. Since you've abstracted the implementation, you won't need to change any of the referencing PHP files.
Also make sure you are HTML-escaping the alt text before using it in the HTML.
Related
I have a simple image upload form. When someone uploads an image, it is for a football pool, so there always is a $poolid that goes with the image they upload.
Right now, I am naming the uploaded image using the poolid. So for example, if someone uploads an image, it might get named P0714TYER7EN.png.
All the app will ever do is, when it outputs the football pool's page, it will check to see if an image exists for that pool and if so, it will show it. It checks like this:
if (file_exists("uploads/".$poolid.".png")) { //code to show it }
My first thought when planning this was to add a field called "image" in my MYSQL database's table for all the pool information (called pools) and I would store a value of either the image name (P0714TYER7EN.png) or empty if there wasn't one uploaded. Then I would check that field in the database to determine if an image exists or not.
But I realized I don't really need to store anything in the database because I can simply use the PHP file_exists check above to know if there is an image or not.
In other words, it would seem redundant to have a field in the database.
Everything works doing it this way (i.e. NOT having a field in the database) but I'm wondering if this is bad practice for any reason?
If anyone feels that I should absolutely still have a field in the database, please share your thoughts. I just want to do it the proper way.
Thank you.
The approach could depend a lot on what exactly you're trying to do. Seems like the options you would have is:
File System Only
Benefits would be the speed of accessing static files of an image and use of it in your HTML directly which makes it a more simple solution. Also if you're comfortable with using these functions it will be faster to finish.
Drawbacks would be that you're limited to using file_exists and similar. Any code to manage files this way has to be very specific and static. You also can not search or perform operations efficiently on this. In general relying on the file system alone is not a best practice from my experience.
Database Only
Benefits, you can use Blob type as a column with meta data like owner, uploader, timestamp, etc. in the same row. This makes checking for existing files faster as well as any searching or other operations fast and efficient.
Drawbacks, you can't serve files statically using a CDN or even a cookie-less subdomain or other strategies for page performance. You also have to use PHP and MySQL to generate then serve any images via code rather than just referring to the image file directly.
Hybrid
Benefits, basically the same benefits as both above. You can have your metadata in MySQL with a MD5 hash and location of the file available as well. Your PHP then renders the page with a direct link to the file rather than processing the Blob to an image. You could use this in conjunction with a CDN by prefixing or storing the CDN location as well.
Drawbacks, if you manually changed names of files on the server you'd have to rely on a function matching hashes to detect this, though this would also affect a File System Only that needs to detect a duplicate file potentially.
TLDR; the Hybrid approach is what you'll see most software use like WordPress or others and I believe would be considered a best practice while file system only is a bit of a hack.
Note: Database only could be a best approach in specific situations where you want database clustering and replication of images directly in your database rather than to a file system (especially if the file system is restricted access or unable to be modified for any reason, then you have full flexibility on the DB).
You can also use the blob datatypes from mysql. There you can save the image as binary data next to the data about the football pool.
So when you want to load an football pool you simple fire an sql statement and check if it returns a result, if so load the image from the database and display the data, otherwise throw an error.
If you have very frequent access you can simply put the images into a seperate table and load the image independent of the data about the football pool. Additional set some cache headers on the image and put it in a seperate file, this way you could simply save the primary key of the images in football table. Then you want to display the web page you simply load another document, pass it the primary key of the image, there the image will be loaded, or if the browser has it in cache, will load it from cache without querying the database.
This way you also have a better consistency of data and images.
Your uploading an image to specific folder and that too with poolid which will be unique. It should work just fine.
Problem :
The code you have written works great. But the problem is, for the first time if the image loaded is .png and second time loaded file in jpeg or jpg then file exists wont check that and hence it may fail.
Caution :
If you have already taken a caution to check that the image uploaded must and should be png than the file_exists will work great.
Alternate Solution :
In case if your not checking for the image type to be .png then I highly advice you to take a boolean image column in your table by is_image_uploaded or something which can be set once you upload the file every time.
This makes sure that in case next time you wan to upload the image then you can directly go and check in your database table and see that if is_image_uploaded column is set or not. If not set then upload or else ignore or do whatever you want
I've been following multiple tutorials on uploading and retrieving images using MySQL and PHP, and they all seem to be using the same technique; upload the image as normal (no problem there) and then create another document and use a PHP script to select the image from the database then change the 'content-type' to image/jpeg, then display said document in an iframe.
That's fine and dandy; if I wanted to display one single image, and I was fine with it being in an iframe. However, I'm developing a CMS(like) system where the end user will be changing many styled images on a particular page and that technique doesn't quite work, as it appears to only work for single image.
I'm not looking to upload the files to a folder, then store the path in the database either. I'd like to store the image itself in the database.
I know this is a broad question and I definitely don't expect anyone to give me a step by step tutorial. But if you could direct me to one that would be great.
Thanks in advance.
The page used to display the image in the way you outline the tutorials show, with retrieval and then a header output is a way that sets the PHP image-calling file to act as an image file .
So you can have
<img src='phpimagefile.php?id=imgreference' alt'my image'>
for example.
If you want to display multiple images like this then you can simply roll the above HTML code into a foreach or similar loop on another page.
foreach ($imagesSet as $image){
print "<img src='phpimagefile.php?id=".$image['id']."' alt'my image'>\n";
}
Edit:
You can get really smart and with some mod_rewrite you can actually store images with filepath names such as :
<img src='/images/45757/goldenShower.jpg' alt='My Image'>
And the mod_rewrite will reorganise this to be able to find the image of:
<img src='/images/phpimagefile.php?id=45757' alt'my image'>
.
Storing the images directly in the database is cumbersome and does not solve your (apparent) problem of retrieval.
If you can clarify why being in the database is better for the image than a image output file as I describe above, this will probably show more people (judging from the comments) exactly what your current issue is.
Some Notes:
Don't use iframes. Use the HTML img tag as I example above.
We can't direct you to any tutorial until we actually understand what you're trying to gain.
Even if you upload the files to a database table, you are still going to need to store a reference to that table/row in order to reference the correct image, so imageId = 'files/image/goldenShower.jpg' is just another reference in the Database like imageId = 4365 would be.
I don't know which way is better to use about uploading and saving a file in my local server.
for example I see someone that INSERT image's link in the mysql field, I'm confused right now...
I want to upload some files and show that in other situation...
what's the best and secure way to perform that?
Store all the images in a folder called photos for example. Then, save an index of the file in your database assigning it an index number and other information. Save the file in the photos folder, renaming it [index_number].jpg, or whatever extension is needed. For example, if I upload the file coolpic.jpg, it will be assigned an index number of 2845. The file itself is saved in photos/2845.jpg.
Saving in Database may make some problems like as DB performance decrease (as result of reading and writing big files), DB crashes (as a result of delete of edits of rows fields), backup problems (because of huge dump file, some problems when table needs to be repaired.
also read file from mySQL will be delivered by Apache again.
I suggest you use of normal path with rewrite mode (virtual url)
Dont use img link.. its not necessary and all it does is just making you DB larger.
You shoud store just "picture.jpg"
and in documents use <img src="images/'.$row['image'].'">
Even better, you can create a function for it (displaying pictures).
Like
function DImage($image)
{
//you can do miracles here like checking images types, if is file and so on, padding, even adding divs and vspaces..
$output = '<img src="imagesfolder/'.$image.'">';
return $output;
}
so latter all you have to do is..
echo DImage($row['image']);
PS: if you ask about $_POST & $_FILE uploading, of course.. it is impossible for you to maintain images, names and updates I'm sure..
Firstly this is for a simple university project, so time is more important than performance of database etc.
I have a database with images stored in blob files. Now some form outputs data from this database, but i want it to also output the image, along with the text.
I realise there is a bit of code to change headers to image, but then the text wont display, so is there a way to display the image and the text on the same page?
thanks a lot,
It is possible to embed images inside HTML, but you usually do it only if you have a really good reason to. Assuming you do, you write the following code, provided that $BLOB is the binary raw data of the image:
<img src="data:image/jpeg;base64,<?php echo base64_encode($BLOB); ?>"/>
Why not use image tags like normal wherever you need the images to be, and in the src attribute, specify a PHP script along with a get argument (for instance, <img src='image.php?name=something.jpg'>). This script then authenticates the request, accesses the database, sends the appropriate headers, followed by the actual BLOB data.
I'm creating a custom CMS for my site, and I'm going to store articles (Text and images per article) in a mysql database. what datatype is best suited for that task?
You shouldn't try to store text and images in a single field, and in this circumstance you probably shouldn't store images in your database at all.
The best solution for this would be to use some kind of markup system in your articles - at it's simplest this could be a filtered subset of html - that is stored as plain text in your database and then parsed in the browser in some way. Obviously if you use filtered html you would not need to write any special code to parse it, but taking this approach does raise possible security issues.
Other options to investigate include Markdown (the system used by this site) as well as BBCode (mainly used by online forums), as well as many others.
To summarise - don't store images and text in one field. Store text, and interpret that text to load images and other media in your articles as appropriate.
Save the images as VARCHAR, but only the image name (and/or location, depending on how big is your cms), save the text as - TEXT.
In my oppinion use text for articles, containing HTML characters, thats what i use. But there are many other things to consider. It depends on what content of your articles. In your images its up to you, you will just store the path of the picture, unless you plan to store the picture itself.
Please see this article in which Microsoft insists the text datatype is going to disappear and therefore should not be used in new development. The alternatives are varchar and nvarchar for text and varbinary for images.
Store images and text separately. Assuming you are trying to store the binary images in the database, I recommend storing images as a BLOB datatype and TEXT for the text.
Don't use VARCHAR for article text because it does not dynamically expand past the size you make it.
VARCHAR would be the best choice for storing text-articles as text and images data types would disappear in the future.
For images you can store them in a folder similar to what you use for css/js and store its src value in the database. This would be efficient in terms of both speed and storage.