PHP MySQLInsert prepared statements - php

I am working on learning about PHP prepared statements and implementing them when using the MySQL INSERT command. I am able to do this just fine without the prepared statements, but I am confused on where I went wrong in my code after adding prepared statements.
The below code gives me the "Internal Server Error", but it appears to be syntactically correct.
EDIT:
Here is dbConnet.php:
<?php
$hostname = "*";
$username = "*";
$database = "*";
$password = "*";
$link = mysqli_connect($hostname, $username, $password, $database);
if (!$link)
{
die('Could not connect: ' . mysqli_connect_error());
}
?>
Code:
<?php
include('dbConnect.php');
$stmt = $mysqli->prepare("INSERT INTO Articles (content, date) VALUES (?,?)");
$stmt->bind_param('si', $article, $submitTime);
$article = $_POST['articleArea'];
$submitTime = new DateTime();
$submitTimeString = $submitTime->format("m-d-Y H:i:s");
$stmt->execute();
if (mysqli_query($link,$stmt) )
{
echo "<script language='javascript'>alert('Article has been submitted!')</script>";
echo "<script language='javascript'>window.location = 'URL'</script>";
}
else
{
echo "<script language='javascript'>alert('Uh oh! An error has been encountered! Please try to resubmit your article.')</script>";
echo "<script language='javascript'>window.location = 'URL'</script>";
}
mysqli_close($link);
?>
Any insight into my issue is greatly appreciated. If you need me to add more info, please let me know!
Thanks in advance

Try using
$stmt = $link->prepare("INSERT INTO Articles (content, date) VALUES (?,?)");
$stmt->bind_param('ss', $article, $submitTimeString);
$article = $_POST['articleArea'];
$submitTime = new DateTime();
$submitTimeString = $submitTime->format("m-d-Y H:i:s");
Instead of
$stmt = $mysqli->prepare("INSERT INTO Articles (content, date) VALUES (?,?)");
$stmt->bind_param('si', $article, $submitTime);
$article = $_POST['articleArea'];
$submitTime = new DateTime();
$submitTimeString = $submitTime->format("m-d-Y H:i:s");
If that error is being caused by trying to connect to the database with both $link and $mysqli (as pointed out by deceze) this should fix that issue. As for the date, I would suggest changing "date" to a "text" datatype in your database (hence the $stmt->bind_param('ss', $article, $submitTimeString); vs $stmt->bind_param('si', $article, $submitTimeString);)

Your database connection is $link, yet you use $mysqli->prepare(..). Which is it?
You're execute()ing the $stmt, yet you also next use mysqli_query(). That's nonsense. Use one or the other, not both.
mysqli_query() expects a query string, but you're giving it a prepared statement object.
You're binding $submitTime to the statement, which is a DateTime object, which mysqli will likely not like. You're never using your formatted date $submitTimeString anywhere.
Any one of these mistakes will likely trigger the fatal error. You need to rewrite that from scratch. Read the manual for how to use the mysqli extension.

is $submitTime defined at the time it is bound to $stmt?
Both $article and $submitTime are initialized after being bound.
And you should bind the date string, not the DateTime object.

the $submitTimeString format is wrong. MySQL expects datetimes as date('Y-m-d H:i:s') (year first)

Related

PDO Insert Into DB

I've seen so many tutorials with so many different ways to insert using PDO. None of them seem to work for me. Can't seem to get mine to send to the database. I have no issue connecting and retreiving the data using FETCH but can't seem to post this data.
Any help with getting my post to work and redirect using the header or meta refresh would be nice. I am $_POST from an html form. Connecting to the db works just fine but can't get the data in.
$hostdb = 'myremoteip';
$namedb = 'cpdemo';
$userdb = 'root';
$passdb = 'mypassword';
$conn = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb);
if(isset($_POST['fname'])) {
$fname = $_POST['fname'];
$lname = $_POST['lname'];
$title = $_POST['title'];
$photo = $_POST['photo'];
$stmt = "INSERT INTO row_users (fname,lname,title,photo)
VALUES (:first,:last,:title,:photo)";
$q = $conn->prepare($stmt);
$results = $q->execute(array(
":first"=>$fname,
":last"=>$lname,
":title"=>$title,
":photo"=>$photo
));
echo 'User Added<br/>';
}
header ('Location:../insertUser.html');
exit();
What you have to understand that there is no such thing like "PDO Insert Into DB"
There is INSERT query, irrelevant to PDO but regular to database you are using.
And there is PDO prepared statement, irrelevant to query type. You have to follow exactly the same pattern, no matter if it insert or delete.
So - all you need is just a tutorial on PDO prepared statements. That's all. Preferably one that teach you to enable error reporting in the first place.
As requested by OP, comment leading to an answer (to close the question and marked as solved).
I tested your code "as is", and it worked fine.
The only thing I can tell that could be the issue is, that your insert won't happen unless it meets the conditional statement you've set if(isset($_POST['fname']))
Check to see if your HTML form's elements are indeed named?
I.e. <input type="text" name="fname"> etc. If one of those are not not named or has a typo, then your whole query will fail.
You can try binding parameter before passing it to execute, like for example in the below code
<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
// insert another row with different values
$name = 'two';
$value = 2;
$stmt->execute();
?>

What is wrong with my MySQL query?

So, I have a form that posts to my php file using ajax, and succeeds. But the following query doesn't insert anything. Can someone help me understand what I'm doing wrong?
My php file:
<?php
include 'connect.php' ;
$type = mysql_real_escape_string($_POST['type']);
$title = mysql_real_escape_string($_POST['title']);
$content = mysql_real_escape_string($_POST['content']);
if ($type == 'Just Text') {
mysql_query("INSERT INTO articles (title, type, thisisaninteger, content) VALUES ('".$title."', '".$type."', 0, '".$content."')")or die("MySQL Error: " . mysql_error());
}
?>
My connect.php:
<?php
$dbhost = "localhost";
$dbname = "example";
$dbuser = "test";
$dbpass = "test";
mysql_connect($dbhost, $dbuser, $dbpass) or die("MySQL Error: " . mysql_error());
mysql_select_db($dbname) or die("MySQL Error: " . mysql_error());
?>
If you aren't receiving any errors and the INSERT just doesn't happen, it is most likely because the if statement fails to be true. Verify that $type actually matches Just Text.
You should also be inserting values using prepared statements, and use PDO or MySQLi - this article will help you decide which.
first, echo "something" after the if statement and recall the data with your ajax post. you can find out if your if statement is working, then try formatting your variables like so
mysql_query("INSERT INTO articles (title, type, thisisaninteger, content) VALUES ('$title', '$type', 0, '$content')")or die("MySQL Error: " . mysql_error());
I just want to throw in an official vote/recommendation in favor of switching to a parameterized SQL statement, too. In spite of the use of mysql_real_escape_string, schlepping a SQL statement together via string concatenation is neither necessary nor a good idea. Honestly, I find a prepared statement much, much easier to read than the typical string-concatenation exercise, as well:
$stmt = $dbh->prepare("SELECT * FROM users WHERE USERNAME = ? AND PASSWORD = ?");
$stmt->execute(array($username, $password));
Alright, it was a stupid mistake on my side. There were columns I didn't include and they were not being assigned a value. Thanks everyone for helping out.

mysqli->prepare('Update')

is this code ok? because I don't get my db updated and I get no errors. Thank you.
//connect to db
$email = $mysqli->real_escape_string($_POST['email']);
$bo = $mysqli->real_escape_string($_POST['bo']);
$p1 = $mysqli->real_escape_string($_POST['p1']);
$p2 = $mysqli->real_escape_string($_POST['p2']);
$dt = $mysqli->real_escape_string($_POST['dt']);
$dt = new DateTime("2012-07-01 13:13:13", new DateTimeZone('Europe/Paris'));
//more validation code...
$stmt = $mysqli->prepare('UPDATE table SET Password=?, R_P=?, R_T=? WHERE E_mail=?')
$stmt->bind_param("ssss", $p2, $p2, $dt, $email);
$stmt->execute();
$stmt->close();
$mysqli->close();
//send email
I had no errors because I forgot to add on my page a thing that I always add on all my pages:
// check for errors
require_once('check_all_errors.php');
You encode the data twice, one manually and once by supplying them to a prepared statement. Just encode it once, like:
$stmt = $mysqli->prepare('UPDATE table SET Password=?');
$stmt->bind_param('s', $_POST['password']);
By the way, unless you truly want to write MySQL-specific code, there's no reason to use mysqli anymore. The PDO module supports multiple databases out of the box, with a similar interface.

PDO not returning results from SELECT on more than 1 column

The server is running PHP 5.2.8. PDO has mysql 5.1.30 drivers installed.
Alright, so I am trying to figure out some PDO ( and this is just killing me. When I run the code below, I get the expected results, no problem.
However, whenever I try to add more than one column (or *) to the SELECT, there is no reply from the query - no results whatsoever. I have tried everything - I know it must be something simple. Any suggestions as to why more than one column fails to return any rows?
$hostname = "localhost";
$dbname = "dbname";
$username = "username";
$password = "password";
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
/*** echo a message saying we have connected ***/
echo 'Connected to database<br />';
/*** The SQL SELECT statement ***/
$sql = "SELECT LastName FROM staff";
foreach ($dbh->query($sql) as $row) {
echo $row['LastName'] . '<br />';
}
/*** close the database connection ***/
$dbh = null;
} catch(PDOException $e) {
echo $e->getMessage();
}
Again, if I try to add columns in the statement stored in $sql to anything other than a single column, I get bupkis. For example:
SELECT FirstName, LastName FROM staff
returns zero results. Both columns exist - if requested separately, they return expected results. When combined, the query takes quite some time, then returns nothing.
No exception is caught by the catch block.
I think you have a number of issues here, mostly in your code that handles reading the values returned by the query. I have taken the liberty of changing a few things and rewriting this to use prepare statements, which is a function that PDO provides that you should take advantage of.
On prepare statements:
Why use them: http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html
PHP PDO doc: http://php.net/manual/en/pdo.prepare.php
Here is the core code:
try {
//open database
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
//define sql query
$sql = "SELECT LastName FROM staff";
//prepare the query for execution
$qresult = $dbh->prepare($sql);
//insert code below to handle parameters to the sql query here
//execute the query
$qresult->execute();
//fetch the results
foreach ($qresult->fetch(PDO::FETCH_ASSOC) as $row)
{
echo $row['LastName'] . '<br />';
}
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
$qresult = null; //close the result set
$dbh = null; //close the database
Note, that I have replaced the call to query() with a couple of lines that call prepare() then execute(). You can then easily insert the following lines in between the prepare() and execute() calls to handle passing parameterized queries. This will help reduce chances of sql injection.
I have also changed the way you are accessing the retirned valued by specifying that I want them returned as and associative array, PDO::FETCH_ASSOC. This will get you a result set that you can iterate through like you would have using the old mysql interfaces.
If your query was a parameterized query like:
$sql="SELECT LastName FROM staff WHERE LastName=':lastname'";
where :lastname is the parameter.
Here is the code you would insert at the comment to handle this, (this code will handle multiple parameters. Simply add additional elements to the $param array):
//bind parameters to the prepared statement
$param = array(':lastname'=>'Jones');
foreach ($param as $key => $value) {
$qresult->bindValue($key,$value);
}
Make sure you separate the columns in the SELECT with a comma (space on either side of the comma is okay, but not required). If you want to select all columns, have only a * with no other characters.

Inserting records into MySQL DB

Im using the follow script to insert records into my DB:
$sql = "INSERT INTO fotetweets VALUES('$tweetid','$dp', '', '$username','$tag', '$twittercontent', '$twittertimestamp', '')";
mysql_query($sql);
However what if $twittercontent contains the ' char, I think it will fail. Correct?
If so how can I deal with it correctly?
You will want to look into mysql_real_escape_string. However, I would look into using the mysqli or PDO class instead and utilize prepared statements.
EDIT
Note, these can all be found / were pretty much taken from the PHP Manual under examples for prepared statements.
Example Usage for MySQLi:
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "my_database");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* create a prepared statement */
$stmt = $mysqli->stmt_init();
if ($stmt->prepare("INSERT INTO fotetweets VALUES(?, ?, '', ?, ?, ?, ?, '')")) {
/* bind parameters for markers */
$stmt->bind_param("issssi", $tweetid, $dp, $username, $tag, $twittercontent, $twittertimestamp);
/* execute query */
$stmt->execute();
/* close statement */
$stmt->close();
}
?>
Example Usage PDO:
<?php
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$sth = $dbh->prepare('INSERT INTO fotetweets VALUES(?, ?, '', ?, ?, ?, ?, '')');
$sth->execute(array($tweetid, $dp, $username, $tag, $twittercontent, $twittertimestamp));
?>
Example of mysql_real_escape_string usage:
$tweetid = (int) $tweetid; // static cast to integer, if that is what it should be.
$sql = "INSERT INTO fotetweets VALUES(
$tweetid,'" . mysql_real_escape_string($dp) . "',
'', '" . mysql_real_escape_string($username) . "',
'" . mysql_real_escape_string($tag) . "',
'" . mysql_real_escape_string($twittercontent) . "',
'" . mysql_real_escape_string($twittertimestamp) . "', '')";
You can find more information and extra usage examples at the manual pages listed above. Given I do know what $dp is I cannot tailor this exactly.
SIDE NOTE
This is all the assumption I am willing to make. The OP could be getting the data from POST and/or in an array form, or he could be getting it from a different means. Either or, given the example the OP posted, this is as accurate as I could be to tailor to the OP. If you have an issue or think it could be better explained / shown, well go ahead and add another answer which addresses it and not just another complaining comment remark about how no one does anything right when you are not willing to pony up the "correct" answer yourself.
And of course if it is an array, this changes a lot of items and the OP should clear that up and not just random people making "guesses" as to where and how the data is being retrieved.
Correct. Not only it will fail but it will also leave you open to SQL Injection attacks.
To avoid these problems, you can use:
mysql_real_escape_string()
PDO and Prepared Statements
Remember, user input should always be sanitized.
Just before you run this query, use this:
$twittercontent = mysql_real_escape_string($twittercontent);
yes it would fail as it would prematurely terminate the string. To fix this use
mysql_real_escape_string($twittercontent) in place of $twittercontent
Make your life simpler:
//$pdo = new PDO("mysql:host=localhost;dbname=testdb", user, pass);
$pdo->prepare("INSERT INTO fotetweets VALUES (?,?,?,?,?,?,?,?)")
->execute( array($tweetid, $dp, '', $username, $tag, $twittercontent, $twittertimestamp, '') );
This sends the data correctly to the database, without security issues. Use it as template for all queries. (Note that you still have to apply htmlspecialchars() when outputting your database content again later...)
That's why you should use mysql_real_escape_string() function first
http://www.php.net/manual/en/function.mysql-real-escape-string.php
It is important, that you always escape (or in general sanitize) variables you interpolate into your queries that come from untrusted sources (i.e. not from you ;) ). Topic for you to Google for read about: 'SQL injection'
You can also use addslashes(). mysql_real_escape_string() is better though. I agree with using PDO.
As it was mentioned before me you can use mysql_real_escape_string
OR
if you use PDO you can also use binding and the you do not have to worry about escaping.
$stmt = $db->prepare("INSERT INTO fotetweets VALUES(:tweetid,:dp, '', :username,:tag, :twittercontent, :twittertimestamp, '')");
$stmt->bindParam(':tweetid', $tweetid);
$stmt->bindParam(':dp', $dp);
$stmt->bindParam(':username', $username);
$stmt->bindParam(':tag', $tag);
$stmt->bindParam(':twittercontent', $twittercontent);
$stmt->bindParam(':twittertimestamp', $twittertimestamp);
$stmt->execute();
As it was mentioned above, you have to use mysql_real_escape_string()
note that you have to use this function not for the $twittercontent variable only,
but for the every field in the query
and not only for inserting and not only for this table.
and from "untrusted input".
But literally every variable you are going to put into query in quotes, should be processed with this function. No exceptions or conditions.
Note if you don't put variable in quotes in the query, this function become useless
Another way, already mentioned too, is to change entire database driver.
Unfortunately, noone bring a useful example of real life usage, which could be extremely useful.

Categories