Can't write data in database $count != 1 - php

I am currently working on a project but can't continue due a error that keeps on coming and I don't know why but perhaps you guys would know. When I fill in my form and want to insert my data in the database I get the error feedback account creation failed. Which is below.
so here is the code:
// write new users data into database
$sql = "INSERT INTO users (user_name, user_password_hash, user_email, user_creation_timestamp, user_activation_hash, user_provider_type, user_persnaam, user_bondsnummer, user_telefoonnummer, user_leeftijd, user_enkelsterkte, user_dubbelsterkte, user_geslacht)
VALUES (:user_name, :user_password_hash, :user_email, :user_creation_timestamp, :user_activation_hash, :user_provider_type, :user_persnaam, :user_bondsnummer, :user_telefoonnummer, :user_leeftijd, :user_dubbelsterkte, :user_enkelsterkte, :user_geslacht)";
$query = $this->db->prepare($sql);
$query->execute(array(':user_name' => $user_name,
':user_password_hash' => $user_password_hash,
':user_email' => $user_email,
':user_persnaam' => $user_persnaam,
':user_bondsnummer' => $user_bondsnummer,
":user_telefoonnummer" => $user_telefoonnummer,
":user_enkelsterkte" => $user_enkelsterkte,
":user_dubbelsterkte" => $user_dubbelsterkte,
":user_leeftijd" => $user_leeftijd,
':user_geslacht' => $user_geslacht,
':user_creation_timestamp' => $user_creation_timestamp,
':user_activation_hash' => $user_activation_hash,
':user_provider_type' => 'DEFAULT'));
$count = $query->rowCount();
if ($count != 1) {
$_SESSION["feedback_negative"][] = FEEDBACK_ACCOUNT_CREATION_FAILED;
return false;
}
the problem seems to be that I can't write anything into my database but I am sure that I can connect and update everything but not write. So the problem isn't with the connection to the database. I think it has something to do with the rowcount but maybe you guys know what's wrong. The double quotes aren't the problem I've checked that already.
Thanks in advance

I don't know if this will be helpful, #fred gave you a few clue, and you said you are sure the connection is good. Here is what I caught:
INSERT INTO users
(user_name,
user_password_hash,
user_email,
user_creation_timestamp,
user_activation_hash,
user_provider_type,
user_persnaam,
user_bondsnummer,
user_telefoonnummer,
user_leeftijd,
user_enkelsterkte, /* here user_enkelsterkte is first */
user_dubbelsterkte, /* here user_dubbelsterkte is second */
user_geslacht)
VALUES (:user_name,
:user_password_hash,
:user_email,
:user_creation_timestamp,
:user_activation_hash,
:user_provider_type,
:user_persnaam,
:user_bondsnummer,
:user_telefoonnummer,
:user_leeftijd,
:user_dubbelsterkte, /* here user_dubbelsterkte is first */
:user_enkelsterkte, /* here user_enkelsterkte is second */
:user_geslacht)
If there is a column type or length mismatch it will fail.
Here is a better way to write your code would be:
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($query = $this->db->prepare($sql)) {
// put code here
}else{
echo "\nPDO::errorInfo():\n";
print_r($this->db->errorInfo());
}
You can do error checking on connection, prepare() or execute().
Now you should find out if you get an error.

Related

Different hash comes out with fn_md5

so i have a very weird issue that its been quite sometime now and am still figuring out why it is is. i have a function in sql server called fn_md5 that accepts 2 parameters and then return it as a varbinary.
but if the function is called via a the php script in my web, the hash is different when you directly call it from the ssms, and all of my ideas are out anymore. all i know is that the fn_md5 function when called directly in the ssms outputs the correct hash that i want it to be.
soo this is my fn_md5 function:
USE [master]
GO
/****** Object: UserDefinedFunction [dbo].[UFN_MD5_ENCODEVALUE] Script Date: 5/17/2022 4:41:16 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- ЗФјцён : UFN_MD5_ENCODEVALUE()
-- і»їл : ЖЇБ¤№®АЪї­°ъ АОµ¦Ѕєё¦ АМїлЗПї© MD5 °ЄА» »эјє
ALTER FUNCTION [dbo].[fn_md5]
(
#btInStr VARCHAR(10),
#btInStrIndex VARCHAR(10)
)
RETURNS VARBINARY(16)
AS
BEGIN
DECLARE #btOutVal VARBINARY(16)
EXEC master..XP_MD5_EncodeKeyVal #btInStr, #btInStrIndex, #btOutVal OUT
RETURN #btOutVal
END
and this is my php script:
$xodbc_connect = odbc_connect('Driver={ODBC Driver 17 for SQL Server};SERVER=WIN-6QBM0ALD4G1\SQLEXPRESS', 'sa', 'superpasszz');
$statement = "select [dbo].fn_md5('passpass', 'useruser')";
$exec = odbc_exec($xodbc_connect, $statement);
$result = odbc_result($exec, 1);
$password = $result;
//var_dump($password);
# insert data
$data = array(
'username' => $username,
'password' => $password,
'name' => $username,
'serial' => $this->_defaultAccountSerial,
'email' => $email
);
# query
$query = "INSERT INTO "._TBL_MI_." ("._CLMN_USERNM_.", "._CLMN_PASSWD_.", "._CLMN_MEMBNAME_.", "._CLMN_SNONUMBER_.", "._CLMN_EMAIL_.", "._CLMN_BLOCCODE_.", "._CLMN_CTLCODE_.") VALUES (:username, :password, :name, :serial, :email, 0, 0)";
now if i do this script in the ssms:
select [dbo].fn_md5('passpass', 'useruser');
it will give me this, which should be the correct hash:
0x0634DF7B99E2CF2344C3362F8CB76729
but if i use the registration process via my web it will give me this instead:
0xE5E892FA86C13BB1DF93630458E7DC31
the more weirder is that i cannot see what is wrongg and my head is going to blow. am still constantly learning both languages please bare with me and i hope you can help me out :<

can't insert data in php poo

i'veen following a tutorial about oop php and I was doing the C of the crud, where I have a user with its attributes. When i'm doing the insert into the bd it just save () or {()}, in the example the person uses
`
public function save(){
$sql = "INSERT INTO usuarios (nombre, apellidos, email, password,rol,) VALUES('{$this->getNombre()}',
'{$this->getApellidos()}','{ $this->getEmail()}','{$this->getPassword()}','user')";
$save = $this->db->query($sql);
$result=false;
if($save){
$result=true;
}
return $result;
}
`
But when I use it, I get only save {()} on the db. I tried erasing the {} from the getters, and saving the attributes in new variables and writting it in the query but I can't make it works.
Here it's my db
And the error I get
Thank you for your answers :)
To avoid sql injection you should use prepared statements. These come with PDO and are pretty simple to use. Have a look at the following example.
$sql = "
INSERT INTO
usuarios
(nombre, apellidos, email, password,role)
VALUES
(:nombre, :apellidos, :email, 'user')
";
$stmt = $this->db->prepare($sql);
$result = $stmt->execute([
'nombre' => $this->getNombre(),
'apellidos' => $this->getApellidos(),
'email' => $this->getEmail()
]);
return $result;
Further more you can wrap the execution of your sql query via PDO in a try/catch block. So if any exception occurs, you can catch it and see, what exactly went wrong.
try {
// execute your logic here
} catch (PDOException $e) {
var_dump($e, $this->db->errorInfo());
}
Hope this helps.
Beside that your SQL Syntax got an error. The last comma after rol. Further the error message says, that an entry () for the key uq_email already exists. This kind of exeptions you can catch with the above shown try/catch block.

Insert a lot of record using single arguments and using bindParam

I have some method to insert some data into a database like this:
public function register($username, $email, $hashedPassword, $activationCode)
{
try {
$conn = Database::getConnection();
// Connect and create the PDO object
$conn->exec('SET CHARACTER SET utf8'); // Sets encoding UTF-8
// Define and prepare an INSERT statement
$sql = 'INSERT INTO users (username, email, pass, reset_token, dateAdded )
VALUES (:username, :pass, :email, :token, now())';
$sqlprep = $conn->prepare($sql);
// Adds value with bindParam
$sqlprep->bindParam(':username', $username, PDO::PARAM_STR);
$sqlprep->bindParam(':email', $email, PDO::PARAM_STR);
$sqlprep->bindParam(':pass', $hashedPassword);
$sqlprep->bindParam(':token', $activationCode);
// If the query is successfully executed, output the value of the last insert id
if ($sqlprep->execute()) {
//echo 'Succesfully added the row with id='. $conn->lastInsertId();
$this->result = true;
}
$conn = null; // Disconnect
} catch (PDOException $e) {
include('../views/error.php');
include('../views/admin/includes/footer.php');
exit();
}
}
The problem is I think it's not a good method if I have so many arguments for my function to enter into a database. So is it any good way I can enter a lot of fields just by using 1 parameter but still using bindParam? Since I see a lot of examples is only using prepare without bindParam. I think I can use an array, but I don't know the proper way to do it. So I need some help how I can do it.
since you want keep your bindparam i suggest you use input like this:
$input = array('username' => $username, 'activationHash' => $activationHash);
and in your bindParam add a code like this:
public function register($input){
//code
$sqlprep->bindParam(':username', $input['username'], PDO::PARAM_STR);
//other
}
hope this will solve your problem
https://stackoverflow.com/a/10060755/1747411
Check second example, you have to repeat values with binds
e.g
VALUES (:username1, :pass1, :email1, :token1, now()), (:username2, :pass2, :email2, :token2, now())
and bindParam with loop
You can insert the params as an array into $sqlprep->execute($param_array)
Or, simply passing each param into an array inside execute, like this: $sqlprep->execute(array($param1, $param2))
Update:
Pass values into $input as an array:
$input = array('username' => $username, 'activationHash' => $activationHash); //and so on
Now on the model side,
You can bind these values to params using foreach loop like this:
foreach ($values as $key => $value) {
$sqlprep->bindParam(':' . $key, $value , PDO::PARAM_STR);
}

PDO insert into MySQL Database not working with another PDO query

(I have no idea whether the title is descriptive or not. I'm not sure where the problem is, so it's kind of difficult to come up with a good title.)
So here's the thing. I'd like to insert values (from an HTML form) into a MySQL database using PDO.
So far so good. I managed to get the $_POST['xyz'] values and successfully inserted them into the DB. But now I'd like to make sure that there's only one row with the same email address ($email) and same question id ($qid). I did that by checking to row count, as you can see in the code. Not sure if that's a good way to do it or not.
Now I can successfully NOT insert two rows with similar email addresses, but for some reason I cannot insert any rows with any other email address. Been trying to figure out what I am doing wrong, but can't. So here's the code. Hope you can see what I did there (because I can't).
try {
$cnnxn = new PDO("mysql:host=$db_host;dbname=$db_name", $db_username, $db_password);
} catch (PDOException $e2) {
die("ERROR: " . $e2->getMessage());
}
$query2 = $cnnxn->prepare("SELECT count(*) as cnt FROM grdj_replies WHERE email = :email AND question_id = :qid");
$query2->bindParam(':email', $email);
$query2->bindParam(':qid', $qid);
$isQueryOk = $query2->execute();
if ($isQueryOk) {
$count = $query2->fetchColumn();
} else {
trigger_error('Error executing statement.');
}
$query2->closeCursor();
if ($count > 0){
echo '<div class="tools-alert tools-alert-red"><p>Sähköpostiosoitteellasi <strong>'.$email.'</strong> löytyy jo tallennettu vastaus tähän tehtävään. Jos haluat muuttaa vastausta, seuraa sähköpostiosoitteeseesi lähetetyn viestin ohjeita.<p>';
echo '<p>(Klikkaa tästä, jos haluat lähettää ohjeet uudestaan osoitteeseen '.$email.'.)</p></div>';
}
else {
$cnnxn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTIONS);
$cnnxn->exec("SET NAMES utf8");
$query = $cnnxn->prepare("INSERT INTO grdj_replies (question_id, last_name, first_name, email, question_number, answer, status, accesstoken) VALUES (:qid, :lastname, :firstname, :email, :questionnumber, :answer, :status, :accesstoken)");
$query->bindParam(':qid', $qid);
$query->bindParam(':lastname', $last_name);
$query->bindParam(':firstname', $first_name);
$query->bindParam(':email', $email);
$query->bindParam(':questionnumber', $question_number);
$query->bindParam(':answer', $answer);
$query->bindParam(':status', $status);
$query->bindParam(':accesstoken', $accesstoken);
$query->execute();
if ($query !== false)
{
print "<div class=\"tools-alert tools-alert-green\">Vastauksesi on tallennettu!</div>";
}
$query->closeCursor();
$cnnxn = null;
}
Firstly, you are using ->bindParam() where ->bindValue() would be adequate (perhaps, more appropriate).
You ask whether your input processing is a good way to do things: I can't see that code. Rather than using superglobals, use filter_input() / filter_input_array()
The problem you describe might not be in the PHP code: take a closer look at the database indexing. Have you uniquely indexed grdj_replies by qid (e.g. do you have a primary key on "qid" alone)? Are there any other inadequate indexes which are blocking you from inserting additional rows into the table, for the same qid? Perhaps you should uniquely index jointly by qid, email.
You apply error handling to the creation of the PDO object (database connection); in cases like these, I often find it helpful to apply error handling (try/catch, $error->getMessage()) to the execution of the SQL statement (this way, you get to see what the database is trying to tell you. Has it thrown an excuse/explanation for not running the query?)
I suggest you to use a MySQL unique index :
ALTER TABLE `grdj_replies`
ADD UNIQUE INDEX `UNIQUE_IDX` (`email`, `question_id`);
Now MySQL will make sure there's no other row with the same email and question_id before inserting a new row, you don't have to check it "manually".
In the case there is already the same data, the INSERT request would fail.

Newbie Question: PDO and MYSQL INSERT Query problem

I'm attempting to be more secure and start using PDO and prepared statements. This had been recommended to me and I've read up on these two websites:
http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
and
http://webdevrefinery.com/forums/topic/1272-your-mysql-code-sucks
I've hit a brick wall and I can't understand why the following doesn't work. I am trying to insert a row (to log a 404 error). I have read up about named and unnamed placeholders and I think the named placeholder method will be easier to maintain. I've also tried using "try" and "catch" for the first time. All of this is completely new to me, so please be kind! I don't get any errors but the code doesn't update the database- I get zero rows returned.
Here is the code:
$referer = $_SERVER['HTTP_REFERER'];
$domainName = "http://domain.com";
$_dtNow = date("d-m-Y H:i:s");
$_referer = $domainName.$_SERVER['REQUEST_URI'];
$_thisPage = $domainName.$url;
$_ip = $_SERVER['REMOTE_ADDR'];
$_host = $_SERVER['REMOTE_HOST'];
if(isset($_SERVER['HTTP_USER_AGENT'])) {$_ua = $_SERVER['HTTP_USER_AGENT'];} else {$_ua = "unset";}
$host = 'localhost';
$port = 3306; // This is the default port for MySQL
$database = 'databaseName';
$username = 'username';
$password = 'password';
// Construct the DSN, or "Data Source Name". Really, it's just a fancy name
// for a string that says what type of server we're connecting to, and how
// to connect to it. As long as the above is filled out, this line is all
// you need :)
$dsn = "mysql:host=$host;port=$port;dbname=$database";
try {
// Connect!
$db = new PDO($dsn, $username, $password);
$data = array(
'dateTime' => $_dtNow,
'referer' => $_referer,
'page' => $_thisPage,
'ip' => $_ip,
'host' => $_host,
'ua' => $_ua
);
$statement = $db->prepare("INSERT INTO 404s (dateTime, referer, page, ip, host, ua) value (:dateTime, :referer, :page, :ip, :host, :ua)");
$statement->execute($data);
}
catch(PDOException $e) {
echo $e->getMessage();
}
?>
Are you sure of the table name is 404s it sound like an incorrect identifier.
INSERT INTO 404s (dateTime, referer, page, ip, host, ua) value (:dateTime, :referer, :page, :ip, :host, :ua)
Try :
INSERT INTO `404s` (dateTime, referer, page, ip, host, ua) value (:dateTime, :referer, :page, :ip, :host, :ua)
Use backquote around `404s`
Note
Keep in mind that construct such as :
create table `404` ( `33` integer);
Are valid .
When you build complex request use of ` is very useful to avoid some kind of painful SQL errors especially when you format request from an introspection algorithm.
Like table, columns and database have to be protected.
In addition to #Dave Kiss, the SQL statement has a small typo at 'value'. It should be 'VALUES'.
INSERT INTO 404s (dateTime, referer, page, ip, host, ua) VALUES (:dateTime, :referer, :page, :ip, :host, :ua)
Maybe that is all.
BTW: Using leading numbers in identifiers (like your table name 404s) is bad style. You may use them, but you have to but the table name in backticks:
INSERT INTO `404s` (dateTime, referer, page, ip, host, ua) VALUES (:dateTime, :referer, :page, :ip, :host, :ua)
Resources:
http://dev.mysql.com/doc/refman/5.6/en/insert.html
http://dev.mysql.com/doc/refman/5.6/en/identifiers.html
Try adding the colons to your keys in the data array.
/* Execute a prepared statement by passing an array of insert values */
$data = array(
':dateTime' => $_dtNow,
':referer' => $_referer,
':page' => $_thisPage,
':ip' => $_ip,
':host' => $_host,
':ua' => $_ua
);
$statement = $db->prepare("INSERT INTO 404s (dateTime, referer, page, ip, host, ua) value (:dateTime, :referer, :page, :ip, :host, :ua)");
$statement->execute($data);

Categories