Error: Call to a member function query () on null

0

I'm doing a crud with MVC and POO following a course and I get the following error

I take a while trying to solve the problem but I can not find a way, this is the file where the error marks me

    class EntidadBase{

            private $table;
            private $db;
            private $conectar;

            public function __contruct($table){

                $this->table = (string) $table;

                require_once 'Conectar.php';
                $this->conectar = new Conectar();
                $this->db = $this->conectar->Conexion();

            }

            public function getConectar(){      // Para sacar la conexion desde otros sitios solo llamandolo

                return $this->conectar;

            }

            public function db(){

                return $this->db;

            }

            public function getAll(){           

                $query = $this->db->query("SELECT * FROM $this->table ORDER BY id DESC"); // Linea que marca el error

                while($row = $query->fetch_object()){

                    $resultSet[] = $row;

                }

                return $resultSet;

            }

            public function getById($id){       // Consulta a un id especifico en la tabla

                $query = $this->db->query("SELECT * FROM $this->table WHERE id=$id");

                if($row = $query->fetch_object()){

                    $resultSet = $row;

                }

                return $resultSet;

            }

            public function getBy($column, $value){         // Consulta a una columna especifica con su valor especifico

                $query = $this->db->query("SELECT * FROM $this->table WHERE $column='$value'");

                while($row = $query->fetch_object()){

                    $resultSet[] = $row;

                }

                return $resultSet;

            }

            public function deleteById($id){            // Eliminar un elemento

                $query = $this->db->query("DELETE FROM $this->table WHERE id = $id");
                return $query;

            }

            public function deleteBy($column, $value){

                $query = $this->bd->query("DELETE FROM $this->table WHERE $column = '$value'");
                return $query;

            }

        }

Si alguien podría guiarme, apenas estoy empezando a aprender la 'POO'.

UserController Code

class UsuariosController extends ControladorBase{

        public function __construct(){

            parent::__construct();

        }

        public function index(){

            $usuario = new Usuario();

            $allUsers = $usuario->getAll();

            $this->view("index", array(
                "allUsers" => $allUsers,
                "Hola"     => "Ejemplo de MVC"
            ));

        }

        public function crear(){

            if(isset($_POST['nombre'])){

                $usuario = new Usuario();

                $nombre = $_POST['nombre'];
                $apellido = $_POST['apellido'];
                $email = $_POST['email'];
                $password = sha1($_POST['password']);

                $usuario->setNombre($nombre);
                $usuario->setApellido($apellido);
                $usuario->setEmail($email);
                $usuario->setPassword($password);

                $save = $usuario->save();

            }

            $this->redirect('Usuarios', 'index');

        }

        public function borrar(){

            if(isset($_GET['id'])){

                $id = (int)$_GET['id'];

                $usuario = new Usuario();
                $usuario->deleteById($id);

                $this->redirect();

            }

        }

    }

Users Code.php

class Usuario extends EntidadBase{

        private $id;
        private $nombre;
        private $apellido;
        private $email;
        private $password;

        public function __construct($table){

            $table = "usuarios";
            parent::__construct($table);

        }

        public function getId() {

            return $this->id;

        }

        public function setId($id) {

            $this->id = $id;

        }

        public function getNombre() {

            return $this->nombre;

        }

        public function setNombre($nombre) {

            $this->nombre = $nombre;

        }

        public function getApellido() {

            return $this->apellido;

        }

        public function setApellido($apellido) {

            $this->apellido = $apellido;

        }

        public function getEmail() {

            return $this->email;

        }

        public function setEmail($email) {

            $this->email = $email;

        }

        public function getPassword() {

            return $this->password;

        }

        public function setPassword($password) {

            $this->password = $password;

        }

        public function save(){

            $query = "INSERT INTO usuarios(id, nombre, apellido, email, password) 
                    VALUES (NULL,
                    '". $this->nombre ."',
                    '". $this->apellido ."',
                    '". $this->email ."',
                    '". $this->password ."')";

                    $save = $this->db()->query($query);

            return $save;

        }

    } 
    
asked by Edwin Aquino 09.03.2018 в 00:34
source

3 answers

0

Hi Edwin, I hope you are very well, you will see, as we are working with the MVC pattern and the OOP we should remember the modularity, that is, we should divide our application into smaller parts so that the development and debugging is done in a more easy. What I recommend is the following:

  • Do not make instances in the model, do so in the controller. See it this way: The model is an idea of what you want to do, for example: a house, this is where we put the idea, now, in the controller is where we instantiate and therefore we create our object or failing our house, if we instantiate inside the model it would be like creating our house and putting it in our head in the form of an idea, weird, right?

  • In your file called 'conecta.php' you can do the following:

  • abstract class Conexion extends PDO{
      private $respuestaConexion = false; //variable encargada de determinar el estado  de la conexion
      private $dbname = "xxx"; //el nombre de su base de datos
      private $host = "localhost"; //host
      private $port = 5432; //puerto
      private $user = "xxxx"; //usuario
      private $password = "xxxx"; //clave
      private $options = [
          PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION //reportes de excepciones
      ];
    
        protected function realizandoConexion(){
            try{
                parent::__construct("pgsql:dbname={$this->dbname};host={$this->host};port={$this->port}",$this->user,$this->password,$this->options);
                $this->respuestaConexion = true;
            }catch(PDOException $e){
                $this->respuestaConexion = false;
            }
        }
    
        protected function getStatusConexion(){
            return $this->respuestaConexion;
        }
    
        protected function cerrarConexion(){
            $this->respuestaConexion = false;
        }
    
    }
    

    What we do is create an abstract class in this way we will have an abstraction layer that PDO does not give us when using databases and it also helps us to use this class within the model without instantiating, let's see how your brother code:

    Model:

    require_once 'Conectar.php';
    
    class EntidadBase extends Conexion{ //Heredamos atributos y metodos de la clase 'Conexion' para usarlos en nuestra clase 'EntidadBase'
    
        private $table;
    
        public function __contruct($table){
    
            $this->table = (string) $table;
            Conexion::realizandoConexion(); //Utilizamos el metodo llamado 'relizandoConexion' perteneciente a la clase 'Conexion' definida en nuestro archivo 'Conexion.php' 
            if(Conexion::getStatusConexion() == true){//Verificamos el estado de la conexion
                return "Conexion Establecida.";
            }else{
                return "Conexion Fallida.";
            }
        }
    
        public function getAll(){           
    
            $query = Conexion::prepare("SELECT * FROM :table ORDER BY id DESC"); // Linea que marca el error
            $query -> bindParam(':table',$this->table,PDO::PARAM_STR); //Relacionamos el parametro de entrada '$this->table' al nombre de la variable ':table'
            $query -> execute(); //ejecutamos consulta
            return $query -> fetchAll(PDO::FETCH_OBJ); //la variable '$query' retornará los registros especificados en la consulta SQL, esto lo usaremos en el controlador gracias a la palabra reservada 'return'
    
            //A PARTIR DE AQUI PUEDES SEGUIR EL MISMO EJEMPLO
            //Reemplazarás $this->db por Conexion::
            //Utiliza 'binParam' al momento de realizar la consulta ya que tienes parametros de entrada
            //Todos esos 'while' te recomiendo cambiarlos por 'foreach' y usarlos en la vista, más abajo te daré un ejemplo
    
        }
    
        public function getById($id){       // Consulta a un id especifico en la tabla
    
            $query = $this->db->query("SELECT * FROM $this->table WHERE id=$id");
    
            if($row = $query->fetch_object()){
    
                $resultSet = $row;
    
            }
    
            return $resultSet;
    
        }
    
        public function getBy($column, $value){         // Consulta a una columna especifica con su valor especifico
    
            $query = $this->db->query("SELECT * FROM $this->table WHERE $column='$value'");
    
            while($row = $query->fetch_object()){
    
                $resultSet[] = $row;
    
            }
    
            return $resultSet;
    
        }
    
        public function deleteById($id){            // Eliminar un elemento
    
            $query = $this->db->query("DELETE FROM $this->table WHERE id = $id");
            return $query;
    
        }
    
        public function deleteBy($column, $value){
    
            $query = $this->bd->query("DELETE FROM $this->table WHERE $column = '$value'");
            return $query;
    
        }
    
    }
    

    Controller:

    <?php    
        require_once 'modelo.php'; //Incluimos el archivo que tenemos en la conexion
        $EntidadBase = new EntidadBase(); //Instaciamos 
        $datosEB = $EntidadBase -> getAll(); //El metodo getAll() retorna los registros de tu tabla, esos registros se guardarán en $datosEB
        require_once 'vista.php';
    ?>
    

    View:

    foreach($datosEB as $var){
        //AQUI VAN LAS FILAS QUE QUIERES QUE SE IMPRIMAN, POR EJEMPLO, OJO, SOLO ES UN EJEMPLOO, USTED LO HARA CON CADA UNA DE SUS COLUMNAS EN LAS CUALES QUIERE QUE SE IMPRIMAN DATOS
         echo "<tr>"; 
    
            echo "<td class='text-center'>{$var["id"]}</td>";
            echo "<td class='text-center'>{$var["nombre_triun"]}</td>";
            echo "<td class='text-center'>{$var["apellido_triun"]}</td>";
            echo "<td class='text-center'>{$var["cedula_triun"]}</td>";
            echo "<td class='text-center'>{$var["trayecto_triun"]}</td>";
            echo "<td class='text-center'>{$var["seccion_triun"]}</td>";
            echo "<td class='text-center'>{$var["condicion_triun"]}</td>";
    
            echo "<td>";
            echo "<a href='../controlador/anadir-triunfador-controlador.php'><input type='text' class='btn btn-success' value='Añadir'></a>
    
              <a href='../controlador/actualizar-triunfador-controlador.php'><input  type='text' class='btn btn-primary' value='Actualizar'></a>
    
              <a href='../controlador/buscar-triunfador-controlador.php'><input  type='text' class='btn btn-info' value='Buscar'></a>
    
              <a href='../controlador/eliminar-triunfador-controlador.php?<?php echo'id=1'; ?><input  type='text' class='btn btn-danger' value='Eliminar'></a>
              </td>";
               echo "</tr>";
    }
    

    ' Remember in the model all our ideas go, in the controller they are created, those ideas are materialized and in the view we show this creation to the world: D I hope my answer has helped you.

      

    The code has already been previously implemented by my person in a System, likewise apologizes if an error occurs.

        
    answered by 09.03.2018 в 04:32
    0

    Look at the constructor of the class Usuario , it has this header:

     public function __construct($table){
            $table = "usuarios";
            parent::__construct($table);
    
        }
    

    Wait for the value of the table as parametre, but when the instances in UsuariosController are not providing any value to you, it is more that value is already defined within the constructor of the user class.

    Instances like this:

    $usuario = new Usuario();

    Try changing the constructor of the class Usuario in this way:

        public function __construct(){
    
            $table = "usuarios";
            parent::__construct($table);
    
        }
    
        
    answered by 09.03.2018 в 15:37
    0

    Hello friend, sorry for the response delay, I just came from the university, well my brother now, we gladly clear up doubts, to check the status of the connection in our conditional structure we can do the following:

    1- We will create a new method or function called for example 'conexionActual' and inside it you will place the conditional (you remove it from the constructor and place it inside the new created method).

    2- In your model change within if and else the reserved word return by echo , in the model is good practice to use return and the more we are using MVC for us it should be mandatory, take it as usual sister, but for test effect we will place a echo only for this test : D your new method within your class EntityBase would look like this:

    public function conexionActual()
    {
        if(Conexion::getStatusConexion() == true){//Verificamos el estado de la conexion
            echo "Conexion Establecida.";
        }else{
            echo "Conexion Fallida.";
        }
    }
    

    And at the end of your class instances normally, then we will print our character string "Connection Established." or "Failed Connection." It all depends if the connection was made or not, it would be something like this:

    $con = new EntidadBase(); //Instanciamos normalmente
    print_r($con->conexionActual()); //El objeto "$con" utiliza el metodo "conexionActual" y esto lo que hace es imprimirnos el mensaje de acuerdo a lo que haya sucedido en nuestro condicional (si se estableció la conexión o no)
    

    And so we would check my brother: D I think it is appropriate to mention that in our file 'conexion.php' we have a method called getStatusConexion and within this method we have a variable called $ this- > answerConnection; if we review well we will realize that we initialize it in false and in our try if the connection is made correctly the value of this variable will change to true if the connection fails within our catch the same variable is found but its value false is maintained, when we in our class EntityBase we use the Connection :: getStatusConexion () method in the if we are saying that if the variable within of that method is equal to true so if the connection was successful, it would print a message "Conexion Est established. ", otherwise you will print a different message" Connection Failed. " then after instantiating we use the new created method called conexionActual and through it the messages will come to the light of the outside world and we will be able to see them: D this is the cold run of that portion of my brother code, I hope you have dispelled the doubt you had, luck and always forward.

      

    In case of having instantiated in the controller erase that instance and you only have what I mentioned in the brother model;)

        
    answered by 10.03.2018 в 00:35