is there something wrong with this php code? - php

is this piece of code correct syntax wise ?
I need to update some fields in a certain row in my database which i can access using email ... so is this right ?
public function storeData($emaill, $servicee, $ratee, $rated_clientss) {
$email = "samy#gmail.com";
$service = "lksdjfsdkljf";
$rate = "good";
$rated_clients = "20";
$stmt = $this->conn->prepare ( "UPDATE users SET service='$service' and SET rate='$rate' and SET rated_clients='$rated_clients' WHERE email='$email'" );
var_dump($stmt->execute ());
if ($stmt->execute ()) {
$data = $stmt->get_result ()->fetch_assoc ();
$stmt->close ();
return $data;
} else {
return NULL;
}
}

Prepared statments to not directly accept user input, instead, you need to pass them as a placeholder: ?, and then use bind_param() to fill in the type and the variable.
Observe:
$stmt = $this->conn->prepare ( "UPDATE users SET service=? and SET rate=? and SET rated_clients=? WHERE email=?" );
$stmt->bind_param('ssss', $service, $rate, $rated_clients, $email);
Now you can correctly ->execute the $stmt.

Related

Update SQL Query not executing

I have a system in which when a user uses a coupon, a "taken" column is filled with a string which I run IS NULL against to render the coupon consumed. My problem is that my update_coupon function is not updating the column as I expect. The first time it worked, but then I must have changed something and subsequent queries no longer work.
Sorry for the noob question. Thank you for any help.
function is_valid_coupon($card_code){
global $db;
$code = sha1($card_code);
$query = 'SELECT * FROM giftcards where card_code = :code';
$statement = $db->prepare($query);
$statement->bindValue(':code', $code);
$statement->execute();
$valid = ($statement->rowCount() == 1);
$statement->closeCursor();
return $valid;
}
function update_coupon($card_code){
global $db;
$code = sha1($card_code);
$query = "
UPDATE `giftcards`
SET taken = used
WHERE card_code = :card_code";
$statement = $db->prepare($query);
$statement->bindValue(':card_code', $code);
$statement->execute();
$statement->closeCursor();
}
Which are executed like so:
if ($card_code){
if (is_valid_coupon($card_code)){
update_coupon($card_code);
}
}
This line is causing the problem:
SET taken = used
you need to put apostrophes before and after used:
SET taken = 'used'

Update dynamically SET statement bind_param not working correctly

I have a simple problem whitch I can't solve, because I am starting with OOP and in the same time with MySQLi.
I need these function universal for everything and I need SET statement dynamically changed.
This is my update function these not working
public function updateUser($user, $pass, $dbSet) {
if($this->getUser($user, $pass) != NULL) {
$sql = $this->connection->prepare("UPDATE users SET ? WHERE user = ?");
$sql->bind_param('ss', $dbSet, $user);
$sql->execute();
$sql->close();
return true;
} else {
return false;
}
}
Variable $dbSet contains different values. For example:
$dbSet = "last_activity = ".$last_activity;
Or complex
$dbSet = "name = ".$newName.", surname = ".$newSurname.", email = ".$newEmail;
But when I change it for one SET statement, it works...
...
$sql = $this->connection->prepare("UPDATE users SET last_activity = ? WHERE user = ?");
...

How to organize SQL select functions?

I want to get information by user id, so lets add this to the model:
public function getById ($id)
{
$sql = 'SELECT * FROM users';
return ActualDbHander::run($sql);
}
later, I want to get only some fields:
public function getById ($id, $fields = '*')
{
$sql = 'SELECT '.$fields.' FROM users';
return ActualDbHander::run($sql);
}
another idea, lets add ordering:
public function getById ($id, $fields = '*', $orderBy = '')
{
$sql = 'SELECT '.$fields.' FROM users';
if ($orderBy != '')
{
$sql.= ' ORDER BY '.$orderBy;
}
return ActualDbHander::run($sql);
}
and I see this becaming messy and messy. What if I want to add JOIN-s? What if I want to add detailed WHERE-s? This is when "too generalic" methods born.
I completely agree with mch and Mjh comments, but, only in the case you actually want to have a "BD driver" (and build it yourself) I'd use different names for each query, very specific names, because you need to know exactly what a function will return to you.
So if I were you I would use names like getAllUsers, getUserById, getAllUsersOnlyPersonalData, getUserByIdOnlyPersonalData, getAllUsersOnlyContactData and so on (with fixed fields and filters for each method).
Note that in your examples you are not using at all the $id variable, so you are always receiving a list of users.
Regarding the method to make the queries, there are lots of ways to do it. Personally, I prefer MySQLi Object-Oriented prepared statements, because it's safe, easy and currently very extended, so I will use it just to ilustrate the examples.
Your functions would be something like this:
<?php
class DBDriver{
function openConnection(){
// If you don't always use same credentials, pass them by params
$servername = "localhost";
$username = "username";
$password = "password";
$database = "database";
// Create connection
$conn = new mysqli($servername, $username, $password, $database);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Return conection object
return $conn;
}
function closeConnection($conn){
$conn->close();
}
function getAllUsers (){ // We don't need ids here
$conn = $this->openConnection();
// Array of arrays to store the results
// You can use any other method you want to return them
$resultsArray = [];
$sqlQuery = "SELECT * FROM users";
// In this case it's not neccesary to use prepared statements because we aren't binding any param but we'll use it to unify the method
if ($stmt = $conn->prepare($sqlQuery)) {
// Execute query
$stmt->execute();
// Bind result variables (I don't know your actuall column names)
$stmt->bind_result($id, $name, $email, $phone, $birthdate);
// Fetch values
while ($stmt->fetch()) {
$resultsArray[] = [$id, $name, $email, $phone, $birthdate];
}
// Close statement
$stmt->close();
}
$this->closeConnection($conn);
// If no results, it returns an empty array
return $resultsArray;
}
function getUserByIdOnlyContactData ($userId){
$conn = $this->openConnection();
// Array to store the results (only one row in this case)
$resultsArray = [];
$sqlQuery = "SELECT name, email, phone FROM users WHERE id = ?";
if ($stmt = $conn->prepare($sqlQuery)) {
// Bind parameter $userId to "?" marker in $sqlQuery
$stmt->bind_param("i", $userId);
$stmt->execute();
$stmt->bind_result($name, $email, $phone);
// If id found
if ($stmt->fetch()) {
$resultsArray = [$name, $email, $phone];
}
// Close statement
$stmt->close();
}
$this->closeConnection($conn);
return $resultsArray;
}
function getAllUserOnlyBirthdayDataOrderByBirthday (){
$conn = $this->openConnection();
$resultsArray = [];
$sqlQuery = "SELECT id, name, birthdate FROM users ORDER BY birthdate";
if ($stmt = $conn->prepare($sqlQuery)) {
$stmt->execute();
$stmt->bind_result($id, $name, $birthdate);
while ($stmt->fetch()) {
$resultsArray[] = [$id, $name, $birthdate];
}
// Close statement
$stmt->close();
}
$this->closeConnection($conn);
return $resultsArray;
}
} // Class end
This way it's true you will have lots of functions depending on your requirements but as you can see it's extremely easy to add new ones or modify them (and you won't get mad with many different options in the same function).
Hope this helps you to organize your database driver!

SELECT_IDENTITY() not working in php

Scenario:
I have a SQL Query INSERT INTO dbo.Grades (Name, Capacity, SpringPressure) VALUES ('{PHP}',{PHP}, {PHP})
The data types are correct.
I need to now get the latest IDENTIY which is GradeID.
I have tried the following after consulting MSDN and StackOverflow:
SELECT SCOPE_IDENTITY() which works in SQL Management Studio but does not in my php code. (Which is at the bottom), I have also tried to add GO in between the two 'parts' - if I can call them that - but still to no avail.
The next thing I tried, SELECT ##IDENTITY Still to no avail.
Lastly, I tried PDO::lastInsertId() which did not seem to work.
What I need it for is mapping a temporary ID I assign to the object to a new permanent ID I get back from the database to refer to when I insert an object that is depended on that newly inserted object.
Expected Results:
Just to return the newly inserted row's IDENTITY.
Current Results:
It returns it but is NULL.
[Object]
0: Object
ID: null
This piece pasted above is the result from print json_encode($newID); as shown below.
Notes,
This piece of code is running in a file called save_grades.php which is called from a ajax call. The call is working, it is just not working as expected.
As always, I am always willing to learn, please feel free to give advice and or criticize my thinking. Thanks
Code:
for ($i=0; $i < sizeof($grades); $i++) {
$grade = $grades[$i];
$oldID = $grade->GradeID;
$query = "INSERT INTO dbo.Grades (Name, Capacity, SpringPressure) VALUES ('" . $grade->Name . "',". $grade->Capacity .", ".$grade->SpringPressure .")";
try {
$sqlObject->executeNonQuery($query);
$query = "SELECT SCOPE_IDENTITY() AS ID";
$newID = $sqlObject->executeQuery($query);
print json_encode($newID);
} catch(Exception $e) {
print json_encode($e);
}
$gradesDictionary[] = $oldID => $newID;
}
EDIT #1
Here is the code for my custom wrapper. (Working with getting the lastInsertId())
class MSSQLConnection
{
private $connection;
private $statement;
public function __construct(){
$connection = null;
$statement =null;
}
public function createConnection() {
$serverName = "localhost\MSSQL2014";
$database = "{Fill In}";
$userName = "{Fill In}";
$passWord = "{Fill In}";
try {
$this->connection = new PDO( "sqlsrv:server=$serverName;Database=$database", $userName, $passWord);
$this->connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e ) {
die("Connection Failed, please contact system administrator.");
}
if ($this->connection == null) {
die("Connection Failed, please contact system administrator.");
}
}
public function executeQuery($queryString) {
$results = array();
$this->statement = $this->connection->query( $queryString );
while ( $row = $this->statement->fetch( PDO::FETCH_ASSOC ) ){
array_push($results, $row);
}
return $results;
}
public function executeNonQuery($queryString) {
$numRows = $this->connection->exec($queryString);
}
public function getLastInsertedID() {
return $this->connection->lastInsertId();
}
public function closeConnection() {
$this->connection = null;
$this->statement = null;
}
}
This is PDO right ? better drop these custom function wrapper...
$json = array();
for ($i=0; $i < sizeof($grades); $i++) {
//Query DB
$grade = $grades[$i];
$query = "INSERT INTO dbo.Grades (Name, Capacity, SpringPressure)
VALUES (?, ?, ?)";
$stmt = $conn->prepare($query);
$success = $stmt->execute(array($grade->Name,
$grade->Capacity,
$grade->SpringPressure));
//Get Ids
$newId = $conn->lastInsertId();
$oldId = $grade->GradeID;
//build JSON
if($success){
$json[] = array('success'=> True,
'oldId'=>$oldId, 'newId'=>$newId);
}else{
$json[] = array('success'=> False,
'oldId'=>$oldId);
}
}
print json_encode($json);
Try the query in this form
"Select max(GradeID) from dbo.Grades"

Bind NULL value with mysqli_stmt_bind_param()

I'm trying to convert a code I write to use the php function mysqli_stmt_bind_param() instead of replacing tag in prewritten statement which I believe is not a good pratice.
So here one of the function I have today:
$idTag1="###";
$requestReplaceArray = array("%PRODUCT_ID%","%PLATFORM_ID%","%STATUS_ID%","%DATE%","%COMMENT%",$idTag1);
$updateRequest="UPDATE REQUEST
SET
id_product = %PRODUCT_ID%,
id_platform = %PLATFORM_ID%,
id_status = %STATUS_ID%,
last_modifier = '".$_SERVER['PHP_AUTH_USER']."',
last_modification_date='%DATE%',
last_comment = '%COMMENT%'
WHERE id =".$idTag1;
function updateRequest($id, $productID, $platformID, $statusID, $date, $comment){
global $requestReplaceArray, $updateRequest;
escapeArguments($id, $productID, $platformID, $statusID, $date,$comment);
/*if number value is empty replace by 'null'*/
$productID=replaceEmptyValueByNull($productID);
$platformID=replaceEmptyValueByNull($platformID);
$statusID=replaceEmptyValueByNull($statusID);
$dbConnection = getDbConnection();
$replacement = array($productID, $platformID, $statusID,$date ,$comment, $id);
$updateRequest = str_replace($requestReplaceArray, $replacement, $updateRequest);
if(! $result = mysqli_query( $dbConnection, $updateRequest ) ) {
mysqli_free_result($result);
$dbConnection->close();
return "Error MyU02, can't update the request #".$id;
}else{
mysqli_free_result($result);
$dbConnection->close();
return $id;
}
}
This code isn't perfect but it works except when a $date is NULL.
My objectives is to now use that synthax :
$requestReplaceString = "iiissi";
$updateRequest="UPDATE REQUEST
SET
id_product = ?,
id_platform = ?,
id_status = ?,
last_modifier = '".$_SERVER['PHP_AUTH_USER']."',
last_modification_date=?,
last_comment = ?
WHERE id =?";
function updateRequest($id, $productID, $platformID, $statusID, $date, $comment){
global $requestReplaceString, $updateRequest;
$dbConnection = getDbConnection();
$stmt = mysqli_prepare( $dbConnection, $updateRequest);
mysqli_stmt_bind_param($stmt, $requestReplaceString, $productID, $platformID, $statusID,$date ,$comment, $id);
if(mysqli_stmt_execute($stmt) ) {
mysqli_stmt_close($stmt);
$dbConnection->close();
return $id;
}else{
mysqli_stmt_close($stmt);
$dbConnection->close();
return "Error MyU02, can't update the request #".$id;
}
}
My main issue here is to set some value to null because trying to bind a php NULL is not working at all. So my question is how can I bind NULL with mysqli if it's possible ?
Edit: it does work and my mistake comes from my bad code, the code is now corrected.
Just bind it. It works perfectly. Any null value will be sent to server as mysql's NULL.
Also note that there is a fatal issue with your code: you are connecting to database for the every query. Which will just kill your server.

Categories