making simple query with MySQLi - php

If i've database table with users(name,job) (john,Poster) and i made query with MySQLi using this code and that would works.
$job = "Poster";
$statement = $con->prepare("SELECT * FROM users WHERE `job` = ?");
$statement->bind_param("s",$job);
$statement->execute();
$statement->bind_result($name,$job);
while ($statement->fetch()){
echo $name;
}
what if i made $job = "NOTHING"; and there was no results then how can i show error such as echo "No reuslts found"; !! the above code if $job was not found it will show nothing. ~ thanks
EDIT
this one didn't worked too :(
$job = "NOTHING"; // should not found and should gives error
if ($statement = $con->prepare("SELECT * FROM users WHERE `job` = ?")){
$statement->bind_param("s",$job);
$statement->execute();
$statement->bind_result($name,$job);
while ($statement->fetch()){
echo $name;
}
}else{
echo "No results found dude";
}

Do not use mysqli. It is unusable with prepared statements.
Use PDO instead.
With PDO your code would be shorter, sensible and works.
$statement = $con->prepare("SELECT * FROM users WHERE `job` = ?");
$statement->execute(array($job));
if ($row = $statement->fetch()){
echo $row['name'];
} else {
echo "No results found dude";
}
You need to create a connection first. Something like this
$dsn = 'mysql:dbname=test;host=127.0.0.1';
$user = 'dbuser';
$pass = 'dbpass';
$con = new PDO($dsn, $user, $pass);
You can see details on the manual page
As a further step you can move to some helper library, which will make your code even shorter:
$name = $db->getOne("SELECT name FROM users WHERE job=?s",$job);
if ($name) {
echo $name;
} else {
echo "No results found dude";
}
But it would be wise to get yourself familiar with raw API functions first.

Related

How to count your user userID to count/select a row in a table?

I'm making a function that i have to check if a userid is in this table already: if not he has to get into another page yet. But for some reason I get "NULL" back instead of the number of the userID.
my class:
public function countHobbies($userID){
try{
$conn = Db::getConnection();
$statement = $conn->prepare("select * from hobby where userID = '".$userID."'");
$userID = $this->getUserID();
$statement->execute();
$aantal = $statement->fetchAll(PDO::FETCH_ASSOC); //
$aantal->execute();
}
catch(throwable $e){
$error = "Something went wrong";
}
}
and this is on my html page:
$userArray = $_SESSION['user_id'];
$userID = implode(" ", $userArray);
$hobby = new Hobby();
$count = $hobby->countHobbies($userID);
if($count == false){
echo "no";
//header('Location: hobby.php');
}
else{
echo "yes";
}
There are at least two things you need to fix:
Always use parameter binding on the SQL statement. It may not be a security problem in this particular instance, but do get into the habit of using prepared statements. Because otherwise you'll find yourself in situations where you should've but didn't. https://www.php.net/manual/en/security.database.sql-injection.php
The $userID variable must be assigned before it is used.
In the end, it could look like this:
$userID = $this->getUserID();
$statement = $conn->prepare("select * from hobby where userID = ?");
$statement->bind_param("s", $userID);

Php webservice looping

I am about to lose my mind.I dont have any php experince and I am struggling about php web service.
Here is my code;
<?php
private $username2 = "";
private $password2 = "";
private $DB_CONNECTION;
private $servername = "localhost";
private $username = "root";
private $password = "";
private $dbname = "dptest";
function __construct()
{
$this->DB_CONNECTION = mysqli_connect($this->servername, $this->username,
$this->password, $this->dbname);
}
function getUserType(){
$sql = "SELECT usertype FROM `login_test` WHERE username = '". $this->username2."'AND password = '".$this->password2."'";
$result = mysqli_query($this->DB_CONNECTION,$sql);
//$value = mysqli_fetch_array($result);
while(!is_null($value = mysqli_fetch_array($result))){
return $value['usertype'];
}
}
}
This is my function code.The other is my login code;
<?php
include_once 'Authentication.php';
use user\Authentication;
$auth = new Authentication();
$auth->prepare($_POST);
$userStatus = $auth->isUserValidToLogIn();
if ($userStatus) {
// user existed
// So log him to main page
$json['success'] = 1;
$json['message'] = 'access granted';
$json['usertype'] = $auth->getUserType();
echo json_encode($json);
} else {
$json['success'] = 0;
$json['message'] = 'error!';
echo json_encode($json);
}
I am trying to get the user's type but when try to get the data form phpmyadmin local database it only gives the first column's usertype.When I try to get 2nd,3rd,4th so on.. user's usertype it doesnt return anything and blank page shows up on postman app.
Also my database looks like this;
usertype username password
admin despro 1234
client test 1234
client despro2 1234
client despro3 1234
The reason you are only getting one column back is because you only request the one column. In order to get the columns you want you need to explicitly request them in your query or use '*' in order to get all columns back. So your query should look like this in order to get all columns from the data table:
$sql = "SELECT * FROM `login_test` WHERE username = '". $this->username2."'AND password = '".$this->password2."'";
In general, I highly recommend that you stop using MySQLi extension and start using PHP Data Objects (PDO). It makes it easy to use prepared statements. Which also makes your code safer.
Then your query could look something like this (this is NOT the complete code):
// connecting to db
$pdo = new PDO($dsn, $user, $pass, $opt);
$sql = 'SELECT *
FROM login_test
WHERE userName = :username
AND pass = :password;';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':username', $username2, PDO::PARAM_STR);
$stmt->bindParam(':password', $password2, PDO::PARAM_STR);
$res = $stmt->execute();
if ($res) {
$response["userdata"] = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$myData = array();
$myData["usertype"] = $row["usertype"];
$myData["username"] = $row["username"];
array_push($response["userdata"], $myData);
}
}
Note that the code above is for returning multiple rows of data. If you just want the one row then use something like this:
if ($res) {
$response["userdata"] = array();
$myData = array();
$myData["usertype"] = $row["usertype"];
$myData["username"] = $row["username"];
array_push($response["userdata"], $myData);
}
removing the 'while' statement.
You might want to take a look at this answer I gave, recently. It is a comprehensive example of using a webservice from an Android app.
How to insert all the SQL table data into an array in java [android studio]

MySQL Prepared statement confusion

Ok, so I am having a lot of trouble with Prepared statements. I've done hours of research and still can't seem to fully understand everything...
I really feel like I need to understand Prepared statements because I was just about to release a few new free APIs on my website (which require API Key to execute API) but I recently realized how insecure everything is.... I can simply use SQL injection to bypass API Key check, e.g. 'OR'1'='1
Here is how I validate API Key:
$apikey = $_GET['key'];
$sql = "SELECT * FROM `table` WHERE `key` = '$apikey'";
$query = mysqli_query($con, $sql);
if($query)
{
$fetchrow = mysqli_fetch_row($query);
if(isset($fetchrow[0]))
{
echo "API Key is valid!";
}
else
{
echo "API KEY is invalid";
}
}
And like mentioned above this can easily be bypassed by executing my API like this
http://website.com/api.php?key='OR'1'='1
This really scared me at first, but then I did some research and learned a good way to prevent any form of SQL injection is to use prepared statement, so I did a lot of research and it just seems quite complicated to me :/
So I guess my question is, how can I take my above code, and make it function the same way using prepared statements?
Probably everything you need:
class Database {
private static $mysqli;
Connect to the DB:
public static function connect(){
if (isset(self::$mysqli)){
return self::$mysqli;
}
self::$mysqli = new mysqli("DB_HOST", "DB_USER", "DB_PASS", "DB_NAME");
if (mysqli_connect_errno()) {
/*Log error here, return 500 code (db connection error) or something... Details in $mysqli->error*/
}
self::$mysqli->query("SET NAMES utf8");
return self::$mysqli;
}
Execute statement and get results:
public static function execute($stmt){
$stmt->execute();
if ($mysqli->error) {
/*Log it or throw 500 code (sql error)*/
}
return self::getResults($stmt);
}
Bind results to the pure array:
private static function getResults($stmt){
$stmt->store_result();
$meta = $stmt->result_metadata();
if (is_object($meta)){
$variables = array();
$data = array();
while($field = $meta->fetch_field()) {
$variables[] = &$data[$field->name];
}
call_user_func_array(array($stmt, "bind_result"), $variables);
$i = 0;
while($stmt->fetch()) {
$array[$i] = array();
foreach($data as $k=>$v)
$array[$i][$k] = $v;
$i++;
}
$stmt->close();
return $array;
} else {
return $meta;
}
}
Class end :)
}
Example of usage:
public function getSomething($something, $somethingOther){
$mysqli = Database::connect();
$stmt = $mysqli->prepare("SELECT * FROM table WHERE something = ? AND somethingOther = ?");
$stmt->bind_param("si", $something, $somethingOther); // s means string, i means number
$resultsArray = Database::execute($stmt);
$someData = $resultsArray[0]["someColumn"];
}
Resolving your problem:
public function isKeyValid($key){
$mysqli = Database::connect();
$stmt = $mysqli->prepare("SELECT * FROM table WHERE key = ? LIMIT 1");
$stmt->bind_param("s", $key);
$results = Database::execute($stmt);
return count($results > 0);
}
PHP automatically closes DB connection so no worries about it.
$sql = "SELECT * FROM `table` WHERE `key` = ?";
if(stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("i", $apikey);
$stmt->execute();
$stmt->bind_result($res);
$stmt->fetch();
$stmt->close();
}
See more - http://php.net/manual/en/mysqli.prepare.php

How to display only result in page

I have a big problem. I wrote a simple $_GET system
$query = mysql_query("SELECT * FROM `users`");
while ($row = mysql_fetch_array($query)) {
if($_GET['user'] == $row['user_seo']) {
echo 'user exists';
} else {
echo 'No users found';
}
}
If user don't exists in table it display 'No users found' otherwise it display No users found user exists No users found. 2 times it display "No users found" but user exists with that seo in database table. Thanks.
database screen http://prntscr.com/2ddqu4
You are looping over all your users so you will get multiple messages.
You should add a WHERE condition to your query to check only for the required user and switch to PDO or mysqli with prepared statements.
Something like (in PDO):
$query = 'SELECT * FROM `users` WHERE `user_seo`=:user';
$db->prepare($query);
$db->execute(array(':user' => $_GET['user']));
// etc.
Try replacing mysql_fetch_array with mysql_fetch_assoc
Also I would strongly recommend using either PDO or mysqli and prepared statements
Safely find the user with mysqli:
if (isset($_GET['user'])) {
$user = $_GET['user'];
$connection = mysqli_connect($Host, $Username, $Password) or die(mysqli_error());
mysqli_select_db($connection, $database) or die(mysqli_error());
$user = mysqli_real_escape_string($connection, $user);
if (!is_numeric($user)) {
$user = "'$user'";
}
$sql = "SELECT * FROM `users` WHERE `user_seo`=$user;";
$result = mysqli_query($connection, $sql);
if ($result) {
$user = mysql_fetch_assoc($result)) {
if ($user) {
// User found
// Do something with info like:
$userName = $user['name'];
} else {
// User NOT found
}
mysql_free_result($result);
} else {
echo "Could not successfully run query ($sql) from DB: " . mysql_error();
exit;
}
}
You better may use an sql like this:
SELECT * FROM users WHERE user_seo='".$_GET['user']."'; And forget about looping all the rows.
EDIT: but better use PDO or Mysqli and prepared statements

I'm a little confused, PHP says $results is a non-object of the mysqli class

I'm trying to fetch results using mysqli->fetch_row() (or fetch_object(), fetch_array()), yet when I go to run the code at run time it gives me the following error:
Fatal error: Call to a member function fetch_row() on a non-object in...on line 23.
The var in question that does this is $results in the code below. $user and $password gain their values from another .php file that this file is being included in so that's not really important at the moment. Now correct me if I'm wrong but if $results is being set = to $db->query($query) then isn't it supposed to inherit the properties of $db aka the mysqli class?
class mySQLHelper{
public function checkPass($user, $pass){
global $db;
$db = new mysqli();
$db->connect('localhost', 'root', '', 'mydb');
if (mysqli_connect_errno()){
echo 'Can not connect to database';
echo mysqli_connect_errno(). mysqli_connect_error();
exit;
return false;
}
$query = "SELECT user, password FROM Users WHERE user = $user AND password = $pass " ;
echo $query;
$results = $db->query($query);
while ($row = $results->fetch_row()){
echo htmlspecialchars($row->user);
echo htmlspecialchars($row->password);
}
$results->close();
$url = 'http://'. $_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF'])."/";
if(!$results){
// mysqli_close($db);
// header("Location:.$url.login.php&msg=1");
}
else{
// mysqli_close($db);
// header("Location:.$url.featured.php");
}
}
}
Your query is failing on this line:
$results = $db->query($query);
Because of this, $results is false - not a result object as you expect.
To fix the issue, you need to add quotes around your variables (or use prepared statements):
$query = "SELECT user, password FROM Users WHERE user = '".$user."' AND password = '".$pass."' " ;
I would suggest updating to use a prepared statement to prevent SQL-injection issues too though:
$stmt = $db->prepare('SELECT user, password FROM Users WHERE user = ? AND password = ?');
$stmt->bind_param('ss', $user, $pass);
$stmt->execute();
$results = $stmt->get_result();
You script is lacking error checking, and therefore the error in the query is not handled.
$query = "SELECT user, password FROM Users
WHERE user = '$user' AND password = '$pass' " ;
// ^ quotes needed
echo $query;
$results = $db->query($query);
// handle a error in the query
if(!$results)
die($db->error);
while ($row = $results->fetch_row()){
echo htmlspecialchars($row->user);
echo htmlspecialchars($row->password);
}
If you user & password field text or varchar, then you need to use single quote around them
$query = "SELECT user, password FROM Users WHERE user = '".$user."' AND password = '".$pass."' " ;
You have to check, if query runs properly:
if ($result = $mysqli->query($query))
{
}
Use: var_dump($results) to check what it contains
Why are you checking if($results) after trying to manipulate it?
This...
$results->close();
//...
if(!$results){
//...
}
Should be...
if(!$results){
//...
}
$results->close();

Categories