Trouble Inserting a Image Data to LongBlob Field - php

Total newbie here, please bear with me.
Building a very small personal app that uploads some images and info. I can't figure out why the following PHP/MySQL doesn't add the last insert in the query ($file_data) to my DB's longblob field.
All the other fields in the query insert fine, meaning I tested them one at a time, adding to the query, until I got to the last and then the insert fails. I am able to echo $file_data before the insert and see that the data is there, I've also found that hardcoding a string value for $file_data (i.e $file_data="this will insert") inserts fine... which is frustrating.
So my guesses are there's an error in the reading of the file ($fp fread etc) or that my longblob is setup wrong. File sizes are <16kb, so I'm sure it's not a php.ini issue either.
Any ideas? Thanks.
$boxtype=$_POST['type'];
$title=$_POST['title'];
if(isset($_POST['submit']) && $_FILES['imgfile']['size'] > 0)
{
$filename = $_FILES['imgfile']['name'];
$tmpName = $_FILES['imgfile']['tmp_name'];
$file_size = $_FILES['imgfile']['size'];
$mime_type = $_FILES['imgfile']['type'];
$fp = fopen($tmpName, 'r');
$file_data = fread($fp, filesize($tmpName));
fclose($fp);
$query = "INSERT INTO table
(boxtype,title,filename,mime_type,file_size,file_data)
VALUES
('$boxtype','$title','$filename','$mime_type','$file_size','$file_data')
";
$db = db_connect();
$result = $db->query($query) or die('Error, query failed');
if ($result)
{
echo "<br>Success<br>";
}
}
else die("No Content");
MySQL Table:
CREATE TABLE `port` (
`id` int(2) unsigned zerofill NOT NULL AUTO_INCREMENT,
`boxtype` tinytext COLLATE latin1_general_ci NOT NULL,
`title` varchar(40) CHARACTER SET latin1 NOT NULL,
`filename` varchar(255) COLLATE latin1_general_ci NOT NULL,
`mime_type` varchar(255) COLLATE latin1_general_ci NOT NULL,
`file_size` int(11) NOT NULL,
`file_data` longblob NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

Because its a binary, it probably contains values which means its probably throwing a wobble
Try using addslashes on the file_data variable, so it can save it.

The examples I came across while using Google showed that the data was escape either using addslashes or mysql_real_escape_string. Therefor my guess is that this is a crucial part since the $file_data string may contain various characters.

If on windows use fopen($tmpName, 'rb'); and use mysql_escape_string($file_data) .

You'll have to use the mysqli_ functions to create a prepared statement. Here is an example
$sql = 'INSERT INTO Table(boxtype,title,filename,mime_type,file_size,file_data)
VALUES (?,?,?,?,?,?)';
$stmt = mysqli_prepare($link, $sql);
mysqli_stmt_bind_param($stmt, "ssssib", $boxtype,$title,$filename,$mime_type,$file_size,$file_data);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
This will also prevent against SQL Injection attacks which it appears your code may be vulnerable to. Alternatively, you can use the PDO libraries to create prepared statements.
With PDO, you can do the following.
$sql = 'INSERT INTO Table(boxtype,title,filename,mime_type,file_size,file_data)
VALUES (:boxtype,:title,:filename,:mime_type,:file_size,:file_data)';
$statement = $con->prepare($sql);
$statement->bindParam(':boxtype',$boxtype,PARAM_STR);
$statement->bindParam(':title',$title,PARAM_STR);
$statement->bindParam(':filename',$filename,PARAM_STR);
$statement->bindParam(':mime_type',$mime_type,PARAM_STR);
$statement->bindParam(':file_size',$file_size,PARAM_INT);
$statement->bindParam(':file_data',$file_data,PARAM_LOB);
$statement->execute();

Related

Issue trying to insert data into a MySQL table with php

I have an existing table and I'm trying to insert data to it from a form submission.
I think I need another set of eyes to look over my code. There is an issue with it, at this point I'm not sure what.
I fill out the form, it appears to submit, I check the table and I get nothing. No data gets inserted.
If some of the values aren't being used right now, can that hinder the data from being inserted into the table? Shouldn't the form inputs that are on the form be inserted anyway? I tried to use only the values within the form, and that still did not work.
For example, right now the form inputs are only for first, last, title, genre, about, and picture. The rest only exist within the table. Data for the remaining fields cannot be currently entered at this time.
Hopefully someone has a solution?
$servername = "server";
$username = "user";
$password = "pass";
$dbname = "db";
if (isset($_POST['submit'])){
$conn = mysqli_connect($servername,$username,$password,$dbname);
if (!$conn) {
die("Connection failed: " . mysqli_error());
}
$first = mysqli_real_escape_string($conn, $_POST['First']);
$last = mysqli_real_escape_string($conn, $_POST['Last']);
$title = mysqli_real_escape_string($conn, $_POST['Title']);
$storylink = mysqli_real_escape_string($conn, $_POST['StoryLink']);
$genre = mysqli_real_escape_string($conn, $_POST['Genre']);
$about = mysqli_real_escape_string($conn, $_POST['About']);
$link = mysqli_real_escape_string($conn, $_POST['Link']);
$picture = mysqli_real_escape_string($conn, $_POST['Picture']);
$alt = mysqli_real_escape_string($conn, $_POST['ALT']);
$sql = "INSERT INTO ContrTemp (`First`,`Last`,`Title`,`StoryLink`,`Genre`,`About`,`Link`,`Picture`,`ALT`)
VALUES ('$first','$last','$title','$storylink','$genre','$about','$link','$picture','$alt')";
mysqli_query($conn, $sql) or die('Error: ' . mysqli_error($conn));
mysqli_close($conn);
}
Here is one input field from the form. The others are pretty much the same.
<input type="text" id="ContrTitle" name="Title" placeholder="Title" class="inputFields" style="width:650px;" />
Could there be an issue with the name within the input?
sql table structure:
CREATE TABLE IF NOT EXISTS `ContrTemp` (
`ID` int(5) NOT NULL AUTO_INCREMENT,
`First` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
`Last` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
`Title` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`StoryLink` varchar(140) COLLATE utf8_unicode_ci NOT NULL,
`Genre` varchar(11) COLLATE utf8_unicode_ci NOT NULL,
`About` varchar(2000) COLLATE utf8_unicode_ci NOT NULL,
`Link` varchar(125) COLLATE utf8_unicode_ci NOT NULL,
`Picture` varchar(500) COLLATE utf8_unicode_ci NOT NULL,
`ALT` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
Now I'm actually hitting the database, a record shows up, but no data was inserted. Before, No record was inserted at all.
You can try this one for inserting data
$sql = 'INSERT INTO ContrTemp (First,Last,Title,StoryLink,Genre,About,Link,Picture,ALT) VALUES ("'.$first.'","'.$last.'","'.$title.'","'.$storylink.'","'.$genre.'","'.$about.'","'.$link.'","'.$picture.'","'.$alt.'")';
I think you have done pretty well but one last try put these symbols [backticks] ` around your fields to understand mysql they are just fields.
$sql = "INSERT INTO ContrTemp (`First`,`Last`,`Title`,`StoryLink`,`Genre`,`About`,`Link`,`Picture`,`ALT`)
VALUES ('$first','$last','$title','$storylink','$genre','$about','$link','$picture','$alt')";
Your mysqli_error() is incorrect syntax, you need to specify the connection so have mysqli_error($conn) to properly feedback to you the SQL errors. As mentioned by Mitkosoft in comments some of your column names are MySQL keywords. It could be a good habit to get into to always encase column names in backticks.
So:
$sql = "INSERT INTO ContrTemp (`First`,`Last`,`Title`,`StoryLink`,`Genre`,`About`,`Link`,`Picture`,`ALT`)
VALUES ('$first','$last','$title','$storylink','$genre','$about','$link','$picture','$alt')";
mysqli_query($conn, $sql) or die('Error: ' . mysqli_error($conn));
Also you don't need to select db with mysqli_select_db($conn,$dbname); because the database is selected on the login command mysqli_connect above.
Further queries:
Is your database access account allowed to INSERT to this database?
Can you insert the same data as in your form directly into the database using an interface such as PHPMyAdmin, MySQL Workbench (Or whichever one you use to view the DB)?
I had hoped this had been as simple as the code I provided above, thus the reason I did not mention that this code was being used as part of a WordPress template. I did not think that would be come an issue as the template is pretty light weight.
With that said, I simply took my block of php code that handles the data insertion, and I placed it at the top of the template. Worked like a charm..

Importing CSV FIle In Wordpress Database

I wrote a php script to import a CSV file into a wordpress database. I have been working through lots of different errors today which were crashing the website till I fixed them.
Now all the errors are cleared and the string at the end of the function is being printed to the screen as if everything is ok but it is not entering my data to the DB.
Also for testing sake I removed the create DB part and only left the remove to see if it would remove the DB and it did not. So basically it appears my function does not have errors but it is being ran. Also it is not actually doing anything. I do not understand how it could run through the function telling me each time there is an error or a file path that does not exist but not actually carry out the operations I am trying to execute.
Any input on how to troubleshoot this or where to go from here would be appreciated,
function productsExec() {
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
global $wpdb;
global $simple_prod_version;
$table_name = $wpdb->prefix . "wuno_inventory";
if($wpdb->get_var("show tables like '$table_name'") != $table_name) {
$sql = "DROP TABLE IF EXISTS $table_name";
dbDelta($sql);
// $wpdb->query($sql);
$sql = "CREATE TABLE " . $table_name . " (
id int(8) NOT NULL AUTO_INCREMENT,
wuno-product varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
wuno-description varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
wuno-alternates varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
wuno-onhand varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
wuno-condition varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;";
dbDelta($sql);
// $wpdb->query($sql);
//Upload File
if (is_uploaded_file($_FILES['inventory.csv']['tmp_name'])) {
echo "<h1>" . "File ". $_FILES['inventory.csv']['name'] ." uploaded successfully." . "</h1>";
echo "<h2>Displaying contents:</h2>";
readfile($_FILES['inventory.csv']['tmp_name']);
}
//Import uploaded file to Database
$handle = fopen(inventory.csv, 'w');
while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) {
$insert = "INSERT INTO" . $table_name . "(wuno-product, wuno-description, wuno-alternates, wuno-onhand, wuno-condition)" .
"VALUES ('$data[0]', '$data[1]', '$data[2]', '$data[3]', '$data[4]')";
$results = $wpdb->query( $insert );
}
fclose($handle);
echo 'Everything seems to be running smoothly.';
}
}
As mentioned in comments, and as per OP's request:
INSERT INTO" . $table_name . " translates to, and for example INSERT INTOtablename since there is no space between INFO and "
Plus, you have hyphens for column names that MySQL is translating as wuno MINUS product, as a math equation and the same for the other column names.
Consult http://dev.mysql.com/doc/refman/5.7/en/identifier-qualifiers.html on Identifier Qualifiers
You can use hyphens, but ticks are required to be used around the column names.
$insert = "INSERT INTO " . $table_name . " (`wuno-product`, `wuno-description`, `wuno-alternates`, `wuno-onhand`, `wuno-condition`)
Edit:
I spotted something else.
$handle = fopen(inventory.csv, 'w');
There should be quotes around the filename:
$handle = fopen("inventory.csv", 'w');
as per the manual on fopen() http://php.net/manual/en/function.fopen.php
$handle = fopen("c:\\folder\\resource.txt", "r");
and error reporting would have thrown you a notice about it.
Plus, since you're using $_FILES, and if using a form, it should be a POST method and contain a valid enctype.
http://php.net/manual/en/features.file-upload.post-method.php
However, this seems invalid $_FILES['inventory.csv'] or is unclear.
Usually, the first array parameter is a matching name attribute. Consult the manual link just above.
Also add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Then the rest of your code
Sidenote: Displaying errors should only be done in staging, and never production.

MySQL PHP statements is returning junk data included with the records

Lately my newly created tables in a MySQL database are returning "\r\n\r\n\r\n" on my SELECT statements along with the stored data. I don't know where this junk data is coming from because it is not visible in phpMyAdmin. It is happening only in newly created tables, it doesn't happen in old ones.
I used phpMyAdmin to create the table, but here is the exact statement to create it:
CREATE TABLE IF NOT EXISTS `user_analysis` (
`project_ID` int(11) NOT NULL,
`uGroupId` int(11) NOT NULL,
`user_address` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`user_strengths` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`user_weaknesses` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The table information is this:
Type: InnoDB
Collation: utf8_general_ci
Here is the query I'm making:
$query = "SELECT user_strengths FROM user_analysis WHERE `project_ID` = ? AND `uGroupId` = ?";
if($stmt = $mysqli->prepare($query)){
$stmt->bind_param("ii", $this->pID, $this->gID);
$stmt->execute();
$stmt->bind_result($strengths);
$stmt->fetch();
echo $strengths;
}
I also tried not using prepared statements and hard coding the query, but it still returns junk data. I tried like this:
$query = "SELECT user_strengths FROM user_analysis WHERE `project_ID` = '10256' AND `uGroupId` = '10'";
$result = $mysqli->query($query);
if (mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_assoc($result);
echo "User strengths: " . $row["user_strengths"];
}
I used the answer found here as a temporary fix: Replacing \r\n with PHP
But working around it is not the problem. The problem is that this shouldn't happen to begin with. What could be causing MySQL to return this junk data? Again, the junk data is not visible from phpMyAdmin. I also tried inserting data directly from phpMyAdmin and carefully make sure there was no such thing as "\r\n\r\n\r\n" in what I inserted, but it still returns that junk data along with the records.
Any ideas?

SQL Insert Date Always comes out NULL

I'm trying to use an upload page to insert into my database with the following code:
if($file!=="")
{
echo "<br/>".$file;
$handle = fopen($file, "r");
$row = 0;
$delete_records = mysql_query("DELETE FROM affiliationagreements");
$delete_records = mysql_query("DELETE FROM college");
$delete_records = mysql_query("DELETE FROM program");
$delete_records = mysql_query("DELETE FROM facility");
$delete_records = mysql_query("DELETE FROM submitor");
$delete_records = mysql_query("DELETE FROM location");
//will loop each record in the CSV file
while(($fileop = fgetcsv($handle,1000,",")) !== false )
{
//columns names of the CSV file are not needed
if($row==0)
{
$row++;
}
else
{
//accept apostrophes in the strings
$fileop = array_map("mysql_real_escape_string",$fileop);
$sql = mysql_query("INSERT INTO affiliationagreements(id, AANumber, Facility, Submitor, Program, Location, College, SubmissionDate, Action, EffectiveDate, Status, ExpirationDate)
VALUES('',
'$fileop[0]',
'$fileop[1]',
'$fileop[2]',
'$fileop[3]',
'$fileop[4]',
'$fileop[5]',
'$fileop[11]',
'$fileop[23]',
'$fileop[24]',
'$fileop[25]',
'$fileop[26]')
")or die(mysql_error());
To just give a sample, and when I upload my CSV file to add the values, I print them out in the console and see that the values are being read correctly and they are. But, once my php script ends and I return to the main page, my dates are all null. None of them are the values what are reflected in the csv file. Here is the schema for my database:
CREATE TABLE `affiliationagreements` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`AANumber` varchar(20) DEFAULT NULL,
`Facility` varchar(150) DEFAULT NULL,
`Submitor` varchar(50) DEFAULT NULL,
`Program` varchar(60) DEFAULT NULL,
`Location` varchar(50) DEFAULT NULL,
`College` varchar(50) DEFAULT NULL,
`SubmissionDate` date DEFAULT NULL,
`Action` varchar(50) DEFAULT NULL,
`EffectiveDate` date DEFAULT NULL,
`Status` varchar(50) DEFAULT NULL,
`ExpirationDate` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
If I change SubmissionDate, EffectiveDate, and ExpirationDate to a varchar, they insert correctly but I can't use varchar because I am comparing date values. And Advice?
***Update. In the CSV file, the format is MM/DD/YYYY. I didn't think this would be a problem. Would it be better to change this? And I'm deleting records because my boss wanted the DB cleared before a file was reuploaded since the uploaded file was an update of the previously uploaded one. ****
Check your date format, as MySql it needs to be in YYYY-MM-DD format
INSERT INTO table SET date = '2014-05-13'
If you have different format, the date will store '0000-00-00' instead. So double check your insertion by echo your query string before running the query.
mysql date field only accepts dates in this format: 0000-00-00
You can use DATE_FORMAT() in your insert query but I can't give exaples becuase you didn't post what format your actual date is.
http://www.w3schools.com/sql/func_date_format.asp

Creating dynamic tables with MySQLi securely

I want to be able to create dynamic tables, for custom user surveys... like survey monkey... how would I go about create something like that?
Because I want to give the ability to the user to create the survey, with different amount of text fields, and different a option fields... I would need to create a custom table for each survey.
Would something like this be possible?
<?php
$table_name = 'survey_'.$_POST['surveyid'];
$query = 'CREATE TABLE ? (
`responseid` INT NOT NULL AUTO_INCREMENT,
`textarea1` TEXT NULL,
`textarea2` TEXT NULL,
`textarea3` VARCHAR(255) NULL,
`drop_down1` VARCHAR(255) NULL,
`drop_down2` VARCHAR(255) NULL,
`bool1` BIT NULL,
`bool2` BIT NULL,
PRIMARY KEY (`responseid`))';
if($stmt = $mysqli->prepare($query)){
$stmt->bind_param('s', $table_name);
$stmt->execute();
$stmt->close();
}else die("Failed to prepare");
?>
The above example comes back with "Failed to prepare", because I don't think I can prepare a table name... is there another work around using mysqli?
if(ctype_digit($_POST['surveyid']) && $_POST['surveyid']>0){
$table_name = 'survey_'.$_POST['surveyid'];
$query = 'CREATE TABLE '.$table_name.' (
`responseid` INT NOT NULL AUTO_INCREMENT,
`textarea1` TEXT NULL,
`textarea2` TEXT NULL,
`textarea3` VARCHAR(255) NULL,
`drop_down1` VARCHAR(255) NULL,
`drop_down2` VARCHAR(255) NULL,
`bool1` BIT NULL,
`bool2` BIT NULL,
PRIMARY KEY (`responseid`))';
I know I can just try to sanitize the $_POST['surveyid'] (like I did above) but I prefer to prepare it if possible.
$table_name = 'survey_'.$_POST['surveyid'];
Do not do the above. It is easy for a hacker to exploit your site if you include $_GET or $_POST data directly in any SQL string.
But you can't use parameters for a table name. A parameter takes the place of a single scalar value only. You can prepare CREATE TABLE but you can't use parameters for identifiers (e.g. table names).
The best practice is to make sure your table name conforms to a rule, for example only the leading portion of a string of numeric digits, up to the maximum length of a MySQL table name:
$table_name = 'survey_' . strspn(trim($_POST['surveyid']), '0123456789', 0, 56);
If you have other rules for a surveyid, then you could use preg_replace():
$table_name = 'survey_' . preg_replace('^(\w+)', '$1', trim($_POST['surveyid']));
It is not possible to prepare a data definition language statement like "CREATE TABLE". I can't find the reference in the MySQL docs that explains this, but I did find a good explanation on the PHP documentation site.

Categories