I'm trying to figure out a way to store files in a database. I know it's recommended to store files on the file system rather than the database, but the job I'm working on would highly prefer using the database to store these images (files).
There are also some constraints. I'm not an admin user, and I have to make stored procedures to execute all the commands. This hasn't been of much difficulty so far, but I cannot for the life of me establish a way to store a file (image) in the database.
When I try to use the BULK command, I get an error saying "You do not have permission to use the bulk load statement." The bulk utility seemed like the easy way to upload files to the database, but without permissions I have to figure a work-a-round.
I decided to use an HTML form with a file upload input type and handle it with PHP. The PHP calls the stored procedure and passes in the contents of the file. The problem is that now it's saying that the max length of a parameter can only be 128 characters.
Now I'm completely stuck. I don't have permissions to use the bulk command and it appears that the max length of a parameter that I can pass to the SP is 128 characters.
I expected to run into problems because binary characters and ascii characters don't mix well together, but I'm at a dead end...
Thanks
In general, we don't pass binary data in SQL. We upload the file to the server, then load the image from the server into the database.
Load the image into the database from a file:
UPDATE images
SET image = LOAD_FILE('images/myimage.jpg')
WHERE image_id = 1234
Get the image back out to a file:
SELECT image
INTO DUMPFILE 'images/myimage.jpg'
FROM images
WHERE image_id = 1234
Here is an example I've found in David Hayden's blog.
It's a c# example, but the steps should be similar in PHP:
Convert your uploaded file to a byte array
Execute dynamic TSQL on the server
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 am building a database for a company. They want a MySQL database and they want to store images for over 11,000 products. I just wanted to know if there is a way or command to say point to a file where the images are stored.
Just save at as a VARCHAR, and that value represents a path to that file. Then just do:
$q=mysql_query("select path from images where id=123");
if($r=mysql_fetch_array($q)){
echo '<img src="'.$r['path'].'">';
}
Regarding the other option, you can store images as BLOBs in mysql, but then you have to go through mysql to get it. And you'll have write a script that will send an image to the browser. I think it's much better to keep them on the filesystem, and just use mysql to point to them. Then when an tag is sent to the browser, your webserver will handle the serving of that image correctly for you. Also, if you have shell/ftp access to your server, it will make managing/viewing your images a lot easier and simple.
You can store the files in table columns with the blob datatype.
Either that, or store the server file path in a string(varchar) field, and retrieve files using server code, after reading from the database.
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.
I am struggling to come up with a process to upload a file with a form i am working on an application that needs the user to upload a file then insert it into a database.
i have setup a database with.
TABLE - tracks
track_name
track_bpm
track_rate
track_ref
track_special
track_file // This is where i need the uploaded file to go
I am stuck on process here is where i have got so far.
http://html5up.users35.interdns.co.uk/
I am looking at doing a you tube style filling out the form while your file uploads, the file could be up to 2gig, then insert file when completed into sessions id here is a snippet of my file-upload.php
mysql_query("UPDATE tracks SET track_file = '".$file_name."'
WHERE session_id = '".$_SESSION['id']."'");
Can someone please help me with the correct process or at least a decent tutorial or way off doing this correctly been Googling for ages.
Is passing a session id the correct way to do this?
Any help please everyone
Advices:
mysql_* functions will be deprecated soon, use PDO or mysqli
Don't store files in the database, try to store only paths to the files.
Learn, how to sanitize SQL-queries.
You can store your files into the database (See Why store binary data in MySQL?), in MySQL that's done in a BLOB field.
You insert the data into the table by reading it from the uploaded file and then send that data over to the database with a standard SQL query.
There are plenty of tutorials available on the web, one is Uploading Files To MySQL Database.
If you store the file on disk, then just store the file on disk. Just take care that the insertion/updating/deleting of the data in the database is atomic with the operation on the file (creation of the file/updating;renaming/deletion).
I want to upload a large file of maximum size 10MB to my MySQL database. Using .htaccess I changed PHP's own file upload limit to "10485760" = 10MB. I am able to upload files up to 10MB without any problem.
But I can not insert the file in the database if it is more that 1 MB in size.
I am using file_get_contents to read all file data and pass it to the insert query as a string to be inserted into a LONGBLOB field.
But files bigger than 1 MB are not added to the database, although I can use print_r($_FILES) to make sure that the file is uploaded correctly. Any help will be appreciated and I will need it within the next 6 hours. So, please help!
You will want to check the MySQL configuration value "max_allowed_packet", which might be set too small, preventing the INSERT (which is large itself) from happening.
Run the following from a mysql command prompt:
mysql> show variables like 'max_allowed_packet';
Make sure its large enough. For more information on this config option see
MySQL max_allowed_packet
This also impacts mysql_escape_string() and mysql_real_escape_string() in PHP limiting the size of the string creation.
As far as I know it's generally quicker and better practice not to store the file in the db as it will get massive very quickly and slow it down. It's best to make a way of storing the file in a directory and then just store the location of the file in the db.
We do it for images/pdfs/mpegs etc in the CMS we have at work by creating a folder for the file named from the url-safe filename and storing the folder name in the db. It's easy just to write out the url of it in the presentation layer then.
Some PHP extensions for MySQL have issues with LONGBLOB and LONGTEXT data types. The extensions may not support blob streaming (posting the blob one segment at a time), so they have to post the entire object in one go.
So if PHP's memory limit or MySQL's packet size limit restrict the size of an object you can post to the database, you may need to change some configuration on either PHP or MySQL to allow this.
You didn't say which PHP extension you're using (there are at least three for MySQL), and you didn't show any of the code you're using to post the blob to the database.
The best answer is to use an implementation that is better and also works around that issue.
You can read an article here. Store 10MB, 1000MB, doesn't matter. The implementation chunks/cuts the file into many smaller pieces and stores them in multiple rows.. This helps with load and fetching so memory doesn't also become an issue.
You could use MySQL's LOAD_FILE function to store the file, but you still have to obey the max_allowed_packet value and the fact that the file must be on the same server as the MySQL instance.
You don't say what error you're getting (use mysql_error() to find out), but I suspect you may be hitting the maximum packet size.
If this is the case, you'd need to change your MySQL configuration max_allowed_packet
You don't say what error you're getting (use mysql_error() to find out), but I suspect you may be hitting the maximum packet size.
If this is the case, you'd need to change your MySQL configuration max_allowed_packet
Well I have the same problem. And data cannot be entered in the mysql database chunck by chunck in a "io mode"
loop for :
read $data from file,
write $data to blob
end loop
close file
close blob
A solution seems to create a table with multi-part blobs like
create table data_details
(
id int pk auto_increment,
chunck_number int not null,
dataPart blob
);
???