I have a problem in saving file data and retrieving content in original form using SQL Server.
To save content, I have used this code
$size = filesize($file);
$fp = fopen($file, 'rb');
$content = fread($fp, $size);
$content = addslashes($content);
fclose($fp);
and database to store its content is of type image.
Never do addslashes to binary files.addslashes should only be done on text data.
Image files,audio video files and executable all are binary files.
Try removing addslashes and try again.If it still doesn't get inserted into your database then you should check if the datatype of the column in your database is set to blob.Only blob datatype can hold binary data.
If still you have problems inserting to database then try inserting smaller images of size smaller than 1mb. php has a default post and file upload limit of 2mb.
Related
I have upload one image and want to store it in base64 encoded format in database. for some images it is not working to store in database.
In my local system it is working for all images but on live server it not stores some of images in base64 format in mysql database . my code to store image in database is below,
$handle = $_FILES["file_name"]["tmp_name"];
$fileObj = $req->files->get('file_name');
$filename = $fileObj->getClientOriginalName();
$fileInfo = pathinfo($filename);
$fileExt = $fileInfo['extension'];
$file1 = $req->files->get('file_name');
$mime = $file1->getMimeType();
$fileName = base64_encode(file_get_contents($handle));
$File = new File();
$File->file_name = $fileName;
$File->save();
from above code if I chane below line then it is working
$fileName = (file_get_contents($handle));
but I want to store it in base64 encoded format in mysql database
in my data table this field's type is "long blob".
If you base64 the image, the column should be longtext. Blob are for binary.
But think again before storing files to database.
Storing image to database is a bad practice because whenever your app layer (in your case, php) retrieve the images, it will increase your memory usage and if you are retrieving list, your server can easily out of memory if multiple users are using the same function.
Storing data as base64 make it worse because the data size is bigger (8/6)
The best practice is to store the file in a file server and only the necessary meta or link in the database.
Storing image details instead saving a blob is better. You can store all images on another server or the same server in a folder and store the path , name of that image in mysql. To retrieve it you can simple get the file from the path stored in mysql.
I have a PDF file on my server that I want to select and transform into a blob for insertion into my database (using an INSERT INTO command). My first problem is getting hold of the PDF using PHP. I know it is done with the file_get_contents() function, but I do not understand what parameters it needs.
$fp = fopen($fileLocation, 'r');
$content = fread($fp, filesize($fileLocation));
$content = addslashes($content);
fclose($fp);
You can save the $content to blob field in mysql
The problem is when I receive email attachments images/binary data becomes corrupted however when I upload files to the same database table they aren't corrupted.
On the left side is the normal image that works (when renamed to PHP and it's binary data is copied). The right side is the image after it's been corrupted. I figured I'd add the image because someone may see it and just know what is going on here. PHP code below...
So I have other files including images stored in the database and they work just fine...
$data = fread($fp, filesize($tmpName));
$data = addslashes($data);
//INSERT INTO table (data), ($data);//etc
However the error is occurring in the PHP code that I use to clean up emails and then store them in the database along with attached files. I know that the attached files are being targeted in PHP correctly so it's simply HOW I'm storing it which seems to be the problem. The data column in MySQL is longblob and uploading images before sending them works fine but when I RECEIVE emails this code that handles putting received attachments is what breaks (using the same database table).
$data = mysqli_real_escape_string($connection,base64_decode($email['attachments'][$t]['attachment']));
$data = mysqli_real_escape_string($connection,$email['attachments'][$t]['attachment']);
$data = base64_decode($email['attachments'][$t]['attachment']);
$data = mysql_real_escape_string(base64_decode($email['attachments'][$t]['attachment']));
$data = addslashes($email['attachments'][$t]['attachment']);
I'm trying to debug this issue by posting raw PNG image data to the server with the help of Postman. Here's a screenshot, which might help to understand the issue:
On the server I'm receiving the file as follows:
$png = $GLOBALS["HTTP_RAW_POST_DATA"];
Then I write the data to a new file:
$fh = fopen($myFile, 'w') or die("can't open file");
fwrite($fh, $png);
fclose($fh);
The file gets saved correctly, but it now has a different file size,
417KB instead of 279KB which is the size of the original file.
Now of course, I can't do any image operation as none of the functions (such as getimagesize which returns bool(false)) recognizes the file as a valid image.
I have debugged this process to a point where the issue must be somewhere in the file operations, but I don't understand why the file just doesn't result in the very same file type and size as the original, when the only thing I am doing is using the same raw data.
UPDATE:
I've now compared the encodings of the original file with the uploaded one,
and the former is in ISO-8859-1 and it displays correctly, the latter is in UTF-8 and has about 138kB more in file size.
Now I've achieved to convert the file on the server to ISO-8859-1.
fwrite($fh, iconv("UTF-8", "ISO-8859-1", $png));
The resulting file does now have the same output file size (279kB),
but it is still not recognized as a PNG image, some information seems to still get lost.
UPDATE (1):
I've been able to examine the issue further and found out, that the original file is exactly 4 bytes bigger than the generated file, thus the resulting PNG seems to be corrupted.
UPDATE (2):
I'm now able to save the file and open it as a valid PNG. The following code seems to be saving the image correctly:
$input = fopen("php://input","r+");
$destination = fopen($myFile, 'w+');
stream_copy_to_stream($input, $destination);
fclose($input);
fclose($destination);
However when trying to open the file with the imagecreatefrompng function I get a 500 error. I'm now trying to figure out if it's a memory issue in PHP.
Problem might be the way you test your POST by copying the "binary" data into a text field.
If you paste the same data into a text editor you won't get a valid image file either when saving this with the png extension.
Try to build a simple form with file field to test your upload
I use nginx for uploads and haven't had a problem, but I use the standard PHP way of uploading files as per: http://www.php.net/manual/en/features.file-upload.post-method.php
I would suggest trying that.
Try using: < ?php $postdata = file_get_contents("php://input"); ?>
To get the raw data. I use it some times to get data sent from a ajax post on cake.
I am using the following scripts to test inserting and then reading blob data.
insertion script:
include('session.php');
$provider =$_POST['provider_id'];
$trd_period =$_POST['trading_period_month'];
$pdf_statement =stream_get_contents(fopen($_FILES['pdf_statement']['tmp_name'], 'rb'));
$pdf_statement_clean=addslashes($pdf_statement);
$insert="update rd_provider_statement
set pdf_statement='".$pdf_statement_clean."', creation_user_id='SCO'
where provider_id='".$provider."' and trading_period_month='".$trd_period."'";
mysql_query($insert);
mysql_query("COMMIT");
echo mysql_error();
Download Script:
include('session.php');
//Gather Post Variables
$TP_Month =$_POST["trading_period_month"];
$provider =$_POST["provider_id"];
$TP_format =substr($TP_Month, 0, 7);
//Download Statement
$sql_qry="select *
from rd_provider_statement
where provider='".$provider."' and trading_period_month='".$TP_Month."'";
$sql_err_no=sql_select($sql_qry,$sql_res,$sql_row_count,$sql_err,$sql_uerr);
$row = mysql_fetch_assoc($sql_res);
$bytes =stripslashes($row['pdf_statement']);
header("Content-type: application/pdf");
header('Content-disposition: attachment; filename="'.$provider.'statement'.$TP_format.'"');
print $bytes;
However, when the file is downloaded it cannot open on the grounds that it is not a supported format. I use the basis of the script on another page to download blob data from the database however the insertion into the database here is done by a mysql procedure and not PHP. I think it is my insertion script that is causing the problem.
try using mysql_real_escape_string() instead of addslashes(). it might fix you problem.
For debugging, you might calculate the md5() of the string before inserting into DB and then after retrieving it. I bet you're going to get different hashes, meaning you're not inserting it correctly and your binary data gets corrupted when inserted into the DB.
Side notes:
don't use inserts like that, use binding - How to bind SQL variables in Php?
check for errors and STOP, dont simply echo them(i hope you're doing this in your production code)
Generally you wouldn't want to have any output code before your http header description. See http://php.net/manual/en/function.header.php
Either store the filename and other file information in a session then just access them in another page.
A few things that you need to check:
max_allowed_packet in my.ini should be equal or higher than the file size that you're expecting to store in the database
check to see if the data type that you selected fits the file that you will store. There's tiny blob, blog, medium blob and long blob. You might want to try the largest which is long blob.
I'm not sure about this one but did you already check if file_get_contents works:
mysql_real_escape_string(file_get_contents($file))
Here's my alternative answer.
First the update query:
Prepare the file (assuming that your file is not a binary file):
$tmpName = $_FILES["pdf_statement"]["tmp_name"];
$fp = fopen($tmpName, 'r');
$data = fread($fp, filesize($tmpName));
$data = addslashes($data);
fclose($fp);
$insert="update rd_provider_statement
set pdf_statement='".$data."', creation_user_id='SCO'
where provider_id='".$provider."' and trading_period_month='".$trd_period."'";
DOWNLOAD:
enter code here
$sql_qry="select provider_id, pdf_statement
from rd_provider_statement
where provider='".$provider."'
and trading_period_month='".$TP_Month."'";
$sql_err_no=sql_select($sql_qry,$sql_res,$sql_row_count,$sql_err,$sql_uerr);
$row = mysql_fetch_assoc($sql_res);
$name=$row['provider_id'];
$file=$row['pdf_statement'];
header("Content-Disposition: attachment; filename=\".$name_statement.$TP_format.\";" );
echo $file;
Hope it helps =)