I have the following code and database table that at one point worked perfect together. If a user was on my site, the database would show those users.
I have the session class conjoint with an ini file that I require on every page of my site, so the session is always running.
I have the same code on another site of mine and this is where I brought the code over from, but one time a user was on it and it seems like the database table froze and up to this day, it still shows that user having a session, but if I go on it or anyone else, it doesn't show.
Does anyone see anything in the following that could be wrong?
CREATE TABLE `groups` (
`id` int(11) NOT NULL,
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`permissions` text COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Session class
class Session {
public static function exists($name) {
return (isset($_SESSION[$name])) ? true : false;
}
public static function put($name, $value) {
return $_SESSION[$name] = $value;
}
public static function get($name) {
return $_SESSION[$name];
}
public static function delete($name) {
if(self::exists($name)) {
unset($_SESSION[$name]);
}
}
public static function flash($name, $string = '') {
if(self::exists($name)) {
$session = self::get($name);
self::delete($name);
return $session;
} else {
self::put($name, $string);
}
}
}
Here's part of my db class..
public function action($action, $table, $where = array()){
if(count($where) === 3){
$operators = array('=', '>', '<', '>=', '<=');
$field = $where[0];
$operator = $where[1];
$value = $where[2];
if(in_array($operator, $operators)) {
$sql = "{$action} FROM {$table} WHERE {$field} {$operator} ?";
if(!$this->query($sql, array($value))->error()) {
return $this;
}
}
}
return false;
}
public function get($table, $where){
return $this->action('SELECT *', $table, $where);
}
public function delete($table, $where){
return $this->action('DELETE', $table, $where);
}
public function insert($table, $fields = array()) {
$keys = array_keys($fields);
$values = '';
$x = 1;
foreach($fields as $field) {
$values .= '?';
if($x < count($fields)) {
$values .= ', ';
}
$x++;
}
$sql = "INSERT INTO {$table} (`" . implode('`, `', $keys) . "`) Values ({$values})";
return ! $this-> query($sql, $fields)->error();
}
public function update($table, $id, $fields) {
$set = '';
$x = 1;
foreach($fields as $name => $value) {
$set .= "{$name} = ?";
if($x < count($fields)) {
$set .= ', ';
}
$x++;
}
$sql = "UPDATE {$table} SET {$set} WHERE id = {$id}";
return ! $this-> query($sql, $fields)->error();
}
public function results() {
return $this->_results;
}
public function first() {
return $this->results()[0];
}
public function error() {
return $this->_error;
}
public function errorMessage() {
return $this->_errmsg;
}
public function count(){
return $this->_count;
}
}
Related
I am trying to extend the function of this tutorial on youtube, and I have run into some issues. Here is the particular chunk of code I am currently struggling with:
public function listProjects() {
$projects = DB::getInstance()->get('projects', array('projectStatus', '=', 'active'));
if($projects->count()) {
echo 'This query senses rows, but returns data it does not';
foreach($projects as $project) {
echo $project->projectName;
}
}
}
This is a method of my "Project" class, and it uses methods from the DB class, with relevant code here:
private function __construct() {
try {
$this->_pdo = new PDO('mysql:host=' . Config::get('mysql/host') . ';dbname=' . Config::get('mysql/db'), Config::get('mysql/username'), Config::get('mysql/password'));
} catch(PDOException $e){
die($e->getMessage());
}
}
public static function getInstance() {
if(!isset(self::$_instance)){
self::$_instance = new DB();
}
return self::$_instance;
}
public function query($sql, $params = array()){
$this->_error = false;
if($this->_query = $this->_pdo->prepare($sql)) {
$x = 1;
if(count($params)) {
foreach($params as $param) {
$this->_query->bindValue($x, $param);
$x++;
}
}
if($this->_query->execute()) {
$this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
$this->_count = $this->_query->rowCount();
} else {
$this->_error = true;
}
}
return $this;
}
public function action($action, $table, $where = array()) {
if(count($where) === 3) {
$operators = array('=', '>', '<', '>=', '<=');
$field = $where[0];
$operator = $where[1];
$value = $where[2];
if(in_array($operator, $operators)) {
$sql = "{$action} FROM {$table} WHERE {$field} {$operator} ?";
if(!$this->query($sql, array($value))->error()) {
return $this;
}
}
} return $this;
}
public function get($table, $where) {
return $this->action('SELECT *', $table, $where);
}
So in my index.php, I write this code:
$projectList = new Project;
$projectList->listProjects();
To try and retrieve all of my "projects" stored in the database. I put the "This query senses rows, but returns data it does not" echo in order to determine if rows were being counted, which they are, because that statement is echoed, but my foreach statement is not working correctly. The field in the projects table that I am trying to access is projectName. I would eventually like to display all relevant project info, but I'm sure I could figure that out once I get it to display anything from the database.
This:
foreach($projects as $project) {
echo $project->projectName;
}
should be:
foreach($projects as $project) {
echo $projects->projectName;
}
I am new to php and I am trying to develop a class. I am connected to sqlsrv and the connection is fine. Its when I run the query the results are repeating almost like it's in a loop. I can not find the problem and I was hoping an extra pair of eyes can help. Any help is appreciated!
class DB{
private static $_instance = null;
private $_connection,
$_query,
$_error = false,
$_results,
$_count = 0;
private function __construct(){
$mssqlInfo = array( "Database"=>"db");
$mssqlServer = "server";
$this->_connection = sqlsrv_connect($mssqlServer, $mssqlInfo);
if($this->_connection === false ) {
echo '<h2>Unable to connect to database</h2><br/>';
die( print_r(sqlsrv_errors(), true));
}else{
//echo 'Connected';
}
}
public static function getInstance(){
if(!isset(self::$_instance)){
self::$_instance = new DB();
}
return self::$_instance;
}
public function query($sql, $params = array()){
$this->_error = false;
$options = array( "Scrollable" => SQLSRV_CURSOR_STATIC );
$this->_query = sqlsrv_query($this->_connection, $sql, $params,$options);
if($this->_query){
$this->_results = sqlsrv_fetch_object($this->_query);
$this->_count = sqlsrv_num_rows($this->_query);
}else{
$this->_error = true;
echo 'Error in statement execution.\n';
die( print_r( sqlsrv_errors(), true));
}
return $this;
}
public function action($action, $table, $where = array()){
if(count($where) === 3){
$operators = array('=', '>', '<', '>=', '<=');
$field = $where[0];
$operator = $where[1];
$value = $where[2];
if(in_array($operator, $operators)){
$sql = "{$action} FROM {$table} WHERE {$field} {$operator} (?)";
if(!$this->query($sql, array($value))->error()){
return $this;
}
}
}
return false;
}
public function get($table, $where){
return $this->action('SELECT *', $table, $where);
}
public function delete($table, $where){
return $this->action('DELETE', $table, $where);
}
public function results(){
return $this->_results;
}
public function first(){
return $this->results()[0];
}
public function error(){
return $this->_error;
}
public function count(){
return $this->_count;
}
}
here is the instance on the index page that I am using to test my functions and to retrieve the query.
require_once 'core/init.php';
$users = DB::getInstance()->query("SELECT * FROM users");
$user = DB::getInstance()->get('users', array('username', '=', 'mike'));
if(!$user->count()){
echo 'No user';
}else{
$obj = $users->results();
foreach($obj as $users){
echo $users->username;
echo '<br/>';
}
}
I forgot to included the table.
CREATE TABLE [dbo].[users](
[id] [int] IDENTITY(1,1) NOT NULL,
[username] [varchar](20) NOT NULL,
[password] [varchar](64) NOT NULL,
[salt] [varchar](32) NOT NULL,
[name] [varchar](50) NOT NULL,
[joined] [datetime] NOT NULL,
[group] [int] NOT NULL,
CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
You fetch only one row of the results in function query() and save it to member _results:
$this->_results = sqlsrv_fetch_object($this->_query);
Then you use function results() in a while loop. results() returns an object saved in member _results which will never change. That's why you got an endless loop.
Solution for your problem:
Change
public function query($sql, $params = array()){
[...]
$this->_query = sqlsrv_query($this->_connection, $sql, $params,$options);
if($this->_query){
$this->_results = sqlsrv_fetch_object($this->_query);
$this->_count = sqlsrv_num_rows($this->_query);
[...]
to
public function query($sql, $params = array()){
[...]
$this->_query = $sql;
$this->_results = sqlsrv_query($this->_connection, $sql, $params,$options);
if($this->_query){
$this->_count = sqlsrv_num_rows($this->_query);
[...]
And change
public function results(){
return $this->_results;
}
to
public function results(){
return sqlsrv_fetch_object($this->_results);
}
It looks like you're setting $obj to $user->results() in your while loop, so it's always true and therefore never stops.
Just change it to a foreach().
$obj = $user->results();
foreach ($obj as $user) {
echo $user->username;
echo '<br/>';
}
My limited PHP knowledge is rather old. When I used to create websites I always had a config.php file which contained some defines and a $_DB global variable. Then in every function_xyz.php file I included this config file.
Now I want to finally move on and use classes. But I can't figure out a proper way to have access to mysql in functions of my classes without inclusion of the so called config.php file on top of each file.
Imagine I have a class called User.php:
class User {
private $firstName;
private $familyName;
private $emailAddress;
public function __construct($username, $password) {
//check if user with name and pass exist in DB
// stuff....
//If user exist, populate member variables
$this->emailAddress = ...
}
public function getEmail(){
return $this->emailAddress;
}
}
I know it is not the best example or practice...but how can I have a global MySQL access in all my classes without being required to have the config file included.
What is the best practice nowadays?
Make a global Instance:
//db.php include once
class DB {
#bind connenction in it
}
#make instance
$db = new DB($config);#use for User Instances
and then:
class User {
private $db;
private $firstName;
private $familyName;
private $emailAddress;
public function __construct($db) {
$this->db=$db;
}
public function validate($username, $password,$db) {
//check if user with name and pass exist in DB
//If user exist, populate member variables
$this->emailAddress = ...
}
public function getEmail(){
return $this->emailAddress;
}
}
$user = new User($db);
Is one way.
But you telling to less about how you want to use the classes.
I would go with PHPAcademy's login/register tutorial. He have DB class that handles almost anything you need. Here is sample of his code, slightly modified by me, but all credits to Alex Garrett.
<?php
class DB {
private static $_instance = null;
private $_pdo,
$_query,
$_error = false,
$_results,
$_count = 0;
private function __construct() {
try {
$this->_pdo = new PDO('mysql:host=' . Config::get('mysql/host') . ';dbname=' . Config::get('mysql/db'), Config::get('mysql/username'), Config::get('mysql/password'));
} catch(PDOException $e) {
die($e->getMessage());
}
}
public static function getInstance() {
if(!isset(self::$_instance)) {
self::$_instance = new DB();
}
return self::$_instance;
}
public function query($sql, $params = array()) {
$this->_error = false;
if($this->_query = $this->_pdo->prepare($sql)) {
$x = 1;
if(count($params)) {
foreach($params as $param) {
if (is_int($param)) {
$this->_query->bindValue($x, $param, PDO::PARAM_INT);
} else {
$this->_query->bindValue($x, $param);
}
$x++;
}
}
if($this->_query->execute()) {
$this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
$this->_count = $this->_query->rowCount();
}
else {
$this->_error = true;
print_r($this->_query->errorInfo());
}
}
return $this;
}
public function action($action, $table, $where = array()) {
if(count($where) === 3){
$operators = array('=', '>', '<', '>=', '<=', '!=');
$field = $where[0];
$operator = $where[1];
$value = $where[2];
if(in_array($operator, $operators)) {
$sql = "{$action} FROM {$table} WHERE {$field} {$operator} ?";
if(!$this->query($sql, array($value))->error()) {
return $this;
}
}
} else if (count($where) === 0) {
$sql = "{$action} FROM {$table}";
if(!$this->query($sql)->error()) {
return $this;
}
}
return false;
}
public function get($table, $where) {
return $this->action('SELECT *', $table, $where);
}
public function delete($table, $where) {
return $this->action('DELETE', $table, $where);
}
public function getAll($table) {
return $this->action('SELECT *', $table);
}
public function first() {
return $this->results()[0];
}
public function last() {
$i = count($this->results()) - 1;
return $this->results()[$i];
}
public function insert($table, $fields = array()) {
if(count($fields)) {
$keys = array_keys($fields);
$values = '';
$x = 1;
foreach ($fields as $field) {
$values .= '?';
if($x < count($fields)) {
$values .= ', ';
}
$x++;
}
$sql = "INSERT INTO {$table} (`" . implode('` , `', $keys) . "`) VALUES({$values})";
if (!$this->query($sql, $fields)->error()) {
return true;
}
}
return false;
}
public function update($table, $where, $parametar, $fields) {
$set = '';
$x = 1;
foreach ($fields as $name => $value) {
$set .= "{$name} = ?";
if ($x < count($fields)) {
$set .= ', ';
}
$x++;
}
if (is_int($parametar)) {
$sql = "UPDATE {$table} SET {$set} WHERE {$where} = {$parametar}";
} else {
$sql = "UPDATE {$table} SET {$set} WHERE {$where} = '{$parametar}'";
}
if (!$this->query($sql, $fields)->error()) {
return true;
}
return false;
}
public function results() {
return $this->_results;
}
public function error() {
return $this->_error;
}
public function count() {
return $this->_count;
}
}
Then you can query database like DB::getInstance()->getAll('tableName')->results();. Change DB credentials in __construct, or watch his videos (which I recomend).
hello i have this code for login and register in PHP OOP
<?php
class DB {
public static $instance = null;
private $_pdo = null,
$_query = null,
$_error = false,
$_results = null,
$_count = 0;
private function __construct() {
try {
$this->_pdo = new PDO('mysql:host=' . Config::get('mysql/host') . ';dbname=' . Config::get('mysql/db'), Config::get('mysql/username'), Config::get('mysql/password'), array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
//$this->query('SET NAMES utf8');
} catch(PDOExeption $e) {
die($e->getMessage());
}
}
public static function getInstance() {
if(!isset(self::$instance)) {
self::$instance = new DB();
}
return self::$instance;
}
public function query($sql, $params = array()) {
$this->_error = false;
if($this->_query = $this->_pdo->prepare($sql)) {
$x = 1;
if(count($params)) {
foreach($params as $param) {
$this->_query->bindValue($x, $param);
$x++;
}
}
if($this->_query->execute()) {
$this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
$this->_count = $this->_query->rowCount();
} else {
$this->_error = true;
}
}
return $this;
}
public function get($table, $where) {
return $this->action('SELECT *', $table, $where);
}
public function delete($table, $where) {
return $this->action('DELETE', $table, $where);
}
public function action($action, $table, $where = array()) {
if(count($where) === 3) {
$operators = array('=', '>', '<', '>=', '<=');
$field = $where[0];
$operator = $where[1];
$value = $where[2];
if(in_array($operator, $operators)) {
$sql = "{$action} FROM {$table} WHERE {$field} {$operator} ?";
if(!$this->query($sql, array($value))->error()) {
return $this;
}
}
return false;
}
}
public function insert($table, $fields = array()) {
$keys = array_keys($fields);
$values = null;
$x = 1;
foreach($fields as $value) {
$values .= "?";
if($x < count($fields)) {
$values .= ', ';
}
$x++;
}
$sql = "INSERT INTO {$table} (`" . implode('`, `', $keys) . "`) VALUES ({$values})";
if(!$this->query($sql, $fields)->error()) {
return true;
}
return false;
}
public function update($table, $id, $fields = array()) {
$set = null;
$x = 1;
foreach($fields as $name => $value) {
$set .= "{$name} = ?";
if($x < count($fields)) {
$set .= ', ';
}
$x++;
}
$sql = "UPDATE {$table} SET {$set} WHERE id = {$id}";
if(!$this->query($sql, $fields)->error()) {
return true;
}
return false;
}
public function results() {
// Return result object
return $this->_results;
}
public function first() {
return $this->_results[0];
}
public function count() {
// Return count
return $this->_count;
}
public function error() {
return $this->_error;
}
public function lastInsertId(){
return $this->_pdo->lastInsertId();
}
public function __sleep(){
return array();
}
}
and i save the user login data in session, everything works fine in localhost, but in my web server i have a problem in the line $this->_query->bindValue($x, $param);
Catchable fatal error: Object of class __PHP_Incomplete_Class could not be converted to string in
i know that is something wrong with my session but i cant find whats the problem, and this is my session class
<?php
class Session {
public static function exists($name) {
return (isset($_SESSION[$name])) ? true : false;
}
public static function get($name) {
return $_SESSION[$name];
}
public static function put($name, $value) {
return $_SESSION[$name] = $value;
}
public static function delete($name) {
if(self::exists($name)) {
unset($_SESSION[$name]);
}
}
public static function flash($name, $string = null) {
if(self::exists($name)) {
$session = self::get($name);
self::delete($name);
return $session;
} else if ($string) {
self::put($name, $string);
}
}
}
please tell me if you can what i can to do with that error thank you very much.
and this is the code where i store my session
public function login($username = null, $password = null, $remember = false) {
if(!$username && !$password && $this->exists()) {
Session::put($this->_sessionName, $this->data()->id);
} else {
$user = $this->find($username);
if($user) {
if($this->data()->password === Hash::make($password, $this->data()->salt)) {
Session::put($this->_sessionName, $this->data()->id);
if($remember) {
$hash = Hash::unique();
$hashCheck = $this->_db->get(Config::get('mysql/tbl_user_sessions'), array('user_id', '=', $this->data()->id));
if(!$hashCheck->count()) {
$this->_db->insert(Config::get('mysql/tbl_user_sessions'), array(
'user_id' => $this->data()->id,
'hash' => $hash
));
} else {
$hash = $hashCheck->first()->hash;
}
Cookie::put($this->_cookieName, $hash, Config::get('remember/cookie_expiry'));
}
return true;
}
}
}
return false;
}
i just do var_dump of my session['user']
array(1) {
["user"]=> &object(__PHP_Incomplete_Class)#1 (6) {
["__PHP_Incomplete_Class_Name"]=> string(4) "User"
["_db":"User":private]=> object(__PHP_Incomplete_Class)#2 (1) {
["__PHP_Incomplete_Class_Name"]=> string(2) "DB"
}
["_sessionName":"User":private]=> string(4) "user"
["_cookieName":"User":private]=> string(4) "hash"
["_data":"User":private]=> object(stdClass)#3 (7) {
["id"]=> string(3) "144"
["username"]=> string(5) "admin"
["password"]=> string(64) "0611affa6664e471b939cd3197b49e0c3b47d146fc12a472c4275dbd85a7cd67"
["salt"]=> string(32) "458a0dbfbd9bdca381e50b8d753329ea"
["name"]=> string(12) "Artur Papyan"
["joined"]=> string(19) "2013-11-29 07:41:54"
["group"]=> string(1) "1"
}
["_isLoggedIn":"User":private]=> bool(true)
}
}
It looks as though you are attempting to output the result to a string, which it cannot do as the class returns an object.
Also, Referring to DB.php line 38 is a red herring, as it is displaying the error message to the called function.
$this->_query->bindValue($x, $param);
Instead look to where your code is calling the class, and how you are attempting to bind your variables within your code it's self, instead of the actual call to DB.php file.
I am building a membership system in php using sessions, functions and MySQL querys,
I have come across a problem or a error that I do not understand the meaning and how to correct it.
any help on this matter would be greatly appreciated.
Error reads
Fatal error: Call to a member function error() on a non-object in /home/ob219/public_html/membership/index.php on line 6
code for index
$user = DB::getInstance()->get('users', array('username', '=', 'ben'));
if($user->error()) {
echo 'No user';
} else {
echo 'OK!';
}
db.php function
public function action($action, $table, $where = array()) {
if(count($where) === 3) {
$operators = array('=', '>', '<', '>=', '<=');
$field = $where[0];
$operator = $where[1];
$value = $where[2];
if(in_array($operator, $operators)) {
$sql = "{$action} FROM {$table} WHERE {$field} {$operator} ?";
if(!$this->query($sql, array($value))->error()) {
return $this;
}
}
}
return false;
}
public function get($table, $where) {
return $this->action('SELECT *', $table, $where);
}
public function delete($table, $where) {
return $this->action('DELETE', $table, $where);
}
public function error() {
return $this->_error;
}
was a simple error, I had Users as table name, and in index.php I had users.
Solution
<?php
require_once 'core/init.php';
$user = DB::getInstance()->get('Users', array('username', '=', 'ben'));
if((!$user->count())) {
echo 'No user';
} else {
echo 'OK!';
}