Problem with PHP class for MySQLi Request - php

i've some trouble with my Script.
I'm trying to create a login script based on classes
The mysql request is handled by the checkLogin Class.
If the request is succesfull it return the Result to the login Class (throw back to index.php with ?status=1)
My Problem is that the SQL request isn't triggered and throws back with ?status=0
I've testet the SQL in phpmyadmin and its correct.
I've testet the $this->postUser and it contains the correct value
<?php
require ("globals.php");
require ("../src/class.connect.php");
require ("../src/class.login.php");
if($_POST)
{
if(isset($_POST['submit']))
{
if(empty($_POST['user']))
{
$request = null;
}
else
{
$request = $_POST['user'];
}
$a = new login($request);
}
}
?>
--class.connect.php
<?php
class dbh
{
private $servername;
private $username;
private $Password;
private $dbname;
protected function connect()
{
$this->servername = HOST;
$this->username = USER;
$this->password = PW;
$this->dbname = DB;
$db = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
mysqli_set_charset($db, 'utf8');
return $db;
}
}
?>
--class.login.php
<?php
class checkLogin extends dbh
{
private $postUser;
protected function getlogin()
{
$this->postUser = $this->request;
$SQL = "SELECT user, isadmin, user_data, name, surname FROM `fm_user`, `fm_support` WHERE sup_id = user_data AND user = ? LIMIT 1";
$stmt = $this->connect()->prepare($SQL);
$stmt->bind_param("s", $this->postUser);
if ($stmt->execute()) {
$result = $stmt->get_result();
$getUser = $result->fetch_assoc();
$result[] = $getUser;
return $result;
}
else
{
header('location: ../index.php?status=0-'.$this->postUser); //$this->postUser - Just to check if the Value is correct given.
die();
}
}
}
class login extends checkLogin
{
protected $request;
public function __construct($request)
{
$this->request = $request;
$this->showLogin();
}
private function showLogin()
{
$data = $this->getlogin();
$cookieVal = "%".$getUser["user"]."%".$getUser["isadmin"]."%".$getUser["name"]."%".$getUser["surname"]."%";
createCookie($cookieVal);
header("location: ../index.php?status=1");
die();
}
}
?>

Related

PHP won't open webpage after logging in

I am trying to create a login system using OOP PHP code and MySQL, however it won't take me to the next page after logging in. It tells me correctly if I haven't used credentials that are in the database, it seems to always redirect me back to the login page even if I have used a user in the database.
Below are the php from the webpages and my classes, everything appears to be correct but it doesn't work and I'm not sure why.
login.php
<?php
ob_start();
require_once ("init.php");
if ($session->loggedIn()) {redirect("SecLogin.php");}
if (isset($_POST['submit']))
{
$email = trim($_POST['email']);
$password = trim($_POST['pword']);
$userFound = User::verify($email, $password);
if ($userFound)
{
$session->login($userFound);
redirect("SecLogin.php");
}
else
{
$message = "Your Email Address or Password are not recognised";
echo $message;
}
}
else
{
$email = "";
$password = "";
}
?>
SecLogin.php
<?php
require_once ("init.php");
if(!$session->loggedIn()) {redirect("login.php");}
?>
init.php
<?php
require_once ("functions.php");
require_once ("constants.php");
require_once ("database.php");
require_once ("user.php");
require_once ("session.php");
session.php
<?php
class Session
{
private $logIn = false;
public $userE;
public function __construct()
//construct function
{
session_start();
$this->check();
}
public function loggedIn()
//checks whether a user is logged in
{
return $this->logIn;
}
public function login($user)
//Logs the user in
{
if ($user)
{
$this->userE = $_SESSION['UserE'] = $user->email;
$this->logIn = true;
}
}
public function logout()
//Logs out the user
{
unset($_SESSION['UserE']);
unset($this->userE);
$this->logIn = false;
}
private function check()
//Checks whether the user exists
{
if (isset($_SESSION['UserE']))
{
$this->userE = $_SESSION['UserE'];
$this->logIn = true;
}
else
{
unset($this->userE);
$this->logIn = false;
}
}
}
//instantiates the class
$session = new Session();
user.php
<?php
class User
{
public $id;
public $firstname;
public $lastname;
public $email;
public $password;
public static function findUser()
{
return self::findQuery("SELECT * FROM user");
}
public static function locateUser($userMail)
{
$datasetArray = self::query("SELECT * FROM user WHERE User_Email = $userMail LIMIT 1");
return !empty($datasetArray) ? array_shift($datasetArray) : false;
}
public static function findQuery($stmt)
{
global $database;
$resultSet = $database->query($stmt);
$instantArray = array();
while ($row = mysqli_fetch_array($resultSet))
{
$instantArray[] = self::instant($row);
}
return $instantArray;
}
public static function verify($email, $password)
{
global $database;
$email = $database->escapeString($email);
$password = $database->escapeString($password);
$sql = "SELECT * FROM user WHERE ";
$sql .= "User_Email = '{$email}'";
$sql .= "AND User_Password ='{$password}'";
$sql .= "LIMIT 1";
$verifyArray = self::findQuery($sql);
return !empty($verifyArray) ? array_shift($verifyArray) : false;
}
public static function instant($record)
{
$instant = new self;
foreach ($record as $attr => $value)
{
if ($instant->hasAttr($attr))
{
$instant->$attr = $value;
}
}
return $instant;
}
private function hasAttr($attr)
{
$properties = get_object_vars($this);
return array_key_exists($attr, $properties);
}
}
database.php
<?php
require_once ("constants.php");
class Database
{
public $conn;
function __construct()
{
$this->openDbConnection();
}
public function openDbConnection()
//Opens the connection to the database
{
$this->conn = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD,DB_NAME);
if ($this->conn->connect_errno)
{
die("Database Connection Failed" . $this->conn->connect_error);
}
}
public function query($sqlStmt)
//
{
$result = $this->conn->query($sqlStmt);
$this->confirmQuery($result);
return $result;
}
private function confirmQuery($result)
{
if(!$result)
{
die("Query Failed".$this->conn->error);
}
}
public function escapeString($string)
{
$escape = $this->conn->real_escape_string($string);
return $escape;
}
public function insertId()
{
return $this->conn->insert_id;
}
}
$database= new Database();
This is a job for PHP Debugging.
Start like this: go to the place in your application that you suspect is most like not working. If it were me, I would start here:
$this->logIn = true;
die('Did I make it to line '.__LINE__.'?');
if the application dies there then you may have cookies turned off or are lacking session support in your php installation. If the application does not make it there, go backwards until you find where it is not behaving as you had hoped.

PHP code convert to PHP/MySQLi OOP

today i tried to convert my code to PHP/MySQLi OOP code.
class Database
{
private $host;
private $user;
private $password;
private $db;
private $mysqli;
function __construct()
{
$this->host = "*****";
$this->user = "*****";
$this->password = "******";
$this->db = "*****";
$this->mysqli = new mysqli($this->host, $this->user, $this->password, $this->db);
if (mysqli_connect_errno()):
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
endif;
}
}
This is a script for the query's:
include_once("WD_Config/database.php");
class Adressen_Db
{
function __construct()
{
$this->database = new Database();
}
public function selecteer()
{
$query = "SELECT * FROM wd_adressen WHERE verborgen = 0 ORDER BY naam ASC";
$result = $this->database->mysqli->query($query);
return $result;
}
}
And this is how i call it.
$adressen = new Adressen_Db;
$adressen_result = $adressen->selecteer();
echo "<p>";
while ($row = $adressen_result->fetch_assoc()):
echo "<a href='http://maps.google.com/?q=".$row['voladres']."' target='_blank'>".$row['naam']."</a> woonachtig op <i>".$row['voladres']."</i><br>";
endwhile;
echo "</p>";
I alway get a "Call to a member function query() on a non-object". Doesn't matter what i trie ...
Can somebody tell me why that is?
Thanks!
The $mysqli variable in class Database is declared private.
You can access it only through setters and getters.
I think while you definitely need to have $mysqli as public so it can be accessed in the other method, there might be something else, as the error would be something like
trying to access private property in database class
or something like that, whereas your script throws a non-object call error
I think your new Adressen_Db; lacks the parenthesis:
$adressen = new Adressen_Db();
You can replace your code with this:
Config.php
<?php
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASS", "");
define("DB_NAME", "your_database_name");
Now include this file in your database file
require_once 'config.php';
Class Database {
public $host = DB_HOST;
public $user = DB_USER;
public $pass = DB_PASS;
public $dbname = DB_NAME;
public $link;
public $error;
public function __construct() {
$this->getConnection();
}
private function getConnection() {
$this->link = new mysqli($this->host, $this->user, $this->pass, $this->dbname);
if (!$this->link) {
$this->error = "Connection failed" . $this->link->connect_error;
return false;
}
}
// for only select query
public function select($query) {
$result = $this->link->query($query) or
die($this->link->error . __LINE__);
if ($result->num_rows > 0) {
return $result;
} else {
return false;
}
}
// for insert, delete and update
public function myquery($query) {
$myquery = $this->link->query($query) or
die($this->link->error . __LINE__);
if ($myquery) {
return $myquery;
} else {
return false;
}
}
}
Now, make your queries like this:
<?php
require_once './lib/Database.php';
?>
<?php
class Admin {
private $db;
public function __construct() {
$this->db = new Database();
}
public function getData(){
$query = "SELECT * FROM admin";
$result = $this->db->select($query);
if($result != false){
while($row = $result->fetch_assoc()){
// do your thing
}
}
}
public function insert(){
$query = "INSERT INTO admin(admin_name) VALUES('$admin_name')";
$result = $this->db->myquery($query);
if($result){
$msg = "User has been added successfully.";
return $msg;
} else {
$msg = "Error while adding user. Please try again.";
return $msg;
}
}
}
Do this.

I have trouble calling my PHP function/method

I am having trouble calling the variable inside my class method. Variable userId won't display on screen. Below is my class and my index.php file. I want to display the userId of the user after form submission.
class validateLogin
{
public $id;
public $username;
public $password;
public function __construct($aUserName,$aUserPassword)
{
$this->username = $aUserName;
$this->password = $aUserPassword;
}
public function checkUser()
{
$conn = new dbconnection();
$dbh = $conn->connect();
$query = $dbh->prepare("SELECT id FROM tbluser WHERE username=:username AND password=:password");
$query->bindParam(":username", $this->username);
$query->bindParam(":password", $this->password);
$query->execute();
$counts = $query->rowCount();
if($counts==1) {
$results = $query->fetch();
$this->id = $results['id'];
}
}
public function getUserId() {
return $this->id;
}
}
My index.php is below (assume that the submit button has been clicked)
require_once 'classes/class.Database.php';
require_once 'classes/class.Validation.php';
if(isset($_POST['submit'])) {
if(!empty($_POST['username']) && !empty($_POST['password'])) {
$user = new validateLogin($_POST['username'],$_POST['password']);
echo getUserId()
}
}
The constructor is not calling the:
checkUser();
You need to make the constructor do that or:
require_once 'classes/class.Database.php';
require_once 'classes/class.Validation.php';
if(isset($_POST['submit'])) {
if(!empty($_POST['username']) && !empty($_POST['password'])) {
$user = new validateLogin($_POST['username'],$_POST['password']);
$user->checkUser();
echo $user->getUserId();
}
}
You need to reference the object
echo getUserId()
should be
echo $user->getUserId()

Fatal error: Call to undefined method Database::prepare()

I have created a separate class for database and users.
Database.php
class Database{
private $db;
public function __construct(){
/*** mysql hostname ***/
$hostname = 'localhost';
/*** mysql username ***/
$username = 'username_web';
/*** mysql password ***/
$password = 'password_web';
try {
$this->db = new PDO("mysql:host=$hostname;dbname=kamadhenu_web", $username, $password);
/*** echo a message saying we have connected ***/
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
/*** Query Function ***/
public function query($sql)
{
return $this->db->query($sql);
}
}
Users.php
class Users{
private $db;
public function __construct($database) {
$this->db = $database;
}
public function login($username, $password)
{
$query=$this->db->prepare("SELECT `password`, `id` FROM `users` WHERE `username` = ?");
$query->bindValue(1, $username);
try{
$query->execute();
$data = $query->fetch();
$stored_password = $data['password'];
$id = $data['id'];
#hashing the supplied password and comparing it with the stored hashed password.
if($stored_password === sha1($password)){
return $id;
}else{
return false;
}
}catch(PDOException $e){
die($e->getMessage());
}
}
}
Here is my Login page with username and password.
login.php
include('database.php');
include('users.php');
$dbh= new Database();
$users= new Users($dbh);
if (isset($_POST['submit']))
{
$username= $_POST['username'];
$password= $_POST['password'];
$login = $users->login($username, $password);
if ($login === false) {
$errors[] = 'Sorry, that username/password is invalid';
}
else {
// username/password is correct and the login method of the $users object returns the user's id, which is stored in $login.
$_SESSION['id'] = $login; // The user's id is now set into the user's session in the form of $_SESSION['id']
#Redirect the user to home.php.
header('Location: list-updates.php');
exit();
}
}
When I execute I get an error:
Call to undefined method Database::prepare()
You create $dbh when you instantiate Database(), but instantiating the Database only returns an instance of your Database class, not your db connection. You should have a getDb to get your connection from database object:
$dbClass = new Database();
$dbh = $dbClass->getDb(); // here you get the connection
$users= new Users($dbh); // here you give to Users() the $dbh, that isn't your
// connection.. it's just Database class
Database construct only return an instance of your Database class, not your db connection
class Database{
private $db;
public function __construct(){
try {
$this->db = new PDO("mysql:host=$hostname;dbname=kamadhenu_web", $username, $password);
/*** echo a message saying we have connected ***/
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function getDb() {
if ($this->db instanceof PDO) {
return $this->db;
}
}
}
add the method "getmyDB" to database file
class Database
{
/* Properties */
private $conn;
private $dsn = 'mysql:dbname=test;host=127.0.0.1';
private $user = 'root';
private $password = '';
/* Creates database connection */
public
function __construct()
{
try
{
$this->conn = new PDO($this->dsn, $this->user, $this->password);
}
catch(PDOException $e)
{
print "Error!: " . $e->getMessage() . "";
die();
}
return $this->conn;
}
public function getmyDB()
{
if ($this->conn instanceof PDO)
{
return $this->conn;
}
}
}
and call it when you create the constructor in the file user.php
include "database.php";
class User
{
/* Properties */
private $conn;
/* Get database access */
public
function __construct()
{
$this->conn = new Database();
$this->conn = $this->conn->getmyDB();
}
/* Login a user */
public
function login()
{
$stmt = $this->conn->prepare("SELECT username, usermail FROM user");
if ($stmt->execute())
{
while ($rows = $stmt->fetch())
{
$fetch[] = $rows;
}
return $fetch;
}
else
{
return false;
}
}
}
and finally add test.php file
include "user.php";
$user = new User();
$list = $user->login();
foreach($list as $test)
{
echo $test["username"];
}
Your Database class does not extend PDO neither it does implement prepare method.
In order to access your PDO object, you must make it public and access like:
From User class:
$this->db->db->prepare();
The best way would be to extend the PDO class.

PHP session - Attach a class instance

For a small personnal project, I need to attach a class instance into a PHP Session.
For that, I've written the following code, but it doesn't work as I expect. For example, when I call the method login and I refresh the page, nothing is modified in my class. I mean, it's like if it was reseted everytime.
My question is: How could I share the Core instance between my pages using PHP sessions ?
<?php
class Core
{
/* Database */
private $db = null;
/* User activity */
private $loggedin = false;
private $userid = 0;
private $username = null;
private $password = null;
private $lastActivity = null;
/* Constructor */
public function __construct()
{
$this->connect();
}
/* Serialize */
public function __sleep()
{
return array('loggedin', 'userid', 'username', 'password', 'lastActivity');
}
/* Unserialize */
public function __wakeup()
{
$this->connect();
}
/* Connect to database */
private function connect()
{
global $DB_HOSTNAME, $DB_BASENAME, $DB_USERNAME, $DB_PASSWORD;
try
{
$this->db = $db = new PDO('mysql:host='.$DB_HOSTNAME.';dbname='.$DB_BASENAME.';charset=utf8', $DB_USERNAME, $DB_PASSWORD);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (Exception $e)
{
die('Erreur : ' . $e->getMessage());
}
}
/* Get database */
public function getDb()
{
return $this->db;
}
/* Create a new login session */
public function login($userid, $username, $password)
{
$this->loggedin = true;
$this->userid = intval($userid);
$this->username = $username;
$this->password = $password;
$this->lastActivity = time();
}
/* Close the login session */
public function logout()
{
$this->loggedin = false;
$this->userid = 0;
$this->username = null;
$this->password = null;
}
/* Check if the session is running or not */
public function isConnected()
{
if ($this->loggedin)
{
if ($this->lastActivity + 3600 < time())
{
$this->logout();
return false;
}
elseif (isset($this->password))
{
$db = $this->db;
$query = $db->prepare('SELECT id FROM ptc_users WHERE id=:userid AND password=:password LIMIT 1;');
$query->bindParam(':userid', $this->userid, PDO::PARAM_INT);
$query->bindParam(':password', $this->password, PDO::PARAM_STR);
$query->execute();
if ($query->rowCount() == 1)
{
$this->lastActivity = time();
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
return false;
}
/* Return the current user id */
public function getUid()
{
return $this->userid;
}
/* Return the current username */
public function getUsername()
{
return $this->username;
}
/* Return the hash signature of the password */
public function hash($input)
{
return sha1('minad8rBxu' .$input. 'MigdVKXUCf');
}
/* Return the user's ip */
public function getIp()
{
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) return $_SERVER['HTTP_X_FORWARDED_FOR'];
else return $_SERVER['REMOTE_ADDR'];
}
}
// Create a new core session if not started before
if (!isset($_SESSION)) session_start();
if (!isset($_SESSION['core']))
{
$core = new Core();
$_SESSION['core'] = serialize($core);
}
else
{
$core = unserialize($_SESSION['core']);
}
?>
I'm using the magic methods __sleep and __wakeup to avoid to serialize the PDO instance.
Thanks for your help.
Instantiate or autoload the Core class so you can use it throughout your application. No need for session..Or just save the class name to session..
Just save username, timestamp, userid and password to the session..
$_SESSION['instance'] = json_encode(array('username', 'timestamp', 'userid','password'));
$object = json_decode($_SESSION['instance']);
echo var_dump($object);

Categories