Error connecting to the BDD through a class

1

I am using a class that a user provided me with in a question that I published some time ago.

The fact is that through this class I can make the connection to the database and make queries, etc.

I was doing a connection test when when executing a query the following error appeared:

  

Notice: Undefined property: Db :: $ stmt in   C: \ xampp \ htdocs \ php \ data_conexion.php on line 94

     

Fatal error: Uncaught Error: Call to a member function bindValue () on   null in C: \ xampp \ htdocs \ php \ data_conexion.php: 94 Stack trace: # 0   C: \ xampp \ htdocs \ php \ index.php (22): Db-> bind (': user', 'gmarsi') # 1   {main} thrown in C: \ xampp \ htdocs \ php \ data_conexion.php on line 94

The code I use is this:

<?php 

require("datos_conexion.php");

$dbObj = new Db();
$pdoObj = $dbObj -> getInstance();

$user = '';
$name = 'marcos';
$user = 'gmarsi';
$data = 'SELECT User_User FROM users WHERE User_Punc > 0 ';

if($user != ''){
    $data .= " AND User_User = :user ";
    $pdoObj -> bind(':user', 'gmarsi');
} 

if($name != ''){
    $data .= " AND User_Name = :name ";
    $pdoObj -> bind(':name', $name);
} 

echo $data;
$pdoObj -> query($data);
$resultado = $pdoObj ->resultset();

foreach($resultado as $row){
    echo '<br>'.$row['User_User'];
}

?>

And the class in question is this:

<?php
class Db 
{

private $host      = 'localhost';
private $user      = 'admin';
private $dbname    = 'baseDeDatos';
private $pass      = 'contraseña';
private static $instance;

public function __construct()
{
    // DSN: cadena de conexión
    $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;

    /* Opciones
        * Muy importante, para tener una buena conexión PDO

    */    
    $options = array(
        PDO::ATTR_PERSISTENT => true, //establecer a false si no se quieren conexiones persistentes
        PDO::ATTR_EMULATE_PREPARES => false, //no cambiar nunca
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //no cambiar nunca
        PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'" //juego de caracteres
    );

    // Crea nueva instancia de PDO
    try{
        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
    }
    // Captura los errores
    catch(PDOException $e){
        $this->error = $e->getMessage();
    }
}



public static function getInstance()
{
    if (self::$instance == null) 
    {
        $className = __CLASS__;
        self::$instance = new $className();
    }
    return self::$instance;
}



 /******************************************** MÉTODOS IMPRESCINDIBLES */

//Recibe las consultas
public function query($query)
{
    $this->stmt = $this->dbh->prepare($query);
}

//Ejecuta las consultas
public function execute()
{
    return $this->stmt->execute();
}

//Devuelve resultados de la consulta en PDO::FETCH_ASSOC 
//Se puede cambiar o agregar otro método con otro tipo de resultado
public function resultset()
{
    $this->execute();
    return $this->stmt->fetchAll(PDO::FETCH_ASSOC);

}

//Envía los datos por separado para proteger de la inyección SQL
public function bind($param, $value, $type = null)
{
    if (is_null($type)) 
    {
        switch (true) 
        {
            case is_int($value):
                $type = PDO::PARAM_INT;
                break;
            case is_bool($value):
                $type = PDO::PARAM_BOOL;
                break;
            case is_null($value):
                $type = PDO::PARAM_NULL;
                break;
            default:
                $type = PDO::PARAM_STR;
        }
    }
    $this->stmt->bindValue($param, $value, PDO::PARAM_STR);
}

/********************************************** FIN MÉTODOS IMPRESCINDIBLES




/******************************************** MÉTODOS OPCIONALES */

//Devuelve el último registro insertado
public function lastInsertId()
{
    return $this->dbh->lastInsertId();
}

//Obtiene un registro simple
public function single()
{
    $this->execute();
    return $this->stmt->fetch(PDO::FETCH_ASSOC);
}


//Devuelve un solo valor, columna o 0
public function valor()
{
    $this->execute();
    $valor=$this->stmt->fetch(PDO::FETCH_COLUMN);
    return (empty($valor)) ? 0 : $valor;

}

//Verifica si un registro existe devolviendo true o false
public function si_existe()
{
    $this->execute();
    if ($this->stmt->fetch(PDO::FETCH_ASSOC))
    {
        return true;
    } 
    else 
    {
        return false;
    }
}
 /**********************************************/

}

?>

I leave the link to the answer where I got this class, since the user made an example of use. Here

    
asked by gmarsi 31.08.2017 в 10:05
source

1 answer

1

First you must fix the first error ( Undefined property: Db::$stmt ), because the property of the class is not defined:

<?php
class Db
{
    /* Definimos propiedades públicas */
    public $error = false, $stmt = false;
    /* ... */

To solve the second error, you must shield the code used by the class and call query first than bind (the first prepares the query and sets the value of stmt and the second uses stmt to set the value of the variables in the prepared query):

<?php

require("datos_conexion.php");

/* Para que funcione como fue diseñado hay llamar al método estático */
$pdoObj = \Db::getInstance();
if ($pdoObj->error !== false) {
    die($pdoObj->error);
}

$user = '';
$name = 'marcos';
$user = 'gmarsi';
$data = 'SELECT User_User FROM users WHERE User_Punc > 0 ';

/* Antes de hacer uso de bind debes preparar la consulta */
$pdoObj->query($data);
if ($pdoObj->stmt === false) {
    die('Ocurrió un error y la clase no permite ver el motivo');
}

/* Ahora sí podemos hacer uso de los bind */
if ($user != '') {
    $data .= " AND User_User = :user ";
    $pdoObj -> bind(':user', 'gmarsi');
}

if ($name != '') {
    $data .= " AND User_Name = :name ";
    $pdoObj -> bind(':name', $name);
}

$resultado = $pdoObj ->resultset();

foreach ($resultado as $row) {
    echo '<br>'.$row['User_User'];
}
    
answered by 31.08.2017 / 10:23
source