mysql query works sometimes but not always - php

I'm building a simple "little" movie cataloging database system for my own use. The problem right now is that I've got a mySQL query that works MOST of the time but not all. Basically it works by using a 3rd party IMDB API. I use that to search and pull the values I need which works just fine. It displays on my preview screen and everything. The problem I'm running into that that while most movies work, a few do not and I can't figure out the reason.
For example, The Fellowship of the Ring stores just fine while The Return of the King simply won't pass the query. I can't find any differences.
Here's my query:
$query = "INSERT INTO movies
(title, year, releaseDate, actors, image, runtime, genre, director, rating, watchedDate, category, series, comments, owned, ownedFormat, seen, plot, favorite, uploadDate)
VALUES ('$title', '$year', '$releaseDate', '$actors', '$newImg', '$runtime', '$genre', '$director', '$rating', '$watchedDate', '$category', '$series', '$comments', '$owned', '$ownedFormat', '$seen', '$plot', '$favorite', '$curDate')";
mysql_query($query) or die ('Error');
I'm not sure what else I need to provide. It seems like some kind of difference in the movies is causing the error but I don't know.
Thanks!
** EDIT ***
So I tried switching over to mysqli. Here's my new code:
/* Create the prepared statement */
if ($stmt = $mysqli->prepare("INSERT INTO movies (title, year, releaseDate, actors, image, runtime, genre, director, rating, watchedDate, category, series, comments, owned, ownedFormat, seen, plot, favorite, uploadDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
/* Bind our params */
$stmt->bind_param('sssssssssssssssssis', $title, $year, $releaseDate, $actors, $newImg, $runtime, $genre, $director, $rating, $watchedDate, $category, $series, $comments, $owned, $ownedFormat, $seen, $plot, $favorite, $curDate);
/* Execute the prepared Statement */
$stmt->execute();
/* Echo results */
echo "Inserted {$title} into database\n";
}
However, now i'm getting an error that reads:
Fatal error: Call to a member function prepare() on a non-object on the line where the if statement starts.
I'm assuming this is because something my query isn't an object?
Thanks

The most likely reason for this is that you are putting the raw values between single quotes. If one of the values has a single quote in it, then you will get a syntax error.
A better way to do what you want is by binding parameters. You can read more about that here.

Without more information about the actually returned value it is hard to say. It is possible that the returned value contains a character that breaks your code such as a semicolon or quote. Try stripping all non alphanumeric characters away using regex.
$result = preg_replace("/[^a-zA-Z0-9]+/", "", $s);
And you have a sql injection vulnerablility. Consider using PDO instead of the depreciacted mysql functions.
http://php.net/manual/en/book.pdo.php

Related

mysqli prepared statement with ADDTIME CURTIME fails

There are so many questions on SO for failed prepared statements, but I cannot find one which solves my exact problem (or explains it, atleast).
I'm trying to give my users a login-token which is valid for 5 minutes.
When I execute the query through PHPMyAdmin it works just fine:
WORKING QUERY
INSERT INTO LOGGEDIN (userID, loggedInToken, loggedInRefresh) VALUES
(1, "HJKFSJKFDSKLJFLS", ADDTIME(CURTIME(), '00:05:00'));
However, when trying to execute the query through PHP using a prepared statement it fails.
$stmt = $this->conn->prepare("INSERT INTO LOGGEDIN VALUES (userID, loggedInToken, loggedInRefresh) VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))");
$stmt->bind_param("is", $userID, $token);
I get the error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))' at line 1
It is the exact same query so I think it's due to how the prepare handles the query.
I've also tried entering the '00:05:00' as a variable because I thought the ' was causing the error but it fails as well.
$five_minutes = '00:05:00';
$stmt->bind_param("iss", $userID, $token, $five_minutes);
When I remove the prepare and use the following query:
$query = "INSERT INTO LOGGEDIN VALUES (userID, loggedInToken, loggedInRefresh) VALUES (" . $userID . ", '" . $token . "', ADDTIME(CURTIME(), '00:05:00'))";
if ($result = $mysqli->query($query)) {
...
It works fine but I would like to keep my code consistent and use a prepared statement everywhere I can.
How can I let this query execute properly using a prepared statement? If all else fails I think I could create the timestamp in PHP and pass it through to the database thus bypassing the whole ADDTIME calculation, but I would like to know what is causing the problem in the first place.
Problems need to be understood, not dodged.
You have a superfluous VALUES on your query:
$stmt = $this->conn->prepare("INSERT INTO LOGGEDIN VALUES (userID, loggedInToken, loggedInRefresh) VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))");
^^
Remove that:
$stmt = $this->conn->prepare("INSERT INTO LOGGEDIN (userID, loggedInToken, loggedInRefresh) VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))");

If I use $_POST value directly in bindParam (mysqli) will there be a security issue?

I have been reading about using $_POST values being used directly in isert statements and understand that this is an invitation for trouble. What is not clear in any of the posts I read was -
Say my form is sending 7 items to my mysqli insertion script and I use the posted values like this:
$stmt = $mysqli->prepare("INSERT INTO `advertisements` (`from`, `r_u_res`, `email`, `blockname`, `floorno`, `doorno`, `content`) VALUES (?, ?, ?, ?, ?,?,?)");
$stmt->bind_param('sssssss', $_POST['from'], $_POST['rures'], $_POST['email'], $_POST['blockname'], $_POST['floorno'], $_POST['doorno'], $_POST['content']);
$stmt->execute();
$stmt->close();
Would that be the correct way to do it? Or should I first store the posted values in a new variable and use that variable while binding? - like this :
$postedfrom = $_POST['from'];
$postedrures = $_POST['rures'];
$postedemail = $_POST['email'];
$postedblockname = $_POST['blockname'];
$postedfloorno = $_POST['floorno'];
$posteddoorno = $_POST['doorno'];
$postedcontent = $_POST['content'];
$stmt = $mysqli->prepare("INSERT INTO `advertisements` (`from`, `r_u_res`, `email`, `blockname`, `floorno`, `doorno`, `content`) VALUES (?, ?, ?, ?, ?,?,?)");
$stmt->bind_param('sssssss', $postedfrom, $postedrures, $postedemail, $postedblockname, $postedfloorno, $posteddoorno, $postedcontent);
$stmt->execute();
$stmt->close();
I saw a post OO mysqli prepared statements help please where the answer does seem to be like the code above but I want to know whether doing it like the first code poses security issues...
both forms are equivalent from a security perspective as php first resolves the values to be passed in the method call to $stmt->bind_param, thus that function sees the exact same values in both cases.
ps: both snippets look ok to me.

properly sanitize multiple user inputs with mysqli

Im currently using mysqli, and I want a way to properly sanitize every single user input. Im looking for the most simple lightweight way to do this, as I understand that Im NOT supposed to use mysql_real_escape....
my query is like so
$stmt = $sql->prepare("INSERT INTO Persons (msg, ip, time, main, twit, city, lat, lon, lang)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
as i understand i'm supposed to use the function bindParam... If i use it like so, am i completley securing my user inputs?
$stmt->bind_param('sssssssss', $_POST[msg], ('$ip'), ('$date'), '$_POST[main]', '$_POST[twit]', ('$cit'), ('$lat'), ('$lon'), '$_POST[lang]');
$stmt->execute();
$stmt->close();
If this isn't securing my user inputs how do i properly do so?
You need to prepare the statement to be safe. Something like below (its probably not 100% but gives you an idea)
$sql = new mysqli("localhost", "my_user", "my_password", "world");
$stmt = $sql->prepare("INSERT INTO Persons (msg, ip, time, main, twit, city, lat, lon, lang)
VALUES
(?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->bind_param("sssssssss",$_POST[msg], $ip, $date, $_POST[main], $_POST[twit], $cit, $lat, $lon, $_POST[lang]);
$stmt->execute();
First of all you have to follow basic PHP syntax
'$_POST[msg]' would be inserted as a literal $_POST[msg] string, while you expecting a value for $_POST['msg'] variable.

Call to member function bind_param on non_object

Ok, before I get started I just want to say that I've read every answer on this site pertaining to this issue, and I still can't get it right. I know PHP is throwing this error because the prepare statement is not returning an object. I just have no idea why. Here's my code:
$stmt = $this->db->prepare("INSERT INTO locations (type, time, street, city, state, country, age, admission, rsvp_limit, keyword1, keyword2, keyword3, description, latitude, longitude, date_posted, member_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, now(), '1')");
var_dump($stmt);
if (!$stmt->bind_param("sssssssiissssdd", $type, $date, $street, $city, $state, $country, $age, $admission, $rsvp, $keyword1, $keyword2, $keyword3, $description, $latitude, $longitude)) {
throw new ErrorException($stmt->error, $stmt->errno);
}
$stmt->execute();
$stmt->close();
Here's the values being echoed that are sent to this statement:
TYPE: Party DATE: 1969-12-31 19:12:00 STREET: 50 Barret Parkway CITY: Marietta STATE: Georgia COUNTRY: United States AGE: 25+ ADMISSION: 20 RSVP: 1000 KEYWORD1: key1test KEYWORD2: key2test KEYWORD3: key3test DESCRIPTION: Description test LATITUDE: 33.950500 LONGITUDE: -84.535900
Now keep in mind, the previous string is just an echo string so the all caps words are not actually being sent to the db, just the statements after the colons. I've 20-drupled check the database and all the spellings are correct to the rows in the db all with adequate space and the correct types.
I've been staring at this problem for the past 5 hours while taking breaks to scour the internet for an answer and I draw blanks. Anybody know what's up. If it's any consolation I can add fields in to the database manually by hand and retrieve them with a $_GET variable just fine.

Prepared statement mysqli

I'm getting obsessed. I'm working for the first time with prepared statement and I am sure I have read somewhere that you could prepare a statement like:
$stmt = $db->prepare("INSERT INTO {$table} (:var1, :var2) VALUES (:val1, :val2)");
$stmt->bind_param(':var1', $var1);
$stmt->bind_param(':var2', $var2);
$stmt->bind_param(':val1', $val1);
$stmt->bind_param(':val2', $val2);
$stmt->execute();
Or something like that. I remember that I have read that you could call the vars with a specific name with ':' as prefix. But I really can't find an example of that. I read the php manual and I couldn't find any sample of this thing.
Is it right or have I dreamed it?
Faq
If you are wondering why I can't use simply the '?' method:
$stmt = $db->prepare("INSERT INTO {$table} (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)");
this gets hard to write.
You can't do :var1,:var2,:varX in both the column names list and the VALUES list for one thing. Secondly, PDO accepts named parameter binding.
See PHP Data Objects and examples in PDO::prepare.

Categories