Error (SQLSTATE[HY000]: General error) in oop - php

I start to get this error when i add something in database i know what the problem but i tried to solve it but i could not
part of database class:
public function query($sql, $params = array()) {
$this->_error = FALSE;
$this->_query = $this->_conn->prepare($sql);
if ($this->_query) {
if (count($params)) {
$x = 1;
foreach ($params as $param) {
$this->_query->bindValue($x, $param);
$x++;
}
}
if ($this->_query->execute()) {
$this->_result = $this->_query->fetchAll(PDO::FETCH_OBJ);
$this->_count = $this->_query->rowCount();
} else {
return $this->_error = TRUE;
}
}
return $this;
}
public function insert($table, $fields = array()){
$keys = array_keys($fields);
$value = NULL;
$x = 1;
foreach ($fields as $field) {
$value .= '?';
if ($x < count($fields)) {
$value .=' , ';
}
$x++;
}
$sql = 'INSERT INTO ' . $table . '(`' . implode('`,`', $keys) . '`) VALUES (' . $value . ')';
if (!$this->query($sql, $fields)->error()) {
return TRUE;
}
return FALSE;
}
this when i insert the data in database
try {
$db->insert('users', array('username' => $_POST['username'],
'password' => $pass_hash,
'Group' => 0));
} catch (Exception $ex) {
die($ex->getMessage());
}
everything work fine and code insert the data in database but problem i get this error (SQLSTATE[HY000]: General error) because i am trying to fetch the data and i should not fetch it but i want my class be more dynamic , what the way i can fix this ? and thank you
problem form this line
$this->_result = $this->_query->fetchAll(PDO::FETCH_OBJ);

Related

Object of class Database could not be converted to string

i'm using this methode to get data from db
class Database {
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 Database();
}
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 insert($table, $fields = array()) {
if (count($fields)) {
$keys = array_keys($fields);
$values = null;
$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, $id, $fields = array()) {
$set = '';
$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 $this->_results;
}
public function first() {
return $this->_results[0];
}
public function error() {
return $this->_error;
}
public function count() {
return $this->_count;
}
}
this is what i want to get AND
this is my table
this is my code ...
public function getModule() {
$epreuve = $this->_db->get('epreuve', array('concour_code', '=', $this->data()->concour_code));
foreach($epreuve->results() as $epreuve){
echo "<tr><td>".$epreuve->designation."</td>"
.$module = $this->_db->get('module', array('epreuve_code', '=', $epreuve->code ));
foreach($module->results() as $module){
echo "<tr><td>".$epreuve->designation."</td>";
}
"</tr>";
}
}
but i have this error
'' Catchable fatal error: Object of class Database could not be converted to string ''
The error seems to be here:
echo "<tr><td>".$epreuve->designation."</td>"
.$module = $this->_db->get('module', array('epreuve_code', '=',
Note that you did not close echo with semi colon, and there is a dot before $module, so PHP is trying to string concat echo string with $module class plus the iteration also inside the concatenation. You cant do that.
Do the following:
public function getModule() {
$epreuve = $this->_db->get('epreuve', array('concour_code', '=', $this->data()->concour_code));
foreach($epreuve->results() as $epreuve){
echo "<tr>";
echo "<td>".$epreuve->designation."</td>";
$module = $this->_db->get('module', array('epreuve_code', '=', $epreuve->code ));
foreach($module->results() as $module){
echo "<td>".$epreuve->designation."</td>";
}
echo "</tr>";
}
}
Suggesiton:
On your code
foreach($epreuve->results() as $epreuve){
AND
foreach($module->results() as $module){
You should not use the same variable name of what you are iterating. Try change it to
public function getModule() {
$epreuve = $this->_db->get('epreuve', array('concour_code', '=', $this->data()->concour_code));
foreach($epreuve->results() as $epreu){
echo "<tr>";
echo "<td>".$epreu->designation."</td>";
$module = $this->_db->get('module', array('epreuve_code', '=', $epreu->code ));
foreach($module->results() as $mod){
echo "<td>".$epreu->designation."</td>";
}
echo "</tr>";
}
}
NOTE: The HTML table is a bit messy I tried by best to understand it. Change it to your needs.

Insert values to db with iterations

so here I'm trying to make an insert function which will be dynamic. By dynamic I mean that it can insert into any table and n number of columns. I'm making this function so that I don't have to write multiple functions to insert whenever I have to insert into different table or increase number of columns.
In my function, I'm passing 2 parameters. One is the tablename and second is the array of columns and their values in this way.
$arr = array("customerid" => "123",
"email" => "asa");
And here's my function :-
function insert_tester($table,$arr)
{
global $conn;
$val=0;
try
{
$s = $conn->prepare("INSERT INTO $table(" . foreach($arr as $column => $valule) {$column.","} . ")
VALUES(" . foreach($arr as $column => $value) {':val'.$val++} . ")");
$val=0;
foreach($arr as $column => $value)
{
$s->bindParam(":val$val", $value);
$val++;
}
if($s->execute())
{
return true;
}
else
{
return false;
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}//function
But unfortunately my function doesn't work, it says foreach not expected.
What would be the best and right way to achieve my target ?
This is what you exactly need, here $db is your PDO database connection object
function insert_tester($db, $table, $arr) {
$fields = array_keys($arr);
$values = array_values($arr);
//build the fields
$buildFields = '';
if (is_array($fields)) {
//loop through all the fields
foreach ($fields as $key => $field) {
if ($key == 0) {
//first item
$buildFields .= $field;
} else {
//every other item follows with a ","
$buildFields .= ', ' . $field;
}
}
} else {
//we are only inserting one field
$buildFields .= $fields;
}
//build the values
$buildValues = '';
if (is_array($values)) {
//loop through all the fields
foreach ($values as $key => $value) {
if ($key == 0) {
//first item
$buildValues .= '?';
} else {
//every other item follows with a ","
$buildValues .= ', ?';
}
}
} else {
//we are only inserting one field
$buildValues .= ':value';
}
$prepareInsert = $db->prepare('INSERT INTO ' . $table . '(' . $buildFields . ') VALUES (' . $buildValues . ')');
//execute the update for one or many values
if (is_array($values)) {
$prepareInsert->execute($values);
} else {
$prepareInsert->execute(array(':value' => $values));
}
//record and print any DB error that may be given
$error = $prepareInsert->errorInfo();
if ($error[1]) {
print_r($error);
} else {
return true;
}
}
Since you're using PDO, there's an easier way:
$names = join(',', array_keys($arr));
$values = substr(str_repeat(',?', count($arr)), 1);
$s = $conn->prepare("INSERT INTO $table ($names) VALUES ($values)");
if ($s->execute(array_values($arr))) {
return true;
}
This assumes your array keys and $table are valid table or column names in SQL.
I actually created a class that extends PDO just so that I could do what you want to do. Use this class instead of PDO when you instantiate your database connection. Then, you'll be able to use the insert, update, and delete methods directly on the database connection instance (i.e. $conn->insert('sometable', array() ); ).
I use this class quite frequently and thought you might appreciate the bonus methods besides insert($table, $data):
class DatabaseConnection extends PDO {
public function insert($table, $data) {
$fields = implode(", ", array_keys($data));
$questionMarks = rtrim( str_repeat("?, ", count($data)), ", ");
$stmt = $this->prepare("INSERT INTO $table ($fields) VALUES ($questionMarks)");
foreach (array_values($data) as $key => $value) {
$stmt->bindValue($key+1, $value);
}
//return $stmt;
return $stmt->execute();
}
public function update($table, $data, $conditions) {
$fields = implode("=?, ", array_keys($data))."=?";
foreach ($conditions as $column => $condition) {
if (empty($whereClause)) {
$whereClause = "$column=?";
} else {
$whereClause .= " AND $column=?";
}
$data[] = $condition;
}
$stmt = $this->prepare("UPDATE $table SET $fields WHERE $whereClause");
foreach (array_values($data) as $key => $value) {
$stmt->bindValue($key+1, $value);
}
//return $stmt;
return $stmt->execute();
}
public function delete($table, $conditions) {
$data = array();
foreach ($conditions as $column => $condition) {
if (empty($whereClause)) {
$whereClause = "$column=?";
} else {
$whereClause .= " AND $column=?";
}
$data[] = $condition;
}
$stmt = $this->prepare("DELETE FROM $table WHERE $whereClause");
foreach (array_values($data) as $key => $value) {
$stmt->bindValue($key+1, $value);
}
//return $stmt;
return $stmt->execute();
}
}
Try an implode on the keys
implode(', ', array_keys($arr));
And for your bindParms you can be clever and try
implode(', :', array_keys($arr));
You'll have to prefix the first one but that should get you on the right track

php Error trying to make a OOP login system

I keep getting the warning error while trying to make this object oriented log in system. I am trying to do the insert function right now but the warning is stopping me.
Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\YetiDraft\yetidb\classes\db.php on line 32
Line 32 is the function query foreach statement
<?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 insert($table, $fields = array()){
if(count($fields)){
$keys = array_keys($fields);
$values = '';
$x = 1;
foreach($fields as $fields){
$values .= "?";
if($x < count($fields)){
$values .= ', ';
}
$x++;
}
$sql = "INSERT INTO users (`" . implode('`, `', $keys) ."`) VALUES ({$values})";
if(!$this->query($sql, $fields)->error()){
return true;
}
}
return false;
}
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;
}
}
?>
This part might cause the problem:
foreach($fields as $fields){
$values .= "?";
if($x < count($fields)){
$values .= ', ';
}
$x++;
}
You are using the variable $fields both as source and as iterator.
Doing so overwrites $fields with the last element of the array. For this reason, in the following call, $fields is not an array anymore:
if(!$this->query($sql, $fields)->error()){
And since you are trying to iterate over the value of $fields in $this->query(), you are getting the error.
Thanks to Barmar for the tip!
Try this instead:
foreach($fields as $field){
$values .= "?";
if($x < count($fields)){
$values .= ', ';
}
$x++;
}
Edit: Or use Barmar's solution instead. His solution is better.
My guess is that $params isnt an array and hence isnt traversable. Make a small check before the foreach like this.
if (is_array($params))
{
foreach ($params as $param)
{
//do things here
}
}
count() is not a reliable way to check if a variable is an array. Use is_array instead of count(). Your error probably is the variable isnt an array, and you are trying to traverse through the variable.
Replace the loop:
foreach($fields as $field){
$values .= "?";
if($x < count($field)){
$values .= ', ';
}
$x++;
}
with
$values = implode(', ', array_fill(0, count($fields), '?'));
Because you're reusing the variable $fields as the iteration variable, when your loop is done $fields no longer contains an array of fields, it contains the value of the last field. So when you call $this->query($sql, $fields), you're passing a string instead of an array, and the foreach inside query() won't work.

Fatal error: Call to a member function count() on a non-object [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am learning PHP OOP by utilizing a PHP Academy tutorial. The tutorial is a Registration/Login system. I am having trouble on the "Remember Me" portion of the tutorial. This part of the tutorial retains a users selection to be able to stay logged in.
I am having an error:
"Fatal error: Call to a member function count() on a non-object in C:\xampp\htdocs\Rikarsen.hol.es\core\init.php on line 32
I have placed the PHP classes below to show what I have done thus far. Since I am new to PHP coding I am unable to locate the problem. Can anyone please help me? If any additional code is needed please let me know so I can supply it to you in order to help you discover my problem.
init.php
<?php
session_start();
$GLOBALS ['config'] = array(
'mysql' => array(
'host' => '127.0.0.1',
'username' => 'root',
'password' => '',
'db' => 'rikars'
),
'remember' => array(
'cookie_name' => 'hash',
'cookie_expiry' => 604800
),
'session' => array(
'session_name' => 'user',
'token_name' => 'token'
)
);
spl_autoload_register(function($class) {
require_once 'classes/' . $class . '.php';
});
require_once 'functions/sanitize.php';
if(Cookie::exists(Config::get('remember/cookie_name')) && Session::exists(Config::get('session/session_name'))) {
$hash = Cookie::get(Config::get('remember/cookie_name'));
$hashCheck = DB::getInstance()->get('users_sessions', array('hash', '=', $hash));
if($hashCheck->count()) {
echo 'asass';
}
}
I think I made a mistake in DB.php
<?php
class DB {
private static $_instance = null;
private $_pdo,
$_query,
$_error = false,
$_result,
$_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 insert($table, $fields = array()) {
$keys = array_keys($fields);
$values = null;
$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, $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}";
if($this->query($sql, $fields)->error()) {
return true;
}
return false;
}
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;
}
public function ins() {
$instance = DB::getInstance();
$instance->get('users',array('user_id','=','1'));
if (!$instance->Count()) {
echo 'No user';
} else {
echo 'User exists';
}
}
}
?>
Your method action return false but you expect object.
if(Cookie::exists(Config::get('remember/cookie_name')) && Session::exists(Config::get('session/session_name'))) {
$hash = Cookie::get(Config::get('remember/cookie_name'));
$hashCheck = DB::getInstance()->get('users_sessions', array('hash', '=', $hash));
if($hashCheck === false) {
echo 'Action return false';
} else {
$count = $hashCheck->count();
if($count) {
echo 'Its object and count ='.$count;
}
}
}
Make sure your table name and column names are correct in get method. I was having the same problem and this was the solution that worked for me.

PHP PDO SQL Server database issue

I'm using SQL Server as a database and PHP PDO to connect, When creating a registration page, I get this error when executing the query
Notice: Array to string conversion in C:\webdev\classes\DB.php on line 36
There was a problem creating an account.PHP Notice: Array to string conversion in C:\webdev\classes\DB.php on line 36
Line 36 - $this->_query->bindValue($x, $param);
<?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('sqlsrv:server=' . Config::get('sqlsrv/servername') . ';database=' . Config::get('sqlsrv/db'), Config::get('sqlsrv/username'), Config::get('sqlsrv/password'));
} catch(PDOExeption $e) {
die($e->getMessage());
}
}
public static function getInstance() {
// Already an instance of this? Return, if not, create.
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) {
/* Line 36 */ $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 users 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;
}}
Why would this be, I used the same code and had a mysql database and it sent the data to the db no problems, why would it be the case for SQL Server?
One of the $param iterations is coming in as an array probably:
if(count($params)) {
foreach($params as $param) {
if(is_array($param) || is_object($param)){ $param=''; }
$this->_query->bindValue($x, $param);
$x++;
}
}
Recommendation for debugging public function insert()
// add a debug parameter
public function insert($table, $fields = array(), $debug = false) {
$return = false;
if(is_array($fields) && count($fields) > 0 && $table != ''){
// build SQL and debug SQL
$sql = "INSERT INTO '$table' (";
$debug_sql = $sql;
// declare variables
$sql_fields = '';
$values = '';
$debug_values = '';
foreach($fields as $k=>$v) {
// encase fields and values in quotes
$sql_fields.= "'$k',";
$values.= "?,";
$debug_values.= "'$v',";
}
// remove trailing commas
$sql_fields = substr($sql_fields, 0, -1);
$values= substr($values, 0, -1);
$debug_values= substr($debug_values, 0, -1);
// finish SQL and debug SQL
$sql.= "$sql_fields) VALUES ($values)";
$debug_sql.= "$sql_fields) VALUES ($debug_values)";
if($debug === true) {
$return = $debug_sql;
}
else {
if(!$this->query($sql, $fields)->error()) {
$return = true;
}
}
}
return $return;
}
// now change the insert call to look like this
die($this->_db->insert('dbo.users', $fields, true)); // <-- notice the true parameter
/**
* Use the output to directly run the SQL from the MSSQL admin console or whatever they call it and it will provide a much more useful error description
*/

Categories