php - Invalid argument supplied for foreach() [closed] - php

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
hey i try to use the foreach function and i get this error...my code goes like this.
My index.php
require_once 'core/init.php';
$user = DB::getInstance()->get('users', array('username', '=', 'kostas'));
if(!$user->count()) {
echo "No user";
}else {
foreach ($user->results() as $user) {
# code...
echo $user->username, '<br>';
}
}
and my DB.php has those functions
<?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) {
$this->_query->bindValue($x, $param);
$x++;
}
}
if($this->_query->execute()){
$this->_reults = $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 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 error() {
return $this->_error;
}
public function count() {
return $this->_count;
}
}
?>
Could you please tell me what possibly goes wrong here???
My database has already a table with the username kostas in the users table so it should returned the result corectly.

try different name for your variable
foreach ($user->results() as $u) {
//# code...
echo $u->username, '<br>';
}

foreach ($user->results() as $user) {
You are using the same variable twice here, could that be the problem?
You could rename one of the variables. Here I renamed the first $user to $userQuery, as I think this is clearer:
$userQuery = DB::getInstance()->get('users', array('username', '=', 'kostas'));
if(!$userQuery->count()) {
echo "No user";
}else {
foreach ($userQuery->results() as $user) {
# code...
echo $user->username, '<br>';
}
}
Or you can rename the variable in the foreach:
foreach ($user->results() as $usr) {

Related

PHP OOP boolean error

I have got the following error:
Fatal error: Uncaught Error: Call to a member function count() on boolean in C:\xampp\htdocs\pianocourse101\index.php:5 Stack trace: #0 {main} thrown in C:\xampp\htdocs\pianocourse101\index.php on line 5
I have been wondering whether is the error part of my function count in my db.php or from index.php? Here is my code:
db.php
<?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;
// set the error to false so that we are not returning a previous error
if($this->_query = $this->_pdo->prepare($sql)) {
// check to see if query has been prepared properly
$x=1;
if(count($params)) { // check to see if need to bind
anything
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(); // to query a
database securely by binding parameters and preventing sql
injections
} else {
$this->_error = true;
}
}
return $this; // return the currenct object we are working with
}
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;
}// to check to see if operator is inside the operators .... We do a ? so that we can bind the value on
}
}
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;
}
public function count() {
return $this->_count;
}
}
index.php
<?php
require_once 'core/init.php';
$user = DB::getInstance()->get('users', array('username', '=', 'alex'));
if (!$user->count()) {
echo 'No user';
} else {
echo 'OK!';
}
Your get() method will always fail since it's generating an invalid SQL query.
Explanation
If we take your request:
$user = DB::getInstance()->get('users', array('username', '=', 'alex'));
and break it up to see what happens (this is the same thing as the above):
// This will work and return an instance of DB
$db = DB::getInstance();
// Will always fail and return false, since the get() method fails
$user = $db->get('users', array('username', '=', 'alex'));
// Since user is false (a boolean), it doesn't have any methods
$user->count()
So, why does it fail? Let's look in your DB class.
Let's start with the get() method:
public function get($table, $where){
// This is calling an internal method called "action()" passing three values
return $this->action('SELECT *', $table, $where);
}
and where it fails, the action() method:
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)) {
// The get() method passed 'SELECT *' to this method, so the below string will be
// "SELECT * * FROM users WHERE username = ?"
// (hint: it's the double * * that's invalid) .
$sql = "{$action} * FROM {$table} WHERE {$field} {$operator} ?";
if(!$this->query($sql, array($value))->error()) {
// Since the query fails, it will never come here
return $this;
}
}
}
// Since the query fails (is invalid), this is what it will return
return false;
}
Solution
A quick fix would be to change the action() method from:
$sql = "{$action} * FROM {$table} WHERE {$field} {$operator} ?"
to
$sql = "{$action} FROM {$table} WHERE {$field} {$operator} ?"
As I've mentioned in comments, you should look into proper error handling for PDO. Or better yet, use some tried and tested db library.
You mentioned that you are new to PHP and are going through some tutorial, the would recommend learning the basics step by step.

Why isn't my foreach loop displaying my mysql data?

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;
}

Fatal Error call to member function count() is non object

I am trying to query a database using pdo, but I cant figure out the problem. I have created an init file for my db details and server details and config file for configuration and index file and DB file.
index.php
<?php
require_once 'core/init.php';
$user = Db::getInstance()->get('users',array('username', '=' , 'raja' ));
if($user->count())
{
echo "No user";
}
else{
echo "OK!";
}
?>
Db.php
<?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 )
{
$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 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;
}
public function count()
{
return $this->_count;
}
}
?>
It reports a fatal error about not finding the count object:
Fatal error: Call to a member function count() on a non-object in
C:\xampp\htdocs\Student Management system\index.php on line 6
You want to declare the object -- just calling an instance from part of the object class returns just that, a non-complete object part. You're calling the function as if it's just a function rather than if it is part of the class as a whole, so then referencing any other parts of the class as a whole the logic is lost because PHP only views it as a get function alone.
To solve:
<?php
require_once 'core/init.php';
//here
$user = new Db();
$userSelect = $user->get('users',array('username', '=' , 'raja' ));
...
From this, $user is your object.
Sinlgeton
If you want to instead create the connection as a singleton, then each reference to a class method (~function) must be referenced with the singleton syntax - the reference to count() should therefore need to be rewritten into a Singleton syntax using :: instead of -> .
please read http://www.phptherightway.com/pages/Design-Patterns.html

Proper way to access database in PHP classes

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).

Unexpected PHP error: Call to a member function ... on a non-object [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
INDEX.PHP
$user = db::getInstance()->get('test', array('user_name', '=', 'rahul'));
if ($user->count()){
echo 'NO user';
} else {
echo 'Ok';
}
DB.PHP
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;
}
private function action($action, $table, $where){
if(count($where==3)) {
$opertors = array('=', '<', '>', '>=', '<=');
$field = $where[0];
$opertor = $where[1];
$value = $where[2];
if(in_array($opertor, $opertors)){
$sql = "{$action} FROM {$table} WHERE {$field} {$opertor} ?";
if (!$this->query($sql, array($value))->error()){
echo ' Go it';
return $this ;
}
}
}
return false;
}
public function get($table, $where){
return $this->action('SELECT *', $table, $where);
}
public function error(){
return $this->_error;
}
public function count(){
return $this->_count;
}
I am getting this error:
Fatal error: Call to a member function count() on a non-object in C:\wamp\www\ooplr\index.php on line 10
What am I missing?
Try this,
if(count($where)==3){
^^
instead of
if(count($where==3)){
You should check whether your db::getInstance()->get successfully returned the object. The following line:
if ($user->count()){
fails because $user is not an object here. The code follows:
$user = db::getInstance()->get('test', array('user_name', '=', 'rahul'));
if( !$user ) {
echo 'EVERYTHING GOES WRONG';
} else {
// OK, PROCESSING
}

Categories