I'm new to PHP and I am trying to check if a user exists in a MySQL database over a MySQLi connection. The name of the user I'm trying to check for is stored in a variable called $code. What would I insert into the statement below to get it to check for $code?
$stmt = $this->db->prepare("SELECT id_user FROM members WHERE username = ??? ($code)");
Thanks for your help.
Edit: Here is my code:
class RedeemAPI {
private $db;
// Constructor - open DB connection
function __construct() {
$this->db = new mysqli('localhost:3306', 'username', 'password', 'db');
$this->db->autocommit(FALSE);
}
// Destructor - close DB connection
function __destruct() {
$this->db->close();
}
// Main method to redeem a code
function redeem() {
// Check for required parameters
if (isset($_POST["username"])) {
// Put parameters into local variables
$code = $_POST["username"];
// Look up code in database
$id_user= 0;
$stmt = $this->db->prepare('SELECT id_user FROM members WHERE username = ?');
$stmt->bind_param("s", $code);
$stmt->execute();
$stmt->bind_result($id_user);
while ($stmt->fetch()) {
break;
}
$stmt->close();
// Bail if code doesn't exist
if ($id_user <= 0) {
sendResponse(400, 'Invalid code');
return false;
}
// Return username, encoded with JSON
$result = array("username" => $code);
sendResponse(200, json_encode($result));
return true;
}
sendResponse(400, 'Invalid request');
return false;
}
}
See mysqli_stmt::bind_param():
$stmt = $this->db->prepare("SELECT id_user FROM members WHERE username = ?");
$stmt->bindParam('s', $code);
$stmt->exeucte();
Here's a good example of a prepared statement:
if ($stmt = $mysqli->prepare("SELECT id_user FROM members WHERE username = ?")) {
/* bind parameters for markers */
$stmt->bind_param("s", $code);
/* execute query */
$stmt->execute();
/* bind result variables */
$stmt->bind_result($result);
/* fetch values */
while ($stmt->fetch()) {
$result = $result;
}
/* fetch value */
$stmt->fetch();
/* close statement */
$stmt->close();
}
Related
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!
The function should return the id of the found user or return false if not found.
Currently I am using bind result and fetch to check if a user is found in an mysql table:
public function getUserIDByName($UserName) {
$uid = "";
$i=0;
if($stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?")){
$stmt->bind_param("s", $UserName);
$stmt->execute();
$stmt->bind_result($uid);
while($stmt->fetch()){
$i++;
}
$stmt->close();
}
if($i==0){
return false;
}else{
return $uid;
}
}
This works, but I assume that there is a proper way to do this without a counter in the fetch loop. I can not use get_result as mysqlnd is not available.
Simple use num_rows to check your query return result or not
function getUserIDByName($UserName) {
if ($stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?")) {
$stmt->bind_param("s", $UserName);
$stmt->execute();
$row_cnt = $stmt->num_rows;
if ($row_cnt == 1) {
$stmt->bind_result($uid);
while ($stmt->fetch()) {
return $uid;
}
} else {
return false;
}
}
}
Use this instead
public function getUserIDByName($UserName)
{
$uid = '';
$response = false;
$stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?");
$stmt->bind_param("s", $UserName);
$stmt->execute();
$stmt->bind_result($uid);
if ($stmt->fetch()) {
$response = $uid;
}
$stmt->close();
return $response;
}
EDIT: just realized you're using mysqli and not pdo. Ill leave this here if you want to use PDO in the feature I guess.
This is how I would do it. You could change rowcount() > 0 to rowcount() === 1 if you want to guarantee only 1 user is found.
public function getUserIDByName($UserName)
{
$stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name = :name");
// bind :name to the username
$stmt->bindParam(":name", $UserName);
// execute the query
$stmt->execute();
// check the rowcount
if ($stmt->rowcount() > 0) {
// fetch the results as a associative array
return $stmt->fetch(PDO::FETCH_ASSOC);
}
// return false because rowcount wasn't bigger than 0
return false;
}
I would like to write a database connection class and I dont understand how I have to write the select method with bind_param-s. Here is the full code. And here the part of the code where I need the help:
public function select($sql){
$db = $this->connect(); //This methos connect to the DB
$stmt = $db->prepare($sql);
if($stmt === false){ //If the prepare faild
trigger_error("Wrong SQL", E_USER_ERROR);
}
$error = $stmt->bind_param("i", $id);
if($error){
return "Error: ".$stmt->error, $stmt->errno;
}
$err = $stmt->execute();
if($error){
return "Error: ".$stmt->error, $stmt->errno;
}
$result = $stmt->bind_result($id);
$stmt->close();
$dbConnection->closeConnection($db);
return $result;
}
I need to got it parameters or how can I slove it?
You need to pass your values into this function too. And eventually bind them into prepared statement.
Optionally you can pass string with types, but by default all "s" will do.
Also remember that you should connect only ONCE per script execution. and then use one single connection all the way throughout your code.
And get rid of all these error checks. Set mysqli in exception mode instead.
public function q($sql, $values = array(), $types = NULL)
{
$stm = $this->mysql->prepare($sql);
if (!$types)
{
$types = str_repeat("s", count($values));
}
if (strnatcmp(phpversion(),'5.3') >= 0)
{
$bind = array();
foreach($values as $key => $val)
{
$bind[$key] = &$values[$key];
}
} else {
$bind = $values;
}
array_unshift($bind, $types);
call_user_func_array(array($stm, 'bind_param'), $bind);
$stm->execute();
return $stm->get_result();
}
so it can be used like this
$res = $db->q("SELECT name FROM users WHERE id=?", [$id]);
or
$res = $db->q("SELECT name FROM users WHERE id=?", [$id], "i");
your other functions have to be changed as well.
class DB{
public $con;
function __construct()
{
$this->con = new mysqli("localhost", "root", "", "proba_fferenc");
}
public function select(...)
{
// as shown above
}
}
This is some PHP code for login on a page.
if ($_POST['submit']=="Log In") {
$query = "SELECT * FROM user WHERE email='".mysqli_real_escape_string($link, $email)."' AND password='$md5' LIMIT 1";
$result = mysqli_query($link, $query);
$row = mysqli_fetch_array($result);
print_r($row);
}
But when I submit LOGIN it doesn't work.
$userCheck = query("SELECT * FROM users WHERE users_email =?",$_POST['user']);
if(count($userCheck)===1){
//we found a match
$data = $userCheck[0];
//now we compare the encryted password
if(crypt($_POST['password'],$data['users_hash'])===$data['users_hash']){
//the password match... the encrypted password
$logged=1;
//so we set the cookie if the user checked the cookie box
//cookie and session code
echo 1;
}else{
//meaning wrong password
echo 2;
}
}else{
//wrong username
echo 0;
}
I am using a custom function working with PDO... I can post the function here if you need to
custom query function using PDO
function query(/* $sql [, ... ] */){
// SQL statement
$sql = func_get_arg(0);
// parameters, if any
$parameters = array_slice(func_get_args(), 1);
// try to connect to database
static $handle;
if (!isset($handle))
{
try
{
// connect to database
$handle = new PDO("mysql:dbname=" . DATABASE . ";host=" . SERVER, USERNAME, PASSWORD);
// ensure that PDO::prepare returns false when passed invalid SQL
$handle->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch (Exception $e)
{
// trigger (big, orange) error
trigger_error($e->getMessage(), E_USER_ERROR);
exit;
}
}
// prepare SQL statement
$statement = $handle->prepare($sql);
if ($statement === false)
{
// trigger (big, orange) error
trigger_error($handle->errorInfo()[2], E_USER_ERROR);
exit;
}
// execute SQL statement
$results = $statement->execute($parameters);
// return result set's rows, if any
if ($results !== false)
{
return $statement->fetchAll(PDO::FETCH_ASSOC);
}
else
{
return false;
}
}
to use it, see the synthax on the top
or:
ex:
$check = query("SELECT * FROM table WHERE column=?",$text);
Here is my code:
$result_username = mysqli_query($dbconnection, Data::checkForUsername($username));
It then goes here:
public static function checkForUsername($username) {
global $database;
$query = "
SELECT COUNT(*)
FROM users
WHERE username='{$username}';";
$result = $database -> query($query);
return $result;
}
Then $result does this:
if (mysqli_result($result_username, 0) > 0) {
However, it then gives me back a Resource_Id?? I can not figure out why?
I simply want to check if the username exists in at least 1 row.
You need to fetch your data after you execute your query
$row = $result->fetch_array(MYSQLI_NUM);
return $row[0];
UPDATE: Now, using prepared statement your function can look like this:
public static function checkForUsername($username) {
global $database;
$result = 0;
$query = "SELECT COUNT(*) FROM users WHERE username=?";
/* create a prepared statement */
if ($stmt = $database->prepare($query)) {
/* bind parameters for markers */
$stmt->bind_param("s", $username);
/* execute query */
$stmt->execute();
/* bind result variable */
$stmt->bind_result($result);
/* fetch value */
$stmt->fetch();
/* close statement */
$stmt->close();
}
return $result;
}
You can try
return $result->num_rows
Then
if (checkForUsername('Redeyes') != 0) {
}