PDO delete from MySQL - php

I have a problem with a PDO code.
I try the code below.
$id = null;
if ( !empty($_GET['t_id'])) {
$id = $_REQUEST['t_id'];
}
$action = isset($_POST['_DELETE_']) ? $_POST['_DELETE_'] : "";
if ($action == 'do_not_delete') {
header("Location: index.php?action=DEL_ERROR");
}
if($action=='delete') {
$host = "localhost";
$db_name = "_notice";
$username = "root";
$password = "111";
$con = new PDO("mysql:host={$host};dbname={$db_name}", $username, $password);
$id = $_REQUEST['t_id'];
$query = "DELETE FROM topics WHERE topic_id = ?";
$stmt = $con->prepare($query);
$stmt->bindParam(1, $id);
$exc = $stmt->execute();
if($exc){
$con = null;
header("Location: index.php?action=DEL_OK");
}else{
$con = null;
header("Location: index.php?action=DEL_ERROR");
}}
Anything happens (dose not delete element from the database).
I have no errors on page; even when i use a try catch block, or page parameter like index.php?action=DELETE

You need to call $stmt->execute() after preparing the query and binding parameters.
Update:
You are checking the content of $_GET['t_id'] but always setting $id to $_REQUEST['t_id'], and everything will execute only if $_POST['_DELETE_'] contains delete.
Also, try to check the resulting query and parameters with $stmt->debugDumpParams() before executing and maybe replace your bindParam with $stmt->bindParam(1, $id, PDO::PARAM_INT).

Related

Is it possible to parametarize query that has a concatenation variable?

As learning php and sql injections, I would like to parametize my queries for safe and secure website app. however, mine does not work I try to parametize my update and select my query but I didn't achieved the goal to make the program working.
The current output is throwing an error the ? is not found
As of now here is my code, am I missing something that does not work?
<?php
//connection
$connection = mysqli_connect("hostserver","username","");
$db = mysqli_select_db($connection, 'dbname');
if (isset($_POST['qrname'])) {
$qrid = $_POST['qrid'];
//Query No. 1
$qrQuery = "SELECT * FROM scratch_cards WHERE code='$qrid' ";
$qrQuery_run = mysqli_query($connection,$qrQuery);
//Query No. 2
$qrQuery2 = "UPDATE scratch_cards SET status = 'U' WHERE code='$qrid' ";
$qrQuery_run2 = mysqli_query($connection,$qrQuery2);
$qrQuery2->bind_param("s", $qrid);
$qrQuery2->execute();
while ($qrRow = mysqli_fetch_array($qrQuery_run)) {
$txtQrvalue = $qrRow['amount'];
$txtQrstatus = $qrRow['status'];
// QUERY TO UPDATE THE VALUE
// BIND AND PARAMETIZE MY QUERY
$qrQuery3 = $db->parepare("UPDATE shopusers SET ewallet = ewallet + " . (0+?) . " WHERE id = '?' ");
$qrQuery3->bind_param("ii", $txtQrvalue, $id);
$qrQuery3->execute();
//END
}
If I'm reading your question and code right, you can reduce this down to two queries using a JOIN instead, that way you can get rid of the SELECT statement. Use prepared statements for both.
I also specified your connection's charset to UTF-8 (which you should set for your PHP and HTML headers, and your database-tables too).
<?php
$connection = mysqli_connect("hostserver","username","");
$db = mysqli_select_db($connection, 'dbname');
$connection->set_charset("utf8");
if (isset($_POST['qrname'])) {
$qrid = $_POST['qrid'];
$sql = "UPDATE scratch_cards SET status = 'U' WHERE code=?";
$stmt = $connection->prepare($sql);
$stmt->bind_param("s", $qrid);
$stmt->execute();
$stmt->close();
$sql = "UPDATE shopusers su
INNER JOIN scratch_cards sc
ON sc.qrid = su.code
SET su.ewallet = su.ewallet + sc.amount,
sc.status = 'U'
WHERE sc.code = ?";
$stmt = $connection->prepare($sql);
$stmt->bind_param("s", $qrid);
$stmt->execute();
$stmt->close();
}
we have the foll syntax in PDO bind param, where i have put your update query as an example and it works perfectly fine. Try searching for named parameter binding
<?php
$user = 'root';
$pass = 'xxxx';
$DB = 'test';
$host = 'localhost';
$mysqlConnection = new \PDO('mysql:host='.$host.';dbname='.$DB, $user, $pass);
$mysqlConnection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$sql = 'update info set fname = fname + :fn where id = 1';
$stmt = $mysqlConnection->prepare($sql);
$stmt->bindValue(':fn', '100');
$stmt->execute();
echo $stmt->rowCount();
?>
Is this the query you wanted to run using mysqli bind params???
<?php
ini_set('display_errors', 1);
$user = 'root';
$pass = 'xxxx';
$DB = 'test';
$host = 'localhost';
$sql = 'update info set fname = fname + ? where id = 1';
$conn = new mysqli($host, $user, $pass, $DB);
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $val);
$val = 100;
$stmt->execute();
printf("%d Row inserted.\n", $stmt->affected_rows);
exit;

using variable inside mysql update query in php

<?php
require 'functions/connection.php';
$conn = Connect();
$e_id = $conn->real_escape_string($_POST['e_id']);
$first_name = $conn->real_escape_string($_POST['first_name']);
$last_name = $conn->real_escape_string($_POST['last_name']);
$e_salary = $conn->real_escape_string($_POST['e_salary']);
$e_startdate = $conn->real_escape_string($_POST['e_startdate']);
$e_department = $conn->real_escape_string($_POST['e_department']);
$sql = "UPDATE employee SET firstname='$first_name' WHERE id=$e_id";
if (mysqli_query($conn, $sql)) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . mysqli_error($conn);
}
mysqli_close($conn);
?>
I'm trying to use the first_name variable inside the update query.
I tried echo the variable and its working...
this is my connection code that im using.
<?php
function Connect()
{
$dbhost = "localhost";
$dbuser = "root";
$dbpass = "";
$dbname = "company";
// Create connection
$conn = new mysqli($dbhost, $dbuser, $dbpass, $dbname) or die($conn->connect_error);
return $conn;
}
?>
if i i replace the variable with anything between "" the database is getting updated
I'd suggest making it more secure and using prepared statements. This is an example using mysqli, but I prefer PDO:
<?php
require 'functions/connection.php';
$conn = Connect();
// Prepare the query
$myQuery = $conn->prepare("UPDATE employee SET firstname=? WHERE id=?");
$e_id = $conn->real_escape_string($_POST['e_id']);
$first_name = $conn->real_escape_string($_POST['first_name']);
$last_name = $conn->real_escape_string($_POST['last_name']);
$e_salary = $conn->real_escape_string($_POST['e_salary']);
$e_startdate = $conn->real_escape_string($_POST['e_startdate']);
$e_department = $conn->real_escape_string($_POST['e_department']);
// Bind your variables to the placemarkers (string, integer)
$myQuery->bind_param('si', $first_name, $e_id);
if ($myQuery->execute() == false) {
echo 'Error updating record: ' . $mysqli->error;
}
else {
echo 'Record updated successfully';
}
$myQuery->close();
?>
Note: The 'cleansing' you're doing in the middle I have left, but it's not really necessary with prepared statements.
functions/connection.php (Now an object):
<?php
class Connect
{
private $dbhost = "localhost";
private $dbuser = "root";
private $dbpass = "";
private $dbname = "company";
public $conn;
public function __construct()
{
if($this->conn = new mysqli($this->dbhost, $this->dbuser, $this->dbpass, $this->dbname))
{
//connection established
//do whatever you want here
}
else
{
//Error occurred
die($this->conn->error);
}
}
//other functions here
}
?>
Change mysqli_query to: $conn->conn->query($sql);
Prepared statement:
Avoid SQLI injection
if($stmt = $conn->conn->prepare("UPDATE employee SET firstname = ? WHERE id = ?"))
{
$stmt->bind_param('si', $first_name, $e_id);
$stmt->execute();
echo $stmt->affected_rows;
}
Final code:
<?php
require 'functions/connection.php';
$conn = new Connect();
$e_id = $conn->conn->real_escape_string($_POST['e_id']);
$first_name = $conn->conn->real_escape_string($_POST['first_name']);
$last_name = $conn->conn->real_escape_string($_POST['last_name']);
$e_salary = $conn->conn->real_escape_string($_POST['e_salary']);
$e_startdate = $conn->conn->real_escape_string($_POST['e_startdate']);
$e_department = $conn->conn->real_escape_string($_POST['e_department']);
if($stmt = $conn->conn->prepare("UPDATE employee SET firstname = ? WHERE id = ?"))
{
$stmt->bind_param('si', $first_name, $e_id);
$stmt->execute();
echo $stmt->affected_rows;
}
$conn->conn->close();
?>

PDO Username validation if already exists

I have a problem with register form.My form works properly but whenever i try to insert username that already exists it doesn't shows any error.
here is my php register file:
<?php
$servername = "localhost";
$username = "root";
$password = "";
try {
$conn = new PDO("mysql:host=$servername;dbname=dblogin", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if (isset($_POST['submit'])) {
$user_name = $_POST['user_name'];
$user_email = $_POST['user_email'];
$user_pass = $_POST['user_pass'];
$hash = password_hash($user_pass, PASSWORD_DEFAULT);
$stmt = $con->prepare("SELECT user_name FROM users WHERE user_name = :user_name");
if($stmt->rowCount() > 0){
echo "exists!";
}
else{
$insert = $conn->prepare("INSERT INTO users (user_name,user_email,user_pass) values(:user_name,:user_email,:user_pass)");
$insert->bindparam(':user_name',$user_name);
$insert->bindparam(':user_email',$user_email);
$insert->bindparam(':user_pass',$hash);
$insert->execute();
}
}
catch(PDOException $e)
{
echo "connection failed";
}
?>
Thanks for your support
You are not executing the select statement. You need to bind params and execute the select statement, try this after the select statemnt.
$stmt->bindparam(':user_name',$user_name);
$stmt->execute();
public function usernameCheck($username)
{
$sql = "SELECT * FROM $this->table where username = :username";
$query = $this->pdo->prepare($sql);
$query->bindValue(':username', $username);
$query->execute();
if ($query->rowCount() > 0) {
return true;
} else {
return false;
}
}
use this one in your project hope it will work... :)
missing } in if statement
if (isset($_POST['submit'])) {
$user_name = $_POST['user_name'];
$user_email = $_POST['user_email'];
$user_pass = $_POST['user_pass'];
$hash = password_hash($user_pass, PASSWORD_DEFAULT);
$stmt = $con->prepare("SELECT user_name FROM users WHERE user_name = :user_name");
if($stmt->rowCount() > 0){
echo "exists!";
}
}else{
}
I notice 4 things (2 of which have been mentioned by others):
First and smallest is you have a spelling error ($con instead of $conn) - don't worry it happens to the best of us - in you first $stmt query which means your select-results becomes NULL instead of 0 - so you rowCount find that it is not over 0 and moves on without your error message
Second you forgot to bind and execute the parameters in your first $stmt query which gives the same result for your rowCount results
Third always clean your variables even when using prepared statements - at a bare minimum use
$conn->mysql_real_escape_string($variable);
and you can with advantage use
htmlspecialchars($variable);
And fourth since you are not doing anything with the database (other than looking) you could simplify your code by simply writing:
$stmt = $conn->query("SELECT user_name FROM users WHERE user_name = '$user_name' LIMIT 1")->fetch();
as I said - no need to bind or execute in the first query
and as a general rule - don't use rowCount - ever - if you have to know the number of results (and in 99% of cases you don't) use count(); but if you as here just want to know if anything at all was found instead use:
if ( $stmt ) {
echo "exists!";
} else {
// insert new user as you did
}
Edit:
Also - as a side note - there are a few things you should consider when you initially create your connection...
Ex:
// Set variables
$servername = "localhost";
$username = "***";
$password = "***";
$database = "***";
$charset = 'utf8'; // It is always a good idea to also set the character-set
// Always create the connection before you create the new PDO
$dsn = "mysql:host=$servername;dbname=$database;charset=$charset";
// Set default handlings as you create the new PDO instead of after
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // And add default fetch_mode
PDO::ATTR_EMULATE_PREPARES => false, // And ALWAYS set emulate_prepares to false
];
// And now you are ready to create your new PDO
$conn = new PDO($dsn, $username, $password, $opt);
Just a suggestion... happy trails

slim framework no output displayed

I'm trying to get a json file using Slim Framework. The code I'm trying is mentioned below
$app->get('/forum/:id', function ($id) {
$user_name = "abc";
$password = "123";
$database = "test";
$server = "localhost";
$db_handle = mysqli_connect($server, $user_name, $password);
mysqli_set_charset($db_handle, "utf8");
mysqli_select_db($db_handle, $database);
$arr = array();
$SQL = "Select y123_forum.post_id, y123_forum.posttext FROM y123_forum INNER JOIN y123_users ON y123_forum.user_id = y123_users.id WHERE type = 1 AND y123_users.email = 'id'";
$result = mysqli_query($db_handle, $SQL);
while ($row = mysqli_fetch_assoc($result))
{
array_push($arr, $row);
}
mysqli_close($db_handle);
echo json_encode($arr);
});
The output displayed on the browser is []
When I try the above code without passing parameter, i.e
$app->get('/faqs/', function () {
$user_name = "abc";
$password = "123";
$database = "test";
$server = "localhost";
$db_handle = mysqli_connect($server, $user_name, $password);
mysqli_set_charset($db_handle, "utf8");
mysqli_select_db($db_handle, $database);
$arr = array();
$SQL = Select y123_forum.post_id, y123_forum.posttext FROM y123_forum INNER JOIN y123_users ON y123_forum.user_id = y123_users.id WHERE type = 1 AND y123_users.email = 'abc#gmail.com'"
$result = mysqli_query($db_handle, $SQL);
while ($row = mysqli_fetch_assoc($result))
{
array_push($arr, $row);
}
mysqli_close($db_handle);
echo json_encode($arr);
});
then it works fine
How do i fix this, I need to get this working to get the json file by passing any email id's from the database
You're forgetting the $ in the parameter, it thinks you're looking for an email address of 'id', not the contents of $id.
SELECT * FROM y123_forum WHERE email = '$id';
Note that this is a horrible, bad, unsafe way to pass parameters to a SQL query. The correct way would be to parameterize your query and execute this way:
$SQL = 'SELECT * FROM y123_forum WHERE email = ?';
$stmt = mysqli_stmt_init($db_handle);
if (mysqli_stmt_prepare($stmt, $sql)) {
mysqli_stmt_bind_param($stmt, 's', $id);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_assoc($result))
{
array_push($arr, $row);
}
}
The 's' in mysql_stmt_bind_param tells the driver your $id variable should be treated as a string, and escapes it appropriately.

MySql PHP Update Error

I've been messing about with this code for a few hours now and can't work out why it's not working. It's a profile update php page that is passed through JQuery and all seems to be fine except for it actually updating into the table. Here is the code I'm using:
session_start();
include("db-connect.php");//Contains $con
$get_user_sql = "SELECT * FROM members WHERE username = '$user_username'";
$get_user_res = mysqli_query($con, $get_user_sql);
while($user = mysqli_fetch_array($get_user_res)){
$user_id = $user['id'];
}
$name = mysqli_real_escape_string($con, $_REQUEST["name"]);
$location = mysqli_real_escape_string($con, $_REQUEST["location"]);
$about = mysqli_real_escape_string($con, $_REQUEST["about"]);
$insert_member_sql = "UPDATE profile_members SET id = '$user_id', names = '$name', location = '$location', about = '$about' WHERE id = '$user_id'";
$insert_member_res = mysqli_query($con, $insert_member_sql) or die(mysqli_error($con));
if(mysqli_affected_rows($con)>0){
echo "1";
}else{
echo "0";
}
All I get as the return value is 0, can anybody spot any potential mistakes? Thanks
To begin with, use
require("db-connect.php");
instead of
include("db-connect.php");
And now, consider using prepared statements, your code is vulnerable to sql injections.
Consider using PDO instead of the mysql syntax, in the long run I find it much better to use and it avoids a lot of non-sense-making problems, you can do it like this (You can keep it in the db-connect file if you want, and even make the database conncetion become global):
// Usage: $db = connectToDatabase($dbHost, $dbName, $dbUsername, $dbPassword);
// Pre: $dbHost is the database hostname,
// $dbName is the name of the database itself,
// $dbUsername is the username to access the database,
// $dbPassword is the password for the user of the database.
// Post: $db is an PDO connection to the database, based on the input parameters.
function connectToDatabase($dbHost, $dbName, $dbUsername, $dbPassword)
{
try
{
return new PDO("mysql:host=$dbHost;dbname=$dbName;charset=UTF-8", $dbUsername, $dbPassword);
}
catch(PDOException $PDOexception)
{
exit("<p>An error ocurred: Can't connect to database. </p><p>More preciesly: ". $PDOexception->getMessage(). "</p>");
}
}
And then init the variables:
$host = 'localhost';
$user = 'root';
$databaseName = 'databaseName';
$pass = '';
Now you can access your database via
$db = connectToDatabase($host, $databaseName, $user, $pass);
Now, here's how you can solve your problem (Using prepared statements, avoiding sql injection):
function userId($db, $user_username)
{
$query = "SELECT * FROM members WHERE username = :username;";
$statement = $db->prepare($query); // Prepare the query.
$statement->execute(array(
':username' => $user_username
));
$result = $statement->fetch(PDO::FETCH_ASSOC);
if($result)
{
return $result['user_id'];
}
return false
}
function updateProfile($db, $userId, $name, $location, $about)
{
$query = "UPDATE profile_members SET name = :name, location = :location, about = :about WHERE id = :userId;";
$statement = $db->prepare($query); // Prepare the query.
$result = $statement->execute(array(
':userId' => $userId,
':name' => $name,
':location' => $location,
':about' => $about
));
if($result)
{
return true;
}
return false
}
$userId = userId($db, $user_username); // Consider if it is not false.
$name = $_REQUEST["name"];
$location = $_REQUEST["location"];
$about = $_REQUEST["about"];
$updated = updateProfile($db, $userId, $name, $location, $about);
You should check the queries though, I fixed them a little bit but not 100% sure if they work.
You can easily make another function which inserts into tha database, instead of updating it, or keeping it in the same function; if you find an existance of the entry, then you insert it, otherwise you update it.

Categories