bellow is my code.Error shown is like
fatal error: call to undefined function execute() on line 21,
how could i solve this problem?
<?php
include 'config/dbconfig.php';
include 'lib/function.php';
include 'helper/helper.php';
$db = new rootfunc();
$fm = new formate();
if(!empty($_POST['name']) or !empty($_POST['email']) or !empty($_POST['password1']) or !empty($_POST['dob']) or !empty($_POST['gender']) ){
$name = $fm->validation($_POST['name']);
$email = $fm->validation($_POST['email']);
$password = $fm->validation($_POST['password1']);
$dob = $_POST['dob'];
$gender = $fm->validation($_POST['gender']);
$query = $pdo->prepare("SELECT * FROM user_table WHERE name = ? AND email = ?");
$query = execute(array($name,$email));
$numRow = $query->rowCount();
if(!$numRow){
$query = "INSERT INTO user_table (name,email,password,dob,gender) VALUES (?,?,?,?,?)";
$query = $pdo->prepare($query);
$query->execute(array($name,$email,$password,$dob,$gender));
echo "Congrates, please login..";
}else{
echo "name and email exist..";
}
}
?>
In both cases you are overwriting $query:
$query = "INSERT INTO user_table (name,email,password,dob,gender) VALUES (?,?,?,?,?)";
$query = $pdo->prepare($query);
You need to give the execution a different variable to hold the object, for example:
$query = "INSERT INTO user_table (name,email,password,dob,gender) VALUES (?,?,?,?,?)";
$result = $pdo->prepare($query);
$result->execute(array($name,$email,$password,$dob,$gender));
In addition you should allow users to use the passwords / phrases they desire. Don't limit passwords.
While you're working with passwords never store them as plain text! Please use PHP's built-in functions to handle password security. If you're using a PHP version less than 5.5 you can use the password_hash() compatibility pack. Make sure that you don't escape passwords or use any other cleansing mechanism on them before hashing. Doing so changes the password and causes unnecessary additional coding.
I also noticed this in your code
$numRow = $query->rowCount();
Since the query is a SELECT query it will not work with rowCount()
From the docs:
PDOStatement::rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.
For SELECT when you are not doing a COUNT() query you can return the number of rows like this after you execute the query;
$rows = $result->fetchAll();
$num_rows = count($rows);
In your case it is not necessary to check the count though - just check to make sure the query executed which is enough to get into your conditional statements.
Related
Well i learned how to parameterize queries in php but i just wanted to ask that is it now totally secure from sql injection or any other type of attacks and if it isnt what betternment can i do to secure it even more?
<?php
include 'db.php';
$name = "";
$pass = "";
if(isset($_POST['send'])) {
$name = $_POST['name'];
$sql_u = "SELECT * FROM users WHERE username='$name'";
$res_u = $connection->query($sql_u);
if (mysqli_num_rows($res_u) > 0) {
echo "Sorry Username already taken";
}
else {
$password = $_POST['pass'];
$hpass = password_hash($password, PASSWORD_DEFAULT);
$query=$connection->prepare("insert into users (username,password) values (?,?)");
$query->bind_param('ss',$name,$hpass);
if ($query->execute()) {
$query->close();
header('location:index.php');
} else {
header('location:not.php');
}
}
}
I want to know if their is a even more secure way than only parameterizing queries?
You're using parameters for the INSERT statement, but you skipped using parameters for the SELECT statement. Without parameterizing the SELECT, you still have an SQL injection vulnerability. You need to use parameters in all cases when you combine untrusted content with your SQL.
Parameters are a good way to prevent SQL injection when combining dynamic content as values in your SQL queries.
You asked if there were another way, so I will recommend that you use PDO if you're starting out with a new PHP project. It's a little bit easier than Mysqli. In my opinion, there's no reason to use Mysqli unless you're porting a legacy PHP application that had used the deprecated Mysql PHP extension.
Here's what it would look like using PDO:
$name = $_POST['name'];
$sql = "SELECT COUNT(*) FROM users WHERE username = ?";
$query = $connection->prepare($sql);
$query->execute([$name]);
$count = $query->fetchColumn();
if ($count > 0) {
echo "Sorry Username already taken";
}
else {
$password = $_POST['pass'];
$hpass = password_hash($password, PASSWORD_DEFAULT);
$sql = "insert into users (username, password) values (?, ?)";
$query = $connection->prepare($sql);
if ($query->execute([$name, $hpass])) {
header('location:index.php');
} else {
header('location:not.php');
}
}
I'm assuming that the PDO connection was made previously, and that it had been enabled with exceptions. If you don't enable exceptions, you should check return values from every prepare() and execute() call to make sure there are no errors.
The same is true for Mysqli, you can enable exceptions so you don't have to check for errors manually.
I also show in the example my preference to use SELECT COUNT(*) instead of SELECT *. It's probably a trivial optimization in this case, but if * refers to many columns or there are many rows matching username = $name then the fetch will need to transfer less data from the database.
All I need is to produce a row. I've looked at all the samples and I cannot for the life of me get the right information. Hence help is required please.
Connection to DB in the usual way. Here is my code for the query.
$sql = "SELECT * FROM table WHERE `u_password` = $pword AND `user` = $uname LIMIT 1";
$result = mysqli_query($mdb, $sql);
$row = mysqli_fetch_assoc($result);
//Then I try to retrieve say the user name....
echo $row['seeking'];
I've got a count in there and it produces a result of 1.
The error I get is
'Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result'
Help would be appreciated.
The error
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result
Almost always means that the query failed for some reason, thus $result = mysqli_query returns FALSE rather than a mysql_result object so anything that then tries to use $result as an object will not work for obvious reasons.
The issue with your query is that text column data must be wrapped in quotes like this
$sql = "SELECT *
FROM table
WHERE `u_password` = '$pword' AND `user` = '$uname' LIMIT 1";
Your script is at risk of SQL Injection Attack
Have a look at what happened to Little Bobby Tables Even
if you are escaping inputs, its not safe!
You should use parameterized queries to avoid this.
$sql = "SELECT *
FROM table
WHERE `u_password` = ? AND `user` = ? LIMIT 1";
$stmt = mysqli_prepare($mdb, $sql);
// its also a good idea to check the staus of a prepare
// and show the error if it failed, at least while testing
if ( $stmt === FALSE ) {
echo mysqli_error($mdb);
exit;
}
$stmt->bind_param('ss', $pword, $uname );
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
echo $row['seeking'];
You need to use prepared statements (in actuality you could get it to work by quoting your strings but prepared statements are much better). Like so:
$sql = "SELECT * FROM table WHERE `u_password` = ? AND `user` = ? LIMIT 1";
$stmt = mysqli_prepare($mdb, $sql);
$stmt->bind_param("ss",$pword,$uname);
if ($stmt->execute()) {
$result = $stmt->get_result();
$row = mysqli_fetch_assoc($result);
//Then I try to retrieve say the user name....
echo $row['seeking'];
} else { /* something went wrong */ }
I have a strange problem where every time I do a simple DELETE query to delete WHERE email =. For some reason after deletion it also does a new INSERT with the same email? There is no INSERT anywhere and there are no triggers... Does anybody know why this happens? The table has a email and a nr with auto_increment.
$check_email = $_POST['email'];
$query = "SELECT `email` FROM `newsletter` WHERE email = '$check_email';";
$sth = $dbh->prepare($query);
$sth->execute();
$row = $sth->fetch(PDO::FETCH_ASSOC);
$check_users_email = $row['email'];
if($check_users_email != ''){
$query_update = "DELETE FROM `newsletter` WHERE email = '$check_users_email';";
}
$sth = $dbh->prepare($query_update);
$sth->execute();
Before deletion: email=test#email.com | nr=1
After deletion: email=test#email.com | nr=2
it might be in your sql string, since you're using prepared statements.
in PDO you should use named or unnamed placeholders. then after preparing the query, you pass the prams as an array when you execute the statement.
If you're using PDO, no need to use single quotes. just the column name and for the search value just use placeholders and then pass on the values on execution as an array.
NOTE: i renamed the PDO object $sth inside the 'if' statement, just to avoid name clash. also i moved the last 2 lines inside the 'if' statement, because you need the value of the sql string '$query_update' which will not be available if that statement returned false.
also to check if the variable $check_users_email is empty, you can use empty() or strlen().
try this:
$check_email = $_POST['email'];
$query = "SELECT email FROM newsletter WHERE email = :check_email";
$sth = $dbh->prepare($query);
$sth->execute(array(':check_email' => $check_email));
$row = $sth->fetch(PDO::FETCH_ASSOC);
$check_users_email = $row['email'];
if($check_users_email != ''){
$query_update = "DELETE FROM newsletter WHERE email = :check_users_email";
$sth2 = $dbh->prepare($query_update);
$sth2->execute(array(':check_users_email' => $check_users_email));
}
Can I use my own functions from PHP directly in SQL queries (using mySQL and PDO)? For example:
$query = null;
$result = null;
$query = $this->database_0->prepare("SELECT `id`, `salt` FROM `general_users` WHERE `username` = :username AND `password` = CONCAT(generatePassword(:password, `salt`)) LIMIT 1");
$query->bindValue(':username', $this->input->getValue('username'), PDO::PARAM_STR);
$query->bindValue(':password', $this->input->getValue('password'), PDO::PARAM_STR);
$query->execute();
$result = $query->fetch(PDO::FETCH_ASSOC);
$query->closeCursor();
Look at line 3 in "WHERE" case.
If it is not possible, I must use two queries just for check if a user exists, it do not look very optimal.
Thanks for your help, Bartek.
Can I use my own functions from PHP directly in SQL queries
No.
Mysql knows nothing of PHP and its functions. You are bound to use mysql functions in mysql and PHP functions in PHP. Quite easy to memorize.
So, here you go, with one single query
$sql = "SELECT id, salt, password FROM general_users WHERE username = ?";
$stmt = $this->db->prepare($sql);
$query->execute([$this->input->getValue('username')]);
$row = $query->fetch();
if (generatePassword($row['password'], $row['salt']) == $this->input->getValue('password'))
{
You can't use a PHP function in a MySQL query.
You can still do this with a single query. Just retrieve user info (including password) by comparing only its username. Then, in PHP, compare stored password with the one you have just computed. That would even allow you to distinguish two cases: "user exists, but password is wrong" and "user does not exist".
I am trying to award a user a badge if their points are 10,000. There is a field in the table called badge1 with a default value set to locked and a points row. I am running and if statement that if the users points are 10,000 then UPDATE the badge1 row from locked to unlocked. My code seems correct but It is neither updating the the field nor showing any errors.
<?php
$db = new PDO('mysql:host=hostname;dbname=databasename;charset=UTF-8', 'username', 'password');
$username = $_SESSION['username'];
$q = "SELECT Points FROM login_users WHERE username ='$username'");
$r = mysql_query($q);
$row = mysql_fetch_assoc($r);
$Points = $row['Points'];
if($Points == "10000") {
$awardBadge = $db->exec("UPDATE login_users SET badge1=unlocked WHERE username=?");
$Points->execute(array($username))
} else {
print "";
}
?>
UPDATE:
I managed to get it working.. however the problem is I am a bit new to converting old sql to PDO so this is not very secure but this is what works:
<?php
$connect = mysql_connect("host","username","password");
mysql_select_db("databasename");
$username = $_SESSION['jigowatt']['username'];
$q = "SELECT Points FROM login_users WHERE username = ('$username')";
$r = mysql_query($q);
$row = mysql_fetch_assoc($r);
$Points = $row['Points'];
?>
// Place somewhere
<?php
if($Points >= "10000") {
$result = mysql_query("UPDATE login_users SET maneki='unlocked' WHERE username='$username'");
} else {
print "Badge has not been unlocked";
}
?>
"10000" string should be an 10000 int
And also, you might want to make a choice here too. You're using 2 types of setting up a mysql-database connection. the old-fashioned mysql_function() way and the new fancy PDO method.
I think working with the PDO version is safer, since newer PHP versions will not support the old methods anymore... That... and it just looks dirty ;P
Try this:
<?php
session_start();
$dbSession = new PDO('mysql:host=***;dbname=***', '***', '***');
$selectQuery = $dbSession->prepare('
SELECT `User`.`Points`
FROM `login_users` AS `User`
WHERE `User`.`username` = :username
');
$selectQuery->bindParam(':username', $_SESSION['username'], PDO::PARAM_STR);
$user = $selectQuery->fetch(PDO::FETCH_ASSOC);
if ( !empty($user) && $user['Points'] == 10000 ) {
$updateQuery = $dbSession->prepare('
UPDATE `login_users`
SET `badge1` = \'unlocked\'
WHERE `username` = :username');
$updateQuery->bindParam(':username', $_SESSION['username'], PDO::PARAM_STR);
$updateQuery->execute();
}
?>
Usefull resources:
PHP Database Objects (PDO)
PHP Sessions
MySQL Datamanipulation
MySQL SELECT syntax
MySQL UPDATE syntax
Better check if >= 10000 and not yet awarded. That could you also be done in SQL so you don't need that logic in PHP.
UPDATE login_users SET badge1=unlocked WHERE points >= 10000 and badget1 <> unlocked
The issue is caused by $point value which actually is not equal to 10000, but is NULL.
So I propose to always use var_dump() to get the actual value of the variable in such cases.
one tip: check the PDO docs, before you write php code! You use PDO and mysql commands on same time for same job!?? why???
Try this if($Points == 10000) instead of if($Points == "10000")
mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier.
if($Points==10000){
$awardBadge = $db->prepare("UPDATE login_users SET badge1=unlocked WHERE username=?");
$awardBadge->execute(array($username));
}