...i am not getting any further.
my database contains a column 'name' = 'John Richards'
i try to query it like:
$act = "John Richards";
prepareEditing($act);
function prepareEditing($act) {
include ($_SERVER['DOCUMENT_ROOT']."/final_ritg/includes/dbconnect.php");
$act = str_replace(" ", " ", $act);
$sql = "select `name`,`genre`, `members`, `story`, `image`, `contact_fname`, `contact_lname`, `contact_phone`, `contact_email` from `festival`.`act` where `name` = :name ;";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':name', $act);
$stmt->execute();
echo $stmt->rowCount();
}
when 'name' only contains a single word, like 'john', the function returns 1 ($act holds 'john' as well).
How do I have to prepare my query?
Edit: I am using utf8 across the board.
Edit: This is the prepare stmt I use to insert the data:
$stmt->bindParam(':name', str_replace(' ',' ',$name));
I did so, because the query result would have been cut off at the whitespace when trying to retrieve it.
As it turns out, my mistake was not in the php, but inside the html.
I was creating a select list from a table. because the names were unique, i used those as primary keys and as value for each select-option...those dont like whitespace.
The solution here would be to either add a numbered index to the table or to do some string-conversion (but that would cause a lot of extra work preparing the string for the query) I dont yet know how I would be going over this.
Anyways, maybe another beginner runs into the same trap and finds this useful.
Related
My application performs INSERT queries like this:
INSERT INTO table (`col1`, `col2`, `col3`) VALUES ('oneVal', 'twoVal', 'threeVal')
Now I want to rebuild my application so it will ALWAYS SELECT, INSERT, DELETE and UPDATE with a specific id.
Let's say the unique id is called: companyId
I don't want to rewrite all my queries manually, so I am trying to write a function that rewrites the existing SQL queries with PHP so it will include the companyId inside the query.
Desired outcome if companyId would be '1' (companyId IS NOT ALWAYS '1'!):
INSERT INTO table (`col1`, `col2`, `col3`, `companyId`) VALUES ('oneVal', 'twoVal', 'threeVal', '1')
My question(s) is/are:
Is there a way in PHP so I can dynamically rewrite the query so
it would include the companyId column and the matching id value?
Is there a better way to do this? Like some trick setting MySQL
server to ALWAYS use an extra value (in this case companyId='1'
?
I've tried option (1) by searching for the string
) VALUES
Once I found that string, I add companyId before the ).
Now get to the end of the query, get the most right ) and add the value before that.
But is this for a generic case? I think there might be a better way to solve this.
Thanks in advance community!
EDIT 1 with more clarification
Currently I've already built a function that modifies my SELECT statements.
Function code:
//If current query = SELECT query
if (containsString($sql, 'select')) {
//Check if contains WHERE
if (containsString($sql, 'where')) {
//Yes
//Add companyId after WHERE
$sql = substr_replace($sql, '(companyId=?) AND ', strpos($sql, 'WHERE') + 6, 0);
//Explanation:
//SELECT * FROM table WHERE deleted='No'; becomes -->
//SELECT * FROM table WHERE (companyId=?) AND deleted='No';
}else{
//No
//Get table , and after that INSERT WHERE companyId=?
$tableName = explode(' from ', strtolower($sql))[1]; //Get part AFTER 'from'
//First word after $tableName = tablename
$tableName = explode(' ', $tableName)[0]; //First word after 'from' = tablename
$sql = substr_replace($sql, 'WHERE (companyId=?) ', strpos($sql, $tableName) + strlen($tableName) + 1, 0);
//Explanation:
//SELECT * FROM table ORDER BY id; becomes -->
//SELECT * FROM table WHERE (companyId=?) ORDER BY id;
}
}
So this code dynamically adds an extra condition to the query statement.
This is also easily possible with DELETE and UPDATE statements (same as SELECT)
But Iam trying to come up with something like this for INSERT INTO queries.
How can I modify the original query using the new companyId?
I guess If you have an associative array with the column names and values then you easily can make it more dynamic for future also. Let's say you've an array of column names with value of it e.g
$data = ['col1'=>'val1','col2'=>'val2','col3'=>'val3','companyId'=>1];
$query = "INSERT INTO `yourtable` ( ".implode(' , ', array_keys($data)).") VALUES ('".implode("' , '", array_values($data))."')";
echo $query;
DEMO: https://3v4l.org/udt1i
Then you can do with regex replace way globally to add column and value to all of your 100 query.
<?php
$re = '/\) VALUES (.+?(?=\)))/m';
$str = 'INSERT INTO table (`col1`, `col2`, `col3`) VALUES (\'oneVal\', \'twoVal\', \'threeVal\')';
$subst = ',`col4`) VALUES $1 , \'1\'';
$result = preg_replace($re, $subst, $str);
echo $result;
?>
DEMO: https://3v4l.org/rOQDG
Using PHP Version 7.1.9, MariaDB 10.1.26.
I'm submitting form data to a MySQL database, one of my values is NULL however in the database it's empty.
I have ensured that my database table is set to;
allow null = yes
default - null
My code is below (please ignore any security vulnerabilities this is simplified code);
$id = $_POST['id '];
$name = $_POST['name'] ? $_POST['name'] : NULL ;
$sql = "INSERT INTO staff (id, name) VALUES ('".$id."', '".$name."')
// query runs and inserts successfully
When I var_dump($name) I get NULL, although the name value in my database is empty (i.e. not null)
Any ideas what i'm doing wrong?
Edit
The original poster said
My code is below (please ignore any security vulnerabilities this is simplified code)
I interpret that as "I know about SQL injection and I am taking measures to prevent it in my code. I've simplified my post to make it easier to get an answer."
My response below is following their format. That's why I did not use PDO, mysqli, prepared statements/escape measures in my post. If I were personally writing code to insert data into a database, I would make sure my data is sanitized and I would use an ORM like Doctrine (which is a wrapper for PDO) to interact directly with the database.
My Answer
Referencing the code in the original post:
$id = $_POST['id '];
$name = $_POST['name'] ? $_POST['name'] : NULL ;
$sql = "INSERT INTO staff (id, name) VALUES ('".$id."', '".$name."')
// query runs and inserts successfully
Your query is behaving the way you've written your code. If you echo/print a PHP variable to standard output after it has been set to NULL you won't see a value at all. Null is the absence of value. Since you've wrapped the absence of value (no value, null) in single quotes, you're telling MySQL that you want to insert an empty string into the name column.
I would rewrite the code as follows:
$id = $_POST['id '];
$name = $_POST['name'] ? "'$_POST[name]'" : 'NULL';
$sql = "INSERT INTO staff (id, name) VALUES ('$id', $name)";
Notice how I put NULL in a string for the name variable. When I include the name variable in the query I don't wrap it with quotes. This is the proper way to explicitly add a null value to a column in MySQL.
PHP's double quotes allows variable interpolation. This means you don't have to break your strings down into individual parts and concatenate string values together. This makes the code cleaner and easier to read.
First, you're obviously not using prepared statements. I strongly advice you to use prepared statements in the name of security and stability.
Then, on to the issue at hand. The database doesn't know what a PHP null is and will only see an empty string to be inserted in your code.
"" . null . "" === ""
Keeping your (very dangerous and vulnerable) example code, and modifing the place where you add the "quotes" around the to be inserted string. If the name is null just insert NULL without quotes around it. the databse server will interpret that as having to inserta null value
$name = $_POST['name'] ? "'".$_POST['name']."'" : 'NULL';
$sql = "INSERT INTO staff (id, name) VALUES ('".$id."', ".$name.")";
Now really, investigate how to do prepared queries to prevent SQL injections
or at least use mysqli_real_escape_string or something equivalent.
this is the more secure version, using PDO.
$sql = "INSERT INTO staff (id,name) VALUES (:id,:name)";
$stmt= $dpo->prepare($sql);
$stmnt->bindParam(':id', $id, PDO::PARAM_INT);
if(!$POST['name']) {
$stmnt->bindParam(':name', null, PDO::PARAM_NULL);
}
else {
$stmnt->bindParam(':name', $POST['name'], PDO::PARAM_STR);
}
$stmt->execute();
I would instead use PDO prepared statements. That should set the value to NULL instead of an empty string. Because you are wrapping '".$name"' it is making the query '') - i.e an empty string.
I'd do like this:
$id = $_POST['id '];
if(isset($_POST['name'])){
$sql = "INSERT INTO staff (id, name) VALUES ('".$id."', '".$name."')
}else{
$sql = "INSERT INTO staff (id) VALUES ('".$id."')
}
discriminating the query if I receive the name from the form or not.
You should use prepared statements to pass variables (user inputs) to a mysql query. Otherwise you are widely open to SQL injections.
So I have the following code, mostly adapted from examples from php.net's SQLite3 prepare statement page.
$stmt = $db->prepare("INSERT INTO users ( accesstoken, authed, ckey, staff) VALUES (':password', 'false', ':ckey' ,'true');");
$stmt->bindValue(':ckey',$_POST["ckey"]);
$hashedpw = password_hash($veri_password, PASSWORD_DEFAULT);
$stmt->bindValue(':password',$hashedpw);
$result = $stmt->execute();
I figured it would work, however when I review the database manually I see this:
:ckey, :password, false, false as the row that was inserted.
I can't seem to fix it either, I tried removing the quotes around it and threw an error instead. I swapped the quote types and either got an undefined column or some other error.
Here is a snip of the code right before that:
$stmt = $db->prepare("select * from `users` WHERE ckey = :ckey");
$stmt->bindValue(":ckey",$_POST["ckey"]);
$result = $stmt->execute();
That works just fine however it is a select query rather than a insert and it only has one value to bind. I've looked at about least 10-15 related questions and still can't solve it, one suggested using ' instead of " but that didn't solve it another suggested using ? instead of :ckey and that left me with question marks inside of my database (how fitting) and I still have not been able to resolve it.
The issue is with the quotes change
$stmt = $db->prepare("INSERT INTO users ( accesstoken, authed, ckey, staff) VALUES (':password', 'false', ':ckey' ,'true');");
to
$stmt = $db->prepare("INSERT INTO `users` ( accesstoken, authed, ckey, staff) VALUES (:password, 0, :ckey ,1)");
Credit to Cfreak
I have a web program which allows the administrator to update a user's information... With that being said, I only want columns updated which have indeed been 'updated'...
I have done quite a bit of researching on this and it seems that all methods use outdated querys, which do not make use of the prepare statement to escape input...
Can someone please help me with the statement?
Essentially in psuedocode:
Update FIRSTNAME if $editedUserdata['firstname'] != FIRSTNAME, LASTNAME if $editedUserData['lastname'] != LASTNAME ...etc...
Here is what I have for the post code...
$password = sha1($password);
$editedUserData = array(
'firstname' => $firstname,
'lastname' => $lastname,
'username' => $username,
'password' => $password,
'cellphone' => $cellphone,
'security_level' => $seclvl,
'email' => $email,
'direct_phone' => $direct,
'ext_num' => $extension,
'is_active' => $userflag
);
Then it should be something like
$query = $this->db->prepare('UPDATE FIRSTNAME if(?) IS NOT FIRSTNAME, LASTNAME if(?) IS NOT LASTNAME, USERNAME if (?) IS NOT USERNAME.... VALUES (:firstname, :lastname, :username).....'
if ($query -> execute($editedUserData)) {
more code....
According to MySQL documentation -
Ref: (http://dev.mysql.com/doc/refman/5.0/en/update.html)
"If you set a column to the value it currently has,
MySQL notices this and does not update it."
Maybe I'm not understanding the problem which you're trying to solve but you don't have to test if field value did change.
If field value is "A" and you put there an "A" it will remain the same otherwise, if you put there a "B" it will be updated as expected
The prepared statement would be something like
$stmt = $dbh->prepare("
UPDATE table_name
SET
field1 = :value1,
field2 = :value2
WHERE
field0 = :key
");
$stmt->bindParam(':value1', $value1, PDO::PARAM_STR);
$stmt->bindParam(':value2', $value2, PDO::PARAM_STR);
$stmt->bindParam(':key', $key, PDO::PARAM_INT);
$stmt->execute()
Run a single statement to update the row.
Firstly, what's the unique identifier for a row in the users table, is there a unique userid or username? You'll want a WHERE clause on the UPDATE statement so that only that row will be updated.
The normative pattern for an UPDATE statement to update several columns in a single row is like this:
UPDATE users
SET col2 = 'value'
, col3 = 'another value'
, col4 = 'fi'
WHERE idcol = idvalue ;
To use a prepared statement with PDO, the SQL text could look something like this, if you use named placeholders:
UPDATE users
SET col2 = :col2_value
, col3 = :col3_value
, col4 = :col4_value
WHERE idcol = :id_value
Or this, if you use positional notation for the placeholders:
UPDATE users
SET col2 = ?
, col3 = ?
, col4 = ?
WHERE idcol = ?
(My personal preference is to use the named placeholders, rather than positional, but either will work.)
This is how I'd do it, run the prepare, then the bind_param, and then the execute.
$sql = "UPDATE users
SET col2 = :col2_value
, col3 = :col3_value
, col4 = :col4_value
WHERE idcol = :id_value ";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':col2_value', $col2_val, PDO::PARAM_STR);
$stmt->bindParam(':col3_value', $col3_val, PDO::PARAM_STR);
$stmt->bindParam(':col4_value', $col4_val, PDO::PARAM_STR);
$stmt->bindParam(':id_value' , $id_val, PDO::PARAM_STR);
$stmt->execute();
To do something different, to dynamically create the SQL text, and adjust the bindParam calls, that would add unnecessary complexity to the code. There's no performance advantage to doing that; when that UPDATE statement runs, MySQL has to lock the row, store a new copy of the row. It doesn't really save anything (aside from a few bytes of data transfer) to avoid sending a column value that hasn't changed.
If you realy want to use cases, read this.
There is no reason to do it in your case, as stated from #spencer7593 in the comments:
That's WAY more overhead... roundtrips to the database, parsing the
statement, developing an execution plan, executing the statement,
obtaining locks, returning a status, client checking the status, etc.
That's just seems an all-around inefficient approach.
I assume that any RDBMS is smart enough, to notice, that Caches etc should not be recalculated (if nothing changes), if that is the problem.
my sql insert query is not working in my program. I have print the query and then copy paste that code in mysql tab of the phpmyadmin, then it works perfectly. Any body please help me.
if ($_FILES["thumbnailimage"]["size"]>0 )
{
$thumbnailkey = generateUniqueKey($tbl_uploads,"upload_key",12);
$fkey = generateUniqueKey($tbl_uploads,"file_key",24);
$folderkey = generateUniqueKey($tbl_uploads,"folderkey",28);
$fname = substr($_FILES['thumbnailimage']['name'],0,strpos($_FILES['thumbnailimage']['name'],"."));
$ext = getExtension($_FILES['thumbnailimage']['name']);
$insertnewupload = "INSERT INTO ".$tbl_uploads." (upload_key,file_key,file_name,file_type,ext,folderkey,user_id,status,pkey) VALUES ";
$insertnewupload.="('".$thumbnailkey."','".$fkey."','".$fname."','1','".$ext."','".$folderkey."','".$_SESSION['user_id']."','0','".$productkey."')";
echo "<br>1=>".$insertnewupload;
// $db->connect();
$exec_insertnewitem = mysql_query($insertnewupload);
This is the printed out put
INSERT INTO tbl_uploads (upload_key,file_key,file_name,file_type,ext,folderkey,user_id,status,pkey) VALUES ('f958c38e5c31','9b6bd5118ec4a8456bcc46df','sunil','1','jpg','1c1a536fbdde4f24a219ada4c1c9','7','0','3b593aff92ce')
You are quoting numeric values, you should aim for. I've added backticks around the field names also (I can't recall if 'status' is reserved)
INSERT INTO `tbl_uploads` (
`upload_key`,
`file_key`,
`file_name`,
`file_type`,
`ext`,
`folderkey`,
`user_id`,
`status`,
`pkey`
)
VALUES (
'f958c38e5c31',
'9b6bd5118ec4a8456bcc46df',
'sunil',
'1',
'jpg',
'1c1a536fbdde4f24a219ada4c1c9',
7,
0,
'3b593aff92ce'
)
So the following replacement for the line specifying values will suffice
$insertnewupload = "INSERT INTO `".$tbl_uploads."` (`upload_key`,`file_key`,`file_name`,`file_type`,`ext`,`folderkey`,`user_id`,`status`,`pkey`) VALUES ";
$insertnewupload.="('".$thumbnailkey."','".$fkey."','".$fname."','1','".$ext."','".$folderkey."',".$_SESSION['user_id'].",0,'".$productkey."')";
As an addition, there'll probably be a few comments stating you should be using mysqli_ functions or PDO instead of mysql_. At present you're potentially vulnerable to SQL injection with such a method of making a query.
Could be severy reasons... did you check that you connect to the correct database ? Maybe add the database name before "tbl_uploads", e.g. "mybase.tbl_uploads"
Always make practice to write mysql query like this.
$query = "INSERT INTO tablename (`upload_key`,`file_key`,`file_name`,`file_type`,`ext`,`folderkey`,`user_id`,`status,pkey`) VALUES ('f958c38e5c31','9b6bd5118ec4a8456bcc46df','sunil','1','jpg','1c1a536fbdde4f24a219ada4c1c9','7','0','3b593aff92ce')";
$check = mysql_query($query);
check if var_dump($check);returns true or false..