Inserting data into database with pdo prepared statment - php

Inserting data into database with pdo prepared statment, doesnt work for me:
I use this function:
public function get_number_of_matches(){
$stmt = $this->pdo->prepare("INSERT INTO `words`( `word_name`, `word_count`, `search_id`) VALUES (:word, :count,:searchID)");
$stmt->bindParam(':word', $word);
$stmt->bindParam(':count', $count);
$stmt->bindParam(':searchID', $search_id);
for($i=0;$i<count($this->words);$i++){
if(preg_match_all('/'.$this->words[$i].'/i', $this->text,$matches)){
$count=count($matches[0]);
$word=$this->words[$i];
$search_id=1;
$stmt->execute();
break;
}
}
return 0;
}
Basically, I try to loop over the values and put them into the database.. no error is given.. nothing goes into the database ..why?
This is how I connect to the database:
class DBConnection {
public static $connect;
public static function connect(){
if(!isset(self::$connect)){
try{
self::$connect=new PDO('mysql:host=localhost;dbname=tweeter', 'root', '');
}catch(Exception $ex){
echo $ex->getMessage();
}
}
return self::$connect;
}
}
UPDATE
Also..see here:
I do the same thing with a different query..but when I try to put object properties inside a variable I get an error:
$tweet= $tweet->tweet ;
$user=$tweet->tweeter_name;
$link= $tweet->link;
Those variables go into a query:
$pdo= DBConnection::connect();
$stmt = $pdo->prepare("INSERT INTO `tweets`( `tweet`, `tweeter_name`, `link`, `date`, `search_id`) VALUES (:tweet, :tweeter_name, :link, :date, :search_id)");
$stmt->bindParam(':tweet', $tweet);
$stmt->bindParam(':tweeter_name', $user);
$stmt->bindParam(':link', $link);
$stmt->bindParam(':date', $date);
$stmt->bindParam(':search_id', $search_id);
I get errors like this:
Notice: Trying to get property of non-object in C:\xampp\htdocs\Twitter\demo.php on line 36
Notice: Trying to get property of non-object in C:\xampp\htdocs\Twitter\demo.php on line 37
Notice: Trying to get property of non-object in C:\xampp\htdocs\Twitter\demo.php on line 38
I can print the properties..but when allocating them to those binded variables..the above errors crop up
I get also this:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'tweeter_name' cannot be null' in C:\xampp\htdocs\Twitter\demo.php:40 Stack trace: #0 C:\xampp\htdocs\Twitter\demo.php(40): PDOStatement->execute() #1 {main} thrown in C:\xampp\htdocs\Twitter\demo.php on line 40
I checked instead like this:
$tweet= "111111"; // $tweet->tweet ;
$user= "22222222"; // $tweet->tweeter_name;
$link= "3333333"; // $tweet->link;
$date= "444444";
and it worked..for some reason it hates those object properties ?!?
This should go as input:
RT #OrganicLiveFood: Scientists Warn #EPA Over #Monsanto's #GMO Crop Failures & Dangers #prop37 #labelGMO #yeson37 http://t.co/2XhuVxO8
Doumastic
TweetCaster for iOS
Mon, 19 Nov 2012 20:40:55 +0000
RT #OrganicLiveFood: Scientists Warn #EPA Over #Monsanto's #GMO Crop Failures & Dangers #prop37 #labelGMO #yeson37 http://t.co/2XhuVxO8
But it doesnt...?!?

Add self::$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); right after connecting.
It would make sure PDO will throw PDOExceptions on every error, making them very easy to see. The error would then outline exactly what's wrong.

Check the return value from $stmt->execute(), if there was a problem it will return false and you should check $stmt->errorInfo() for details.
Or else use the ERRMODE_EXCEPTION that #Madara Uchiha suggests, but if you're not already handling exceptions in your application, this can be hard to adapt to.
Re: your update.
You should check error status from both PDO::prepare() and PDOStatement::execute() every time you call them. The error about "Trying to get property of non-object" likely means that $stmt is actually the boolean value false instead of a valid PDOStatement object. Your call to $stmt->bindParam() fails because false is not an object, so it cannot have a bindParam() method.
In my opinion it's much easier to pass parameters by value instead of binding variables by reference. Here's an example of both error-checking and parameters by value:
$pdo = DBConnection::connect();
$sql = "INSERT INTO `tweets`( `tweet`, `tweeter_name`, `link`, `date`, `search_id`)
VALUES (:tweet, :tweeter_name, :link, :date, :search_id)";
if (($stmt = $pdo->prepare($sql)) === false) {
die(print_r($pdo->errorInfo(), true));
}
$params = array(
':tweet' => $tweet,
':tweeter_name' => $user,
':link' => $link,
':date' => $date,
':search_id' => $search_id
);
if (($status = $stmt->execute($params) === false) {
die(print_r($stmt->errorInfo(), true));
}
The error "Column 'tweeter_name' cannot be null'" that you saw in the exception means that your tweeter_name column is declared NOT NULL, but your $user variable had no value when you bound it to the :tweeter_name parameter.

Related

Trouble converting to parameterized queries

So i'm trying to convert all of my SQL statements to prepared statements etc to prevent SQL injection attacks, but i'm having some issues fetching stuff etc
My code:
if($_GET["action"] == "ban"){
if(isset($_GET["username"])){
$username = $_GET["username"];
$banMsg = $_GET["banMsg"];
$email = "test#gmx.ch";
$sql = "SELECT * FROM bans WHERE username = ?";
$stmt = $db->prepare($sql);
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->fetch();
$stmt->close();
if($result->num_rows > 0){ //LINE 61
die(json_encode(array("status" => 400, "message" => "User already banned")));
}
$result2 = $db->prepare("INSERT INTO bans (username, ip, email, message, expire, ban_creator) VALUES (?, ?, ?, ?, ?, ?)");
$result2->bind_param("sssssd", $username, null, $email, $banMsg, null, 1); // LINE 72^^
$result2->close();
if($result2){
updateBanCache();
die(json_encode(array("status" => 200, "message" => "Successfully banned")));
} else {
die(json_encode(array("status" => 400, "message" => "SQL error")));
}
}
Also $result = $stmt->get_result(); doesn't wanna work for me, i do have mysqlnd driver installed in my php / cpanel though.
Any pointers would be helpful thanks!
ERROR LOG:
[11-Nov-2020 04:46:04 America/New_York] PHP Notice: Trying to get property 'num_rows' of non-object in /home/public_html/index.php on line 61
[11-Nov-2020 04:46:04 America/New_York] PHP Fatal error: Uncaught Error: Cannot pass parameter 3 by reference in /home/elysianmenu/public_html/index.php:72
Stack trace:
#0 {main}
thrown in /home/public_html/index.php on line 72
SIDE NOTE: I also tried using $result = $stmt->get_result(); but I end up with error:
[11-Nov-2020 04:57:30 America/New_York] PHP Fatal error: Uncaught Error: Call to undefined method mysqli_stmt::get_result() in /home/public_html/index.php:55
Stack trace:
#0 {main}
thrown in /home/public_html/index.php on line 55
^^ Yes i do have the mysqlnd driver installed
From the docs: Fetch results from a prepared statement into the bound variables.
fetch() returns either TRUE, FALSE or NULL, but not the result set you expected. Instead, it sets the output to the variables you previously bound (using bind_param()) by reference. This is why you have to use variables, and not actual scalar types.
If your query did not return any rows, fetch() will return NULL. Update your code as follows:
$stmt = $db->prepare($sql);
$stmt->bind_param("s", $username);
$stmt->execute();
if ($stmt->fetch() === TRUE)
die(json_encode(array("status" => 400, "message" => "User already banned")));
$stmt->close();
And to fix the error on line 72, you have to pass the values by reference, using variables. Something like this:
$ip = NULL;
$expire = NULL;
$ban_creator = 1;
$result2->bind_param("sssssd", $username, $ip, $email, $banMsg, $expire, $ban_creator);
Don't forget to execute the query! You're checking $result2 before anything actually happened.
The action of banning a user MUST NOT come from a GET request ($_GET["action"]). This would make it incredibly simple for a webcrawler to stumble upon your banning script and ban all of your users (if it somehow found a list of usernames). The whole payload should be coming in as $_POST. The bottomline is: use $_POST when you are writing data, use $_GET when you are reading data.
You MUST NOT blindly trust the user input. You should be validating the data even before connecting to the db. If the payload is invalid, no resources should be engaged.
When you are only interested in the row count of a result set (and not the values in the result set), write COUNT(1) in your query. This way you can check the lone value to be zero or a non-zero value with no unnecessary overheads. Use something like this https://stackoverflow.com/a/51259779/2943403
ip, expire, and ban_creator should have default settings in your table declaration of NULL, NULL, and 1. You should only mention those columns in an INSERT query if you wish to store a different value. Your INSERT query should only be binding 3 parameters. And of course check the outcome of the executed insert, like this: $stmt->execute() : How to know if db insert was successful?

Cant update this query

Hi can anyone help me on this
$stmt = $conn->prepare("update data set anrede=?, vorname=?, nachname=?, strasse=?, plz=?, ort=?, krankenkasse=?, seit=?, personen=?, telefon=?, termin=?, time=?, vermittler=?, coment=?,feedback=?, Astatus=?, positiv=?, personen_amgaben=?, fr_1=?, fr_2=?, z_fr_2=?, fr_3=?, z_fr_3=?, fr_4=?, z_fr_4=?, fr_5=?, fr_6=? where t_id=?");
$stmt->bind_param('sssssssssssssssssssssssssssi',$anrede, $vorname, $nachname, $strasse, $plz, $ort, $krankenkasse, $seit, $personen, $telefon, $termin, $time, $vermittler, $coment, $feedback, $Astatus, $positiv, $personen_amgaben, $fr_1, $fr_2, $z_fr_2, $fr_3, $z_fr_3, $fr_4, $z_fr_4, $fr_5, $fr_6, $t_id);
I got this error --- Fatal error: Call to a member function bind_param() on a non-object in
what's wrong
The error indicates that $stmt is not an object. This can happen when $conn->prepare() fails. As from the documentation:
mysqli_prepare() returns a statement object or FALSE if an error occurred.
So, you should check whether the return value is false, and then check what the error is, which you can do with the mysqli error method:
Returns the last error message for the most recent MySQLi function call that can succeed or fail.
So your code could look like this:
stmt = $conn->prepare(" ... ");
if (stmt === false) {
die($conn->error);
}
$stmt->bind_param( ... );
Note that in production mode you better not print database error messages to the browser, but in a log file.
From comments it appears that the above code prints:
Unknown column 'positiv' in 'field list'
which is a clear indication of why the statement failed. Your table data apparently has no column that is called positiv. So correct that typo (maybe it is called positive?), and then try again, fixing any other errors that might be reported in this way.

MySQLi Fatal error

I have index.php page and in the title tag I have something like this:
<title><?php echo getBasic('title'); ?></title>
And it's returning the following error:
Fatal error: Call to a member function bind_param() on a non-object in C:\Program Files\WAMP\www\Filmovi\modules\database\dbcon.php on line 12
And in dbcon.php included on the top of the index with require_once('modules/database/dbcon.php') I have this:
function getBasic($type){
global $db;
$sql='SELECT content FROM a853_filmovi WHERE type = ?';
$stmt = $db->prepare($sql);
$stmt->bind_param('s',$type); <-- Line 12
$stmt->execute();
$stmt->bind_result($content);
return $content;
}
On the line number 3 I have this:
$public = getBasic('public');
and it's working perfectly.
By the way, this worked and showed the title properly and then stopped working because of an uknown reason. I don't get it how is it working with getBasic('public') but not with the title. I have a record with the type 'title' in the database so that's not a problem.
Thanks in advance.
Errors like this happen because you are not checking return values before using them.
In this case the error happens because $db->prepare($sql) fails, returns false, and then you use it as if it is a statement (stmt) object.
Check your return values before using them:
$stmt = $db->prepare($sql);
if ($stmt === false) {
die('Preparing SQL string failed');
}
One reason for the error is, prepare() is getting failed -
if the sql statement sent to it is not valid in the current DB.
prepare() will then return false.
Eg - if the table name is not correct or one or more field in the query does not exist.

Fatal error: Call to a member function query() on a non-object in admin.php on line 219

I've searched a lot of basically the same questions on SO which haven't seemed to help. Been a while since i've touched php so i'm guessing there's a simple solution but really can't figure it out.
config.php: (included into admin.php)
$mysqli = new mysqli($mHost, $mUser, $mPass, $db);
admin.php:
$sqlQuery = "INSERT INTO `category` (`id`, `name`) VALUES ('', '$_POST[name]')";
$result = $mysqli->query($sqlQuery);
var_dump($result) returns:
NULL
and gives error:
Fatal error: Call to a member function query() on a non-object in
You are not checking the result of the call to new mysqli. If that fails, then $mysqli will be null and not a valid object you can query against.
Also, by building SQL statements with outside variables, you are leaving yourself open to SQL injection attacks. Also, any input data with single quotes in it, like a name of "O'Malley", will blow up your SQL query. Please learn about using parametrized queries, preferably with the PDO module, to protect your web app. My site http://bobby-tables.com/php has examples to get you started, and this question has many examples in detail.
At the setout, you should call
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
This enables you don't have to check any return values, just put try { ... } catch { ... } blocks.
try {
if (
!isset($_POST['name']) ||
!is_string($_POST['name']) ||
$_POST['name'] === ''
) {
throw new UnexpectedValueException('$_POST[\'name\'] is empty');
}
$mysqli = new mysqli($mHost, $mUser, $mPass, $db);
$stmt = $mysqli->prepare("INSERT INTO `category` (`name`) VALUES (?)");
$stmt->bind_param('s', $_POST['name']);
$stmt->execute();
echo 'Success';
} catch (Exception $e) {
echo $e->getMessage();
}

PHP SQL Prepared Statement: Fatal Error Call To Member Function

I've been trying to get prepared statements working - however, I keep running into the following error
<b>Fatal error</b>: Call to a member function bindParam() on a non-object on line <b>41</b><br />
I have copied exactly many tutorials and even the provided code did not work and threw the same error.
My code is below:
$mysqli = new mysqli(connect, username,pass, datatbase);
$name = 'Tester';
if (mysqli_connect_errno()) {
echo "Can't connect to MySQL Server. Errorcode: %s\n", mysqli_connect_error();
}
$stmt = $mysqli->prepare("INSERT INTO Parks VALUES (null,?,?,?,?,?,?,?,?,?,?,?,?,?,Now(),?,?,?, 0, 0, 0)");
if ($stmt === FALSE) {
die ("Mysql Error: " . $mysqli->error);
}
$stmt->bind_param('ssssssssssssssss', $name, $theme, $size, $mountains, $hills, $river, $lake, $island, $setofislands, $ocean, $waterfalls, $file, $image, $description, $author,$cs);
$stmt->execute();
$stmt->close();
$mysqli->close();
It's the BindParam Line causing the error.
thanks in advance :)
EDIT: Error resolved, however, no data is being inserted into the database.
EDIT: Updated query, database contains VARCHARs except for Description which is LONGTEXT. The final 3 are ints/doubles and there is a current date field.
bindParam is the PDO function. You are using mysqli so try bind_param instead. Where you have 'name' should also be the type definition, so you need 's' for string.
E.g:
$stmt->bind_param('s', $name);
Edit: Although saying that, the error doesn't say the function is incorrect. It says the object doesn't exist... Running this could would give you information as to why the prepare is failing.
$stmt = $mysqli->prepare("INSERT INTO 'Parks' VALUES(null, ?");
if ($stmt === FALSE) {
die ("Mysql Error: " . $mysqli->error);
}
Most likely the prepare is failing as the SQL is incorrect (My guess is the table name 'Parks' should NOT be in qutoes)
Edit 2: My guess for it still not working is:
$stmt->bindParam('name', $name);
Where you have 'name' should actually be the variable type, as in integer, double, string, etc. This is so the database knows what your variable is.
Try replacing that line with:
$stmt->bindParam('s', $name);

Categories