I create a simple site for findID when I write the email.
HTML CODE
<form action="test.php" method="post">
<input type="text" name="user_id_test" id="user_id_test">
<br>
<br>
<input type="submit" value="Find ID">
</form>
PHP CODE
<?php
//include database
include 'include/db.inc';
$emailUser = $_POST['user_id_test'];
$findNewID = mysqli_query($connessione,"SELECT user_id FROM user_tmplt WHERE user_mail = $emailUser");
if ($findNewID != "") {
var_dump($findNewID);
echo "$findNewID";
} else {
echo "Errore: " . $findNewID . "<br>" . mysqli_error($connessione) ."<br>";
}
mysqli_error($connessione);
?>
I try to find ID for email: dfaf#dfaf.fa (it is in my database with ID 13) and I've this error You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '#dfaf.fa' at line 1
You should use prepared statements to avoid this kind of errors and to avoid SQL Inyection:
$stmt = mysqli_prepare($connessione,"SELECT user_id FROM user_tmplt WHERE user_mail = ?");
if ( !$stmt ) { someErrorHandlingHere(); }
mysqli_stmt_bind_param($stmt, "s", $emailUser);
// same here: mysqli_stmt_bind_param may fail -> returns false
mysqli_stmt_execute($stmt);
// same here: mysqli_stmt_execute may fail -> returns false
mysqli_stmt_bind_result($stmt, $userId);
// and so on and on: error handling
mysqli_stmt_fetch($stmt);
echo "The user id es: {$userId}";
It is about passing email as integer, pass it as string..
mysqli_query($connessione,"SELECT user_id FROM user_tmplt WHERE user_mail = $emailUser");
to
mysqli_query($connessione,"SELECT user_id FROM user_tmplt WHERE user_mail = '".$emailUser."' ");
This would work but it is not safe to pass parameters within the queries directly, make the sql injection safe first...
Your immediate problem (as has already been answered) is/was that you didn't mark the string parameter (the email-address) as a string literal within the SQL query. The MySQL server therefore interpreted it as an identifier (like a database/table/field name). And since # is an invalid character within an identifier the server reported the error you've posted, see http://dev.mysql.com/doc/refman/5.0/en/identifier-qualifiers.html.
To mark a string literal within a query you put it (by default) in single-quotes:
SELECT x FROM table WHERE y=z // compares the value of the field y with the value of the field z in each record
SELECT x FROM table WHERE y='z' // compares the value of the field y with the string literal 'z' <- that's what you want
Anyway, here's an example (that addresses some other issues) using PDO instead of mysqli_*:
<?php
define('POST_FIELD_MAIL', 'user_id_test');
if ( !isset($_POST[POST_FIELD_MAIL]) ) { // maybe the resource (...script) has been requested without that parameter?
trigger_error('missing parameter '.POST_FIELD_MAIL, E_USER_ERROR);
}
else {
/** that's you part you probably want in inc/db.php */
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // that's why there's not error handling code after each and every call to a pdo function/method
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
/* ***** */
try {
$stmt = $pdo->prepare('SELECT user_id FROM user_tmplt WHERE user_mail=?'); // avoiding sql injections
$stmt->execute( array($_POST[POST_FIELD_MAIL]) );
$row = $stmt->fetch();
if (!$row) {
echo '<div>no such record</div>';
}
else {
echo '<div>user_id=', htmlspecialchars($row['user_id']), '</div>';
}
}
catch(PDOException $pex) {
yourErrorHandler();
}
}
This query is exposed to sql injections. Always sanitize or escape special characters in a string before using in a where clause. In this case wrap $email with quotes.
ie. change
$email to '".$emailUser."'
In the where clause.
Related
I am some confused because some people write PHP code like this for upload data.
But my instructor used $query and $link always to upload and retrieve data from SQL.
<?php
include 'connection.php';
function reg_in() {
if (isset($_POST['submit'])) {
$name = $_POST['name'];
$email = $_POST['email'];
$mob = $_POST['mobile'];
$check_in = $_POST['in'];
$check_out = $_POST['out'];
$rm = $_POST['room'];
$room_type = $_POST['type'];
// Problem start from here
if (mysql_query("INSERT INTO `book` (`name`,`email`,`mobile_no`,`check_in`,`check_out`,`room`,`room_type`) VALUES ('$name','$email','$mob','$check_in','$check_out','$rm','$room_type')")) {
header('Location: C:/wamp/www/project/payment.html');
} else {
echo mysql_error();
}
}
}
if (isset($_POST['submit'])) {
reg_in();
//echo ' succesfully inserted';
} else {
echo 'Not book';
}
MySQL (by my instructor):-
<?php
$link = mysqli_connect("myserver.com", "test", "sunil7117", "test");
if (mysqli_connect_error()) {
die("please give correct permision");
}
//Is both are same!
//$query="INSERT INTO user(email,password) VALUES ('shivanandcpr25#gmail.com','sunil7117')";
$query = "UPDATE user SET email='test#gmail.com' WHERE email='abc#gmail.com' LIMIT 1";
echo mysqli_query($link, $query);
echo "<br>";
$query = "SELECT * FROM user";
if ($result = mysqli_query($link, $query)) {
echo "welcome to database<br>";
$row = mysqli_fetch_array($result);
echo "my E-mail id is <strong> ".$row[1]. "</strong> and passoword is <strong>".$row[2]."</strong>";
}
Neither!
Your first example uses function which has been removed from PHP years ago. mysql_query() does not exist and should not be used anymore. The reason why it was removed is that you should use prepared statements instead. They are provided by either mysqli or PDO extensions.
Your second example is better, but it is way too messy.
You should not echo mysqli_query. There's nothing useful to be printed out from this function.
Get into a habit of using prepared statements all the time and use placeholders for variable data. As of now your queries are constant, but using prepared statements is still a good practice in case you need to add a parameter later on.
Avoid using functions like mysqli_fetch_array(). Iterating the result option one by one is messy and rarely useful.
Never check the return value of mysqli calls. It's pointless. Enable error reporting instead. See How to get the error message in MySQLi?
Always set the correct charset. It should be utf8mb4 99% of the time.
The SQL query can be saved in a separate variable, but what's the point? You are only going to pass it as an argument to the query function. There's no need to use an intermediate variable.
Don't use mysqli. You should use PDO instead. If you have to use mysqli, then create a simple wrapper function or class for this purpose and execute your generic function instead of messing around with mysqli functions.
Here is an example of how I would do it. First I enable error reporting for mysqli, I open the connection and set the charset. Then I declare a function which takes 3 parameters and returns an array. First parameter is your database connection you have just opened. Second is your SQL query with placeholders if there are any. Third is optional and it is an array of values to be bound to the placeholders as parameters. This function works for all kind of SQL queries. The rest of the code becomes really simple.
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = new mysqli("myserver.com", "test", "sunil7117", "test");
$link->set_charset('utf8mb4'); // always set the charset
/**
* Executes an SQL query on the database.
*
* #param \mysqli $mysqli
* #param string $query e.g. SELECT * FROM users WHERE username=?
* #param array $params An array of parameters to be bound in the given order to the placeholders in SQL
* #return array
*/
function prepared_query(\mysqli $mysqli, string $query, array $params = []): array {
$stmt = $mysqli->prepare($query);
if ($params) {
$stmt->bind_param(str_repeat("s", count($params)), ...$params);
}
$stmt->execute();
if ($result = $stmt->get_result()) {
return $result->fetch_all(MYSQLI_BOTH);
}
return null;
}
prepared_query($link, "UPDATE user SET email='test#gmail.com' WHERE email='abc#gmail.com' LIMIT 1");
echo "<br>";
$result = prepared_query($link, "SELECT * FROM user");
echo "welcome to database<br>";
if ($result) {
$row = $result[0];
echo "my E-mail id is <strong> ".$row[1]. "</strong> and passoword is <strong>".$row[2]."</strong>";
}
I am creating a form where a user tick on the checkbox then 1 will be stored in that column on MySQL table. If the user does not tick then 0 will be stored on that field in the database. One checkbox for one column. My HTML code is :
Type ;<label class="checkbox-inline"><input type="checkbox" name="mentor" value="1" >Mentor</label>
<label class="checkbox-inline"><input type="checkbox" name="core" value="1" >Core</label>
and my PHP code is
$name = mysqli_real_escape_string($DBcon, $_POST['name']);
$mentor;
if (isset ($_POST['mentor']) == "1")
{
$mentor = 1;
}
else
{
$mentor = 0;
}
$core;
if (isset ($_POST['core']) == "1")
{
$core =1;
}
else
{
$core =0;
}
$insert = $DBcon->query("INSERT into contributor(name,mentor,core) VALUES('$name','$mentor','$core')");
But I am getting "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '????\"Exif\0\0MM\0*\0\0\0\0\0\0\0\0\0?\0\0\0\0\0\0?\0\0\0\0\0\0\' at line 1"
this error when I press submit button
PHP uses single quotes to mean literals. That is, the $varname won't be interpreted to mean 0, it will mean $varname. Remove the single quotes and it should work.
"INSERT into contributor(name,mentor,core) VALUES($name,$mentor,$core)"
or
'INSERT into contributor(name,mentor,core) VALUES('.$name.','.$mentor.','.$core.')'
If this is for work, please read up on PHP PDO and the security it adds.
# as #War10ck mentioned, you're mixing Procedural-style with object oriented
$name = $DBCon->real_escape_string($_POST['name']);
# You were comparing a boolean (isset) with "1". Since it's a checkbox, you an do this (or $_POST['mentor'] == "1" since that's your value on the form..)
$mentor = isset($_POST['mentor']) ? 1 : 0;
$core = isset($_POST['core']) ? 1 : 0;
# remove single quotes from your $paramaters
$insert = $DBcon->query("INSERT into contributor(name,mentor,core) VALUES($name, $mentor, $core)");
Note you should use PDO prepared statements as others have mentioned
$stmt = $DBcon->prepare("INSERT INTO contributor(name, mentor, core) VALUES(?,?,?)");
$stmt->bind_param('sssd', $name, $mentor, $core);
$insert = $stmt->execute();
You appear to be mixing procedural and object-oriented mysqli_* statements in your code. You should choose one or the other. Change your line here:
mysqli_real_escape_string($DBcon, $_POST['name']);
to this instead:
$DBCon->real_escape_string($_POST['name']);
In addition, you will also want to remove the nested single quotes in your query statement:
$insert = $DBcon->query("INSERT into contributor(name,mentor,core) VALUES($name,$mentor,$core)");
SECURITY IMPLICATIONS:
I cannot go without saying (and without echoing the comments above), that you are leaving yourself open to SQL Injection attacks using this method. To ensure that you are protected, you should consider using the prepared statements offered by both the mysqli_* and PDO_* extensions.
Consider using the following safer alternative instead of the code you used above:
$DBCon = new \PDO('{dsn}', '{user}', '{pass}', [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => FALSE
]);
$mentor = (isset($_POST['mentor']) AND intval($_POST['mentor']) === 1) ? 1 : 0;
$core = (isset($_POST['core']) AND intval($_POST['core']) === 1) ? 1 : 0;
try {
$stmt = $DBCon->prepare("INSERT INTO contributor(name,mentor,core) VALUES (:name,:mentor,:core)");
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':mentor', $mentor, PDO::PARAM_INT);
$stmt->bindParam(':core', $core, PDO::PARAM_INT);
$stmt->execute();
/* Cleanup (if you are finished interacting with the database) */
$stmt = NULL;
$DBCon = NULL;
} catch (\PDOException $e) {
/* Handle Error Here */
}
I'm trying to insert a PHP function into a foreach loop in order to generate values for each row fetched from the db for the variable $Match.
The db query itself works properly, and the function which assigns values to variable $Match works properly when I test it with hard-coded values, but when I try combining it with the rest of the code in order to use db values it stops working properly. Specifically: 1) It only runs the first IF statement; and 2) If that statement is true, it's adding the same value for every row.
I've uploaded a functional example with hard-coded values to this sandbox http://sandbox.onlinephpfunctions.com/code
Declaring values for test case:
$User_Waist = "26";
$User_Hip = "38";
$Match = Null;
$waistMatch = Null;
$hipMatch = Null;
Query database & fetchAll
$stmt = $conn - > prepare("SELECT * FROM SizeChart WHERE FIND_IN_SET($User_Waist, Waist_Measurement) > 0 OR FIND_IN_SET($User_Hip, Hip_Measurement) > 0;");
$stmt - > bindValue(':Waist_Measurement', $Waist_Measurement, PDO::PARAM_STR);
$stmt - > bindValue(':Hip_Measurement', $Hip_Measurement, PDO::PARAM_STR);
$stmt - > execute();
$rows = $stmt - > fetchAll(PDO::FETCH_ASSOC);
Loop through results
$count = 0;
foreach($rows as $row) {
$count++;
Adds value to variable $Match
if (strpos($row['Waist_Measurement'], $User_Waist) !== false) {
$waistMatch = 'waistFit';
}
if (strpos($Hip_Measurement, $User_Hip) !== false) {
$hipMatch = 'hipFit';
}
$Match = $waistMatch.', '.$hipMatch;
Display Results
echo "Size #: ".$row['Size']."; Fit Matches: ".' '.$Match."; Waist: ".$row['Waist_Measurement'], "; Hip: ".$row['Hip_Measurement'], ".<br />";
The SQL text doesn't contain bind placeholders :Waist_Measurement or :Hip_Measurement.
The bindValue calls aren't going to work, since there's no placeholder of the specified name to bind a value to.
Here's an example that uses a bind placeholder named :fum. Note that this string appears both in the SQL text and as an argument to bindValue or bindParam.
$foo = "bar";
$sql = "SELECT fee FROM fi WHERE fo = :fum ";
// ^^^^
$sth = $dbh->prepare($sql);
$sth->bindValue(":fum", $foo, PDO::PARAM_STR);
// ^^^^
$sth->execute();
FOLLOWUP
This is the SQL text in your prepare.
(I notice that there's a semicolon at the end of the SQL text, and that may be causing an error; I normally don't include a trailing semicolon in my SQL text.)
SELECT *
FROM SizeChart
WHERE FIND_IN_SET($User_Waist, Waist_Measurement) > 0
OR FIND_IN_SET($User_Hip, Hip_Measurement) > 0
But the point is that there aren't any bind placeholders in that SQL text. When you do a:
->bindValue(":Waist_Measurement",...
^^^^^^^^^^^^^^^^^^
That's essentially saying "Hey! There's a string literal ':Waist_Measurement' in the SQL text of the prepared statement", and saying "in place of that string literal, use this value...".
But the thing is, that string literal does not appear in your SQL text. There's no bind placeholder in the statement. (There's not even a placeholder of a different name, I don't see any colon characters anywhere in the SQL.)
I'm surprised that PDO isn't throwing an error. Actually, PDO probably is throwing an error, but your code is ignoring it. If your code isn't going to check the return from prepare, execute, et al. then you can have PDO do the check and throw the exception for you, by specifying an attribute on the connection.
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Also...
The inclusion of PHP variables $User_Waist and $User_Hip is a little unusual in a prepared statement. One of the benefits of prepared statements is that variables representing values can be replaced with bind placeholders.
(I'm confused by what you are trying to do, I can't tell you how to fix it.)
I am trying to convert some old PHP ODBC queries over to PDO Prepared statements and am getting an error I cannot find too much information on.
The Error is:
"[DataDirect][ODBC Sybase Wire Protocol driver][SQL Server]There is no host variable corresponding to the one specified by the PARAM datastream. This means that this variable '' was not used in the preceding DECLARE CURSOR or SQL command. (SQLExecute[3801] at ext\pdo_odbc\odbc_stmt.c:254)"
I am searching for a single row in the database using a 6 digit ID that is stored in the database as a VARCHAR but is usually a 6 digit number.
The database connection is reporting successful.
The ID passed by the query string is validated.
The prepared statement results in the above error.
The backup straight ODBC_EXEC statement in the else clause returns the data I am looking for.
//PDO Driver Connect to Sybase
try {
$pdo = new PDO("odbc:Driver={Sybase ASE ODBC Driver};NA=server,5000;Uid=username;Pwd=password;");
$pdo_status = "Sybase Connected";
} catch(PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
if((isset($_GET['id'])) AND ($_GET['id'] != "")) {
//Validate ID String
if(!preg_match("/^[A-Za-z0-9]{5,7}/",$_GET['id'])) {
$query1_id = FALSE;
echo "Invalid ID";
exit;
} else {
$query1_id = $_GET['id'];
}
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= ?");
$query1->execute(array($query1_id));
if($query1->errorCode() != 0) {
$person_data = $query1->fetch(PDO::FETCH_ASSOC);
echo "Person Data from PDO: ";
print_r($person_data);
} else {
$errors = $query1->errorInfo();
echo $errors[2];
//Try the old way to confirm data is there.
$odbc_query1 = "SELECT * FROM People WHERE PersonId='$query1_id' ";
$person_result = odbc_exec($conn,$odbc_query1) or die("Error getting Data, Query 1");
$person_data = odbc_fetch_array($person_result);
echo "Person Data from ODBC_EXEC: ";
print_r($person_data);
}
It also fails if I use:
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= :id ");
$query1->execute(array(":id"=>$query1_id));
Does anyone have experience with this error?
Edit: Sybase Manual says this about the error...
Error 3801: There is no host variable corresponding to the one specified by the PARAM datastream. This means that this variable `%.*s' was not used in the preceding DECLARE CURSOR or SQL command.
Explanation:
Adaptive Server could not perform the requested action. Check your command for missing or incorrect database objects, variable names, and/or input data.
Which is odd because my error (quoted at the top) doesn't tell me which variable has no host.
Also fails if I use...
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= :id ");
$query1->bindParam(':id',$query1_id,PDO::PARAM_STR); //Or PARAM_INT
$query1->execute();
The query works if I place the variable in the query like this...
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= '$query1_id'");
So I think it has something to do with the parameter not being bound to the placeholder but I can't figure out why.
If I can't work this out I'll have to revert to building my query as a string and hoping my input validation is bullet proof.
Your problem seems to be with the default data type PHP assigns to variables in the placeholders. The SQL Statement is looking for a number but PHP is interpreting it as something else. You can prevent this using quotes around the placeholder variable. Notice that in the statements that work you have apostrophes ('') around the value that PHP sees:
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= '$query1_id'");
Try this when using the placeholder it should be the same:
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= ':id'");
Hello I've got this query to get users by email, which is an unique field in the db.
However, when i want to get the data on it, it simply returns null.
Here's the code
public function getUserByEmail($email)
{
$statement = "SELECT id_user,nome,email,permissao,activo FROM sys_users
WHERE email=$email";
try
{
$sth = $this->db->query($statement);
$sth->setFetchMode(PDO::FETCH_OBJ);
$rcs_users = $sth->fetchAll();
return $rcs_users;
}
catch(PDOException $e)
{
"DB Error".$e->getMessage();
}
}
And the respective function call
$user_rcs = $user->getUserByEmail($email);
var_dump($user_rcs); //returns null
$_SESSION['email'] = $email;
$_SESSION['user'] = $user_rcs->nome;
$_SESSION['permissao'] = $user_rcs->permissao;
And then I get this error
Notice: Trying to get property of non-object in C:\xampp\htdocs\inacesso\admin\modules\auth\authhandler.php on line 24
Glad if you could help me!
Strings in SQL have to be quoted, so unless $email arrives in the function with ' and ' around it, the SQL will error.
But you shouldn't be building SQL by mashing together PHP strings anyway. Use PDO or mysqli_* with bound parameters (and prepared statements) and that will take care of quoting (and escaping) for you.
First off, seriously have a look at PDO.
Secondly I would imagine the email column is a string. As such, you'll need to surround $email with quotes in your query (after having sanitized it vigorously of course...)
WHERE email='$email'
PDO version:
$pdo = new PDO(...);
$query = $pdo->prepare('SELECT id_user,nome,email,permissao,activo '.
'FROM sys_users '.
'WHERE email = ?');
$result = $query->execute(array($email));