I want to show the variable "points" which belongs to a certain username,.
This is a part of my login2.php file:
if(isset($_SESSION['username'])){
$username=$_SESSION['username'];
$points = $mysqli->query("SELECT points FROM account_information WHERE username = '".$username."'");
}
I dont know how to show the points now. I know that the outcome of $points is not the amount of points that belongs to a username. I actually want to know how to do this and what the outcome is of the $points. How can I show the actual result of the query I am running?(which would be the amount of points stored in my database So of course if you would run this query in mysql then the outcome will be :"Amount of points", but in this situation I dont know how to show the amount of points actually.
while ($row = mysqli_fetch_assoc($points)) {
echo $row['points'];
}
Just put the results into an array called $row then access the parts of the array with $row['points'].
The "points" value is in, after executing AND FETCHING the sql/results.
Fetch row
http://www.php.net/manual/de/mysqli-result.fetch-row.php
$sql_result = $mysqli->query("SELECT points FROM account_information WHERE username = '".$username."'");
while ($data_row = mysqli_fetch_assoc($points)) {
print 'Your score is: '.$data_row['points'];
}
OP already has accepted an answer but they both arent good imo. NDM said it, take a look into the docs it's all well written there.
I think it's also very bad practice to mix object and procedural style.
Also, the other answers don't care about security. Use prepared statements and reselect the username, because mysqli validates your $_SESSION['username'] in this case.
Take a look into this one:
<?php
// Init the database connection
$db = new mysqli("example.com", "user", "password", "database");
// Look for errors or throw an exception
if ($db->connect_errno) {
throw new Exception($db->connect_error, $db->connect_errno);
}
// Init prepared statement
$prep = $db->stmt_init();
// Prepared statement
$prep = $db->prepare("SELECT username, points FROM account_information WHERE username = ? AND username IS NOT NULL AND username != ''");
// See if statement is ok
if (!$prep) {
throw new Exception($db->error);
}
// Put your variables into the query
$prep->bind_param('s', $_SESSION['username']);
// Fire the query!
$prep->execute();
// This is magic, it's awesome.. try it :-))
$prep->bind_result($username, $points);
// Get the results easily
while ($prep->fetch()) {
echo "{$username} has {$points}<br>", PHP_EOL;
}
// This is like in our house, when we leave it, we close the door
$prep->close();
$db->close();
Update:
Answering your comment, this style is better because objects are better in general than procedural functions. Better to program, better to read, easier to understand (object abstract from real life objects).
bind_param validates your input. Imagine me putting in ;DROP TABLE account_information;-- into my username session. This is SQL Injection - the only safe way to prevent them is to prepare statements. Or Imagine having more than one database connection. Every mysqli object represents a different connection. This is not as clear as with procedural style. Also, error reporting using Exceptions is way more flexible because they can be catched and thrown.
If you want to know more about their returns, just read the manual: http://php.net/mysqli_query
mysqli_query / mysqli::query return values:
Returns FALSE on failure. For successful SELECT, SHOW, DESCRIBE or
EXPLAIN queries mysqli_query() will return a mysqli_result object. For
other successful queries mysqli_query() will return TRUE.
Related
I am iterating rows of a csv file.
On row 1, I call stored procedure (import_extended_data_sp) and it succeeds.
On row 2, the call fails with :
Strict Standards mysqli::next_result(): There is no next result set.
However, with the call being exactly the same as the first, I am struggling to see why ?
I have now hard coded test values as parameters, and checked that the Sproc has no issue with the same values being given twice.
It still fails on the second call !?
Am wondering if there is some nuance of mysqli, where I need to clear or reset something before making the second call ?
<?php include("cnn.php");?>
<?php include("fn_db.php");?>
# ... get csv file (skipped for brevity) #
while($row = fgetcsv($file_data))
{
$line = array_combine($head, $row);
# This call works on every loop - no issues
$id = placemark_to_db($mysqli,$v_header,$line['id_placemark'],$line['name'],$line['swim_type'],$line['latitude'],$line['longitude'],$line['description']);
# This next line only succeeds on first call, but fails on next while loop
$x = xtended_to_db($mysqli,'99','[{"xtra":"oo"}]');
}
** fn_db.php >> xtended_to_db**
function xtended_to_db($cn,$id,$jsonarray){
# procedure returns a rowcount in output parameter
$cn->multi_query( "CALL import_extended_data_sp($id,'$jsonarray',#out);select #out as _out");
$cn->next_result();
$rs=$cn->store_result();
$ret = $rs->fetch_object()->_out;
$rs->free();
return $ret;
}
cnn.php
<?php
$mysqli = new mysqli("xxx.xxx.xxx.xxx","mydb","pass","user");
// Check connection
if ($mysqli -> connect_errno) {
echo "Failed to connect to MySQL: " . $mysqli -> connect_error;
exit();
}
?>
The best way to fix this error is to avoid multi_query() altogether. While it might sound like a reasonable use case with stored procedures, the truth is this function is mostly useless and very dangerous. You can achieve the same result using the normal way with prepared statements.
function xtended_to_db(mysqli $cn, $id, $jsonarray) {
$stmt = $cn->prepare('CALL import_extended_data_sp(?,?,#out)');
$stmt->bind_param('ss', $id, $jsonarray);
$stmt->execute();
$stmt = $cn->prepare('select #out as _out');
$stmt->execute();
$rs = $stmt->get_result();
return $rs->fetch_object()->_out;
}
If you are stuborn and you want to keep on using multi_query() then you need to be more careful with how you fetch results. This function is extremely difficult to get right. I am not going to show you how to fix multi_query() as I consider it too dangerous with variable input.
One last note, you really should think about getting rid of stored procedures. They are cumbersome and offer pretty much no benefit. There definitely is a better way to achieve what you want rather than calling stored procedure from PHP, but without seeing its contents I can't give you better advice.
I have a pretty stupid question, but I can't get it to work immediately.
How do I load only one field of the result array of a query into a session (array) using a single PDO statement?
I commented the missing code below:
public function getPermissions($user_role_id){
if(!isset($user_role_id) || empty($user_role_id)){
$_SESSION['user']['user_permissions'] = '';
}else{
$db = Database::get_database();
$query = "
SELECT
rp.role_id, rp.permission_id
FROM
role_permission_tbl rp
WHERE
rp.role_id = :role_id";
$query_params = array(
':role_id' => $user_role_id
);
try
{
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}
$row = $stmt->fetchAll();
if($row){
//I only want to retrieve the field "permission_id"
$_SESSION['user']['user_permissions'] = $row;
}else{
$_SESSION['user']['user_permissions'] = '';
}
}
}
Thanks
After seeing your later comments, it looks as though you're wanting to save all permission data in a session variable so that you can look it up by permission ID:
$rows = $stmt->fetchAll();
foreach($rows as $row){
//Add to session, keyed by permission ID.
$_SESSION['user']['user_permissions'][$row['permission_id']] = $row;
}
//Then, if you want to see if said permission ID #21 exists:
if(isset($_SESSION['user']['user_permissions'][21])){
echo 'This user has permissions with ID 21!';
$permissionDetails = $_SESSION['user']['user_permissions'][21];
var_dump($permissionDetails);
}
Like any other "get it to work immediately" this question has contradicting conditions.
Like any other PHP code, it is ten times long than needed.
Like many other SO questions, it can be solved by quick manual lookup.
In case you need your permissions in array
public function getPermissions($user_role_id){
$sql = "SELECT permission_id FROM role_permission_tbl WHERE role_id = ?";
$stm = Database::get_database()->prepare($sql);
return $stm->execute(array($user_role_id))->fetchAll(PDO::FETCH_COLUMN);
}
note that assigning variables inside functions is a very bad practice. So, better call it this way
$_SESSION['user']['user_permissions'] = $user->getPermissions($user_role_id);
isset() is useless in conjunction with empty() as latter covers the former.
both isset() and empty() are useless for the function variable too, as it is always set by design
a verification for this particular input variable can be done, but for the sanely designed application it would be unnecessary.
setting a variable you are going to test with in_array() to an empty string will produce an error.
there is no use for the alias with single table.
PDO methods can be called dramatically shorter way, there is no use for stretching one simple query call to a whole screen of code.
echoing a system error message to a site user is an awful practice.
the very manual page for the fetchAll() contains an exact example for this very question of getting single column out of the query result.
there is no use for testing returned value explicitly, as it already contains either result or empty value (and luckily, fetchAll() will return even empty value of desired type).
Can you try $row = $stmt-> fetch(); instead of $row = $stmt->fetchAll(); if it is fetch only one record from table,
$row["permission_id"];
I am relatively new to PHP OOP and i know that there are numerous questions here on SO, but none of them seam to be pointing me in the right direction. I have created the class user, and I am calling this in another file.
I am trying to get the method 'reset' to call up 'connect', connect to the mysql db and then query it and set various properties to the row contents.
I am receiving no errors but for some reason it is not feeding the properties any data from the database.
I have tried placing the mySQL connect in the reset method, just to see if the variables cannot be passed between methods. But still no joy.
Can anyone point me in the right direction?
class user(){
public function reset(){
$this->connect();
$sql ='SELECT * FROM users WHERE user_id="'.$user_id.'"' ;
$result = mysqli_query($con,$sql);
while($row = mysqli_fetch_array($result))
{
$this->user_name=$row['dtype'];
$this->user_id=$row['user_id'];
$this->atype=$row['atype'];
$this->user_email=$row['user_email'];
$this->group1=$row['group1'];
$this->group2=$row['group2'];
$this->group3=$row['group3'];
$this->group4=$row['group4'];
$this->group5=$row['group5'];
$this->group6=$row['group6'];
}
// Test that these properties are actually being echoed on initial file... it is
// $this->user_name = "john";
// $this->user_email = "john#gmail.com";
// $this->dtype = "d";
// $this->atype = "f";
}
public function connect(){
//GLOBALS DEFINED IN INDEX.PHP
if ($db_open !== true){
$con=mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
// Check connection
if (mysqli_connect_errno())
{
$debug_system .= 'Error on user.php: ' . mysqli_connect_error().'<br\/>';
} else {
$db_open = true;
$debug_system .= 'user.php: user details grab successful. <br\/>';
}
}
}
}
If you are relatively new to PHP OOP, it is strongly recommended not to mess with awful mysqli API but learn quite sensible PDO first, and only then, making yourself familiar with either OOP and prepared statements, you may turn to mysqli.
Nevertheless, there shouldn't be no function connect() in the class user. You have to have a distinct db handling class, which instance have to be passed in constructor of user class
The problem lies in this line:
$sql ='SELECT * FROM users WHERE user_id="'.$user_id.'"' ;
At no point do you actually define $user_id. Presumably you actually mean $this->user_id.
$sql ='SELECT * FROM users WHERE user_id="'.$this->user_id.'"' ;
Better still would be to make full use of parameterized queries, which might look like this:
$sql ='SELECT * FROM users WHERE user_id=?' ;
You would then prepare the statement and bind the user ID, then execute the query:
$stmt = mysqli_prepare($sql);
mysqli_stmt_bind_param($stmt, $this->user_id);
mysqli_stmt_execute($stmt);
And then fetch the results:
while($row = mysqli_stmt_fetch($result))
As you can see, there is a whole load more to modern MySQL libraries. I'd advise you to do more research into how MySQLi and parameterized queries work (and perhaps PDO as well: it's a superior library) before you use them further. It will be worth the effort.
This yields proper results, but I would like to have the resulting row in an array, instead of binding individual variables to each field, so I can access fields like $row[0] and/or $row["name"].
$idToSearch = 2;
$conn = new mysqli("localhost", "username", "password", "db_people");
$statement = $conn->prepare("SELECT name, age from People where id = ?");
$statement->bind_param("i", $idToSearch);
$statement->execute();
$statement->bind_result($name, $age);
if($statement->fetch()) {
echo "The name is $name and the age is $age. ";
} else {
echo "No person found with that id.";
}
Saw an example about fetch_assoc(), but it used a mysqli_result class which I don't know hot to use and unprepared statements which I'd rather not use.
EDIT: To clarify, I'm fine with a solution whether it uses bind_result or not.
In order to use fetch_assoc you would need to use get_results which would force you to not use the bind which it seems you don't want to do. So I believe what you want to do is explained pretty well by user uramihsayibok in the php docs for the bind_result function, specifically here: http://php.net/manual/en/mysqli-stmt.bind-result.php#92505. They explain how to work around that in order get the results into an array.
I'm attempting to convert my script that I use for registering a user on my website from SQL to SQLi. I have some code and wondered if it was correct. Thanks.
$members = new mysqli("localhost", "root", "pass", "members");
$check = $members->prepare("select email from users where email = ?");
$check->bind_param('s', $_POST['r_email']);
$check->execute();
$check->store_result();
if ($check->num_rows > 0) {
echo "user already registered";
} else {
$user_id = mt_rand(100000000, 999999999);
$add_user = $members->prepare("insert into users(email, password, user_id) values(?, ?, ?)");
$add_user->bind_param('ssi', $r_email, $r_password, $user_id);
$r_email = $_POST['r_email'];
$r_password = md5($_POST['r_password']);
$add_user->execute();
$add_user->close();
}
$check->close();
$members->close();
Dealing with the error message you noted in your comment, 'All data must be fetched before a new statement prepare takes place'' ...
The error means exactly what it says: You're trying to prepare a new statement before you've fetched all the data from the previous statement. From the manual entry on mysqli::use_resultdocs ...
Used to initiate the retrieval of a result set from the last query
executed using the mysqli_real_query() function on the database
connection.
Either this or the mysqli_store_result() function must be called
before the results of a query can be retrieved, and one or the other
must be called to prevent the next query on that database connection
from failing.
Further, from the manual entry on mysqli_stmt::num_rowsdocs ...
Returns the number of rows in the result set. The use of
mysqli_stmt_num_rows() depends on whether or not you used
mysqli_stmt_store_result() to buffer the entire result set in the
statement handle.
You need to call mysqli_stmt::store_result before you check mysqli_stmt::num_rows (as described at mysqli_stmt::num-rows). After that, you need to close the statement using mysqli_stmt::close (mysqli_stmt::close).
Edit: Also, using md5 for password hashing (especially without a salt) is very insecure. Take a look at https://stackoverflow.com/a/1581919/140827 for suggestions on more secure solutions (bcrypt, salt, etc.)