I am fairly new to PHP and have been following the Lynda.com tutorials (although they still use mysql in stead of mysqli or PDO).
I'm having problems with using the data I get from my queries.
I'll use my login page as example, leaving out the connect to db part:
$login_username = trim(htmlspecialchars($_POST['username']));
$password = trim(htmlspecialchars($_POST['password'])); // from login form
$stmt = $db->prepare("SELECT * FROM users
WHERE username = :login_username");
$stmt->bindParam(':login_username', $login_username);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() > 0 && $result = password_verify($password,$result['hashed_password'])) {
$_SESSION['logged_in_id'] = $result['id'];
$_SESSION['logged_in_username'] = $login_username; //this was the only way I could pass the username as I could not get it from $result['username']
$_SESSION['first_name'] = $result['first_name'];
$_SESSION['last_name'] = $result['last_name'];
Nothing gets passed to the session and there are no errors. I also can't echo out the value of $result. If I just try to echo $result, then I just get the value 1
Please help!
Your problem is:
... && $result = password_verify($password,$result['hashed_password'])
Note that $result is an array that contains the row that you just fetched and you are assigning it a new value here; you are overwriting your $result variable so all assignments afterwards will fail.
You probably want something like:
... && password_verify($password,$result['hashed_password'])
Also note that you should not rely on the rowCount() as that is not necessarily what you expect for a SELECT statement.
As you are fetching a row already, you can simply do:
if ($result && password_verify($password,$result['hashed_password']))
If there is no result, the second condition will never be checked so it will not lead to warnings or errors.
Related
I'm trying to take a query string param such as ?table=products and have mysql return all the rows for the "products" table in mysql. I tried running the code below in my browser, but I just get a blank white page. I know the mysql server/username/pass information is correct, I've tested the query in mysql and it works fine.
I guess I have two question:
What am I doing wrong?
How come I can't see any error messages when php has an issue?
e.g. code:
<?php
// Get query string parameter value
$keys = array_keys($_GET);
$key = $keys[0];
$value = $_GET[$key];
// Setup connection to mysql database
$serverName = "localhost";
$username = "root";
$password = "password";
$dbname = "webserver";
$conn = new mysqli($serverName, $username, $password, $dbname);
// SQL query
$sql = "SELECT * FROM $value";
$result = $conn->query($sql);
// Print results
echo $result;
?>
Follow the instuctions on below link to enable php.ini errors
How do I get PHP errors to display?
VULNERABLE IMPLEMENTATION WARNING
The above comments clearly mention the side effects of this implementation.
Since knowing the actual bug is a developer's right! Continue reading the answer keeping the safety of software and its users in mind.
You are trying to print $result which is not valid since its an object.
You can do the following instead:
$response = array();
$sql = "SELECT * FROM $value";
$result = $conn->query($sql);
// Print results
if ($result) {
while($row = $result->fetch_array(MYSQL_ASSOC)) {
$response[] = $row;
}
}
echo json_encode($response);
What am I doing wrong?
Sadly, pretty much everything.
// Get query string parameter value
$keys = array_keys($_GET);
$key = $keys[0];
$value = $_GET[$key];
You are dereferencing a named value based on its position. And its totally unnecessary. Consider:
$value=$_GET['table'];
...
$conn = new mysqli($serverName, $username, $password, $dbname);
Where is your error checking to see if $conn was initialized?
$result = $conn->query($sql);
again, no error checking.
echo $result;
$result here is a mysqli_result object. You need to call some methods on it to get the data out.
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
var_export($row);
}
How come I can't see any error messages when php has an issue?
Have you tested that the default handlers produce output in your browser? You're not overriding the config in php.ini in the code you've shown us. Did you check your logs?
ini_set('diplay_error', 1);
error_reporting(E_ALL);
I just get a blank white page
Would it be so hard to put
print "finished";
at the end of the code? Then you'd at least know if the code executed.
The main issue you have right now is you need to get the results
while ($row = $result->fetch_assoc()) {
//do something with row
}
See ( for mysqli->query method )
http://php.net/manual/en/mysqli.query.php
false on failure and mysqli_query() will return a mysqli_result object on success
See ( for the result objects definition )
http://php.net/manual/en/class.mysqli-result.php
Now as others mentioned I would never just concatenate user data into your query. Imagine a hacker knows the name of a valid table, not hard considering your sending it through the request. All they would have to do is send a value like this:
$value = 'real_table; DROP DATABASE';
And your query becomes.
$sql = "SELECT * FROM real_table; DROP DATABASE";
I won't say that this would actually work as there are ( maybe ) some restrictions on running multiple queries in a single request,user permissions etc... That might save your bacon, but I certainly wouldn't risk it.
So you have 2 choices.
Use a white list of tables
Query the DB for the schema
The first one is easy to do, make a list of tables
$whitelist = [
'table1',
'table2'
];
Then compare your user input
$safeTable = false;
if( false !== ($index = array_search($table, $whitelist))) {
$safeTable = $whitelist[$index];
}else{
//log error and
exit();
}
// SQL query
$sql = "SELECT * FROM $safeTable";
$result = $conn->query($sql);
For the second one,
$schema = $conn->query('SELECT `TABLE_NAME` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` LIKE "database"');
$whitelist = [];
while ($row = $result->fetch_assoc()) {
$whitelist[] = $row['TABLE_NAME'];
}
$safeTable = false;
if( false !== ($index = array_search($table, $whitelist))) {
$safeTable = $whitelist[$index];
}else{
//log error and
exit();
}
// SQL query
$sql = "SELECT * FROM $safeTable";
$result = $conn->query($sql);
This will return a list of all the tables in that database, from which you can build an array and then compare. The nice thing about the second one is that if you add a table then you don't have to change the code, which may or may not be a good thing. You have to have a user with permission to read from information_schema database. And you have to do an additional query.
-note- I am not directly using the users input, I'm using their input to find my data. It's less prone to breaking when there is a coder error. Consider this:
///all my codes are broken;
--if(!in_array($_GET['table'], $whitelist))) {
-- //log error and
-- exit();
--}
// SQL query
$sql = "SELECT * FROM {$_GET['table']}";
$result = $conn->query($sql);
Against this:
$safeTable = false;
// all my codes are broken
-- if( false !== ($index = array_search($_GET['table'], $whitelist))) {
-- $safeTable = $whitelist[$index];
-- }else{
-- //log error and
-- exit();
-- }
// SQL query
$sql = "SELECT * FROM $safeTable"; //$safeTable is undefined or false;
$result = $conn->query($sql);
Were using our code for inclusion, instead of exclusion. So if it breaks, it's never included. The other way, if it breaks it's never excluded. Which is not a situation we want to be even remotely possible.
I hope that helps you understand some of the pitfalls. The #1 rule for SQL (or anything on the web), is Never Trust the User. Never put their data into your SQL.
I have code
$email = "jb#tlb.com";
$row = mysql_query("SELECT EXISTS(SELECT email FROM accounts WHERE email='".$email."');");
echo $row[0];
However, nothing is echoed.
This is strange because something is being returned because, later in the code I have a function that is CALLED:
if ( $row[0] == 0 ) { echo "Email address is available<br>";};
However: this is strange because when i put the SAME CODE into mySQL database command prompt:
It clearly returns 1 or TRUE.
The mysql_query is returning 0 when the same exact command in mysql command prompt returns 1. Further: I am unable to echo the result for debugging purposes.
EDIT: Please not, the regular mySQL command is returning this and ONLY this:
EDIT: Here is there entire database:
MySQL query gives you a ressource. After that you have to fetch the data with mysql_fetch_assoc or mysql_fetch_row or something else for example. But its better to use prepared statements with mysqli or PDO to get more security.
$email = "jb#tlb.com";
$res = mysql_query("SELECT EXISTS(SELECT email FROM accounts WHERE email='".myql_real_escape_string($email)."')");
$row = mysql_fetch_assoc($res);
echo $row['email'];
Answer to your question:
$email = "jb#tlb.com";
$res = mysql_query("SELECT email FROM accounts WHERE email='".mysql_real_escape_string($email)."')");
$numRows = mysql_num_rows($res);
if($rowRows > 0) {
echo "Record Available";
}
You need to actually retrieve the result set from the query. mysql_query() just returns a resource handle for a successful select. You then need to fetch the results using mysql_fetch_* class of functions. Alternatively, you can use mysql_num_rows() to determine the number of rows returned in the result set.
In this case it is really senseless to wrap your actual query into a subquery. Just run your select and determine the number of rows:
$email = "jb#tlb.com";
$result = mysql_query("SELECT email FROM accounts WHERE email='".$email . "'");
if($result) {
$row_count = mysql_num_rows($result);
echo $row_count;
}
Also, you should not be writing new code using mysql_* functions, as these are deprecated. I would suggest mysqli or PDO extensions instead.
You need to do something like
while ($r = mysql_fetch_assoc($row))
{
echo $r[0];
}
after that code.
Let me know.
$q = $db->query(" SELECT username FROM users WHERE userident = '1' ");
echo $q; //error
print_r $q; //prints the query information (SELECT ... etc)
How do I go about getting the specific value of the element I am querying? Say the element under column username and where userident equals '1' contains the value "Patrick"; how do I initialize this string into a variable?
//same query as above
$user = $q;
echo $user; //prints "Patrick"
Sorry if this is something so rudimentary and mundane, but I've never done this outside of a foreach() loop. I'd normally iterate through rows to print specific details. The below works, but the foreach() is unnecessary as far as I understand.
foreach($q as $p) {
$user = $p["username"];
}
echo $print; //this correctly prints "Patrick"
Surely there's a method I missed somewhere?
Using the query method pretty much defeats the purpose of using prepared statements. Plus, I believe for what you're looking for, it isn't quite right.
<?php
if (!isset($_POST['id'])) {
exit;
}
$userId = $_POST['id'];
$db = new PDO(/* Stuff */);
$sql = '
SELECT username
FROM users
WHERE id = :id';
// Get a prepared statement object.
$statement = $db->prepare($sql);
// Bind a parameter to the SQL code.
$statement->bindParam(':id', $userId, PDO::PARAM_INT);
// Actually get the result.
$result = $statement->fetch(PDO::FETCH_ASSOC);
// Close the connection.
$statement->closeCursor();
// Print the result.
print_r($result);
Alternately you can use $statement->fetchAll() to gather more than one result.
Edit: I didn't actually run this code, so you might have to tinker with it to get it working right.
im trying to use mysqli with bind_result but all i get is null values. My $stmt
number of rows is greater than 0 so i do have some data in it.
I dont realy understand what value should come into bind_result
I have read at the manual http://php.net/manual/en/mysqli-stmt.bind-result.php
And they dont explain what should i put in the bind_result.
Should i put there the column names? if yes, as strings? how do i get my wanted values?
Here is my code thanks for helping:
$sql = "SELECT * FROM comments WHERE workout_name = ? AND user = ?";
$stmt = $mysqli->prepare($sql) or trigger_error($mysqli->error."[$sql]");
$stmt->bind_param('ss', $workout_name, $user);
$workout_name = "rytg";
$user = "tomer";
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($comment, $commented_user);
if($stmt->num_rows > 0)
{
$response["workouts"] = array();
while ($stmt->fetch())
{
// temp user array
$workouts = array();
$workouts["comment"] = $comment;
$workouts["user"] = $commented_user;
// push single product into final response array
array_push($response["workouts"], $workouts);
}
}
Your only problem is insufficient error reporting
error_reporting(E_ALL);
ini_set('display_errors',1);
Just add these lines at the top of your code and you will be immediately informed of the exact problem with your code.
Note that on the production server you have to turn displaying errors off and logging on
I don't have a working PHP installation next to me at the moment, so I can't verify it, but I believe you might have to bind both parameters and result before you execute the query, like so:
$workout_name = "rytg";
$user = "tomer";
$stmt = $mysqli->prepare($sql) or trigger_error($mysqli->error."[$sql]");
$stmt->bind_param('ss', $workout_name, $user);
$stmt->bind_result($comment, $commented_user);
$stmt->execute();
I'm not too sure about store_result() either. I don't recall having to use it while retrieving the results, so you might want to try running your code without it and see what happens.
Basically I am attempting to make a login. I understand a very small amount of php, but everytime I try to log in it works. So it is not following my if statement below. So I would like to see if anyone can help me print the $results as not a string. Everytime I echo it, it says error can not print as string. Which makes me think its an array, can someone help ? =(
<?php
include('include/dbConnection.php');
if (isset($_REQUEST['attempt']))
{
//variables
$user = $_POST['user'];
$password = sha1($_POST['password']);
//SQL statement
$query = "SELECT COUNT(user)
FROM users
WHERE user = '$user'
AND password = '$password'";
//Execute prepared MySQL statement
$results = mysqli_query($dbc,$query) or die('Error querying database');
/* Here is where I want to print $results
if ($results = 1)
{
session_start();
$_SESSION['$user'];
header('location: home.php');
}
else
{
echo $results + 'Incorrect Username or Password';
}
*/
//Close dbConnect
mysqli_close($dbc);
}
?>
Use var_dump($output) or print_r($output) to display contents of an array.
You have to use this:
echo "<pre>";
print_r($results);
echo "</pre>";
It first echoes so that the print of the array is formatted properly. If you don't do this it will all be on one line.
Hope this helped! :D
mysql_query() returns a statement result handle, NOT the data you've requested in the query. You first have to fetch a row of data to get access to the actual query data:
$result = mysqli_query(...);
$row = mysqli_fetch_row($result);
$count = $row[0];
mysqli_query function returns false for unsuccessful queries. it returns a MySQLi_Result object for select or show queries and true for insert and update queries.
if your query fails for some reason your script will die because of or die statement and never returns false.
if ($results = 1)
statement assigns 1 to your result variable. when your script runs, your code enters this if block. because you control the assignment statement whether it is done or not.
your query is a select, mysqli_query function returns MySQLi_Result object.