Class does not show table values

1

I would like to know why the values of the query are not shown in the class array.

    public function login($usuario, $clave){
        try {
                $query = "SELECT usuario, privilegio, estado FROM sc_usuario WHERE usuario = :usuario AND clave = :clave";

                $BD = new conecta();

                $resultado = $BD->prepare($query);
                $resultado->bindParam(":usuario", $usuario, PDO::PARAM_STR);
                $resultado->bindParam(':clave', $clave, PDO::PARAM_STR);
                $resultado->execute();

                while ($fila = $resultado->fetch(PDO::FETCH_ASSOC)) {
                    $usuario = new UsuarioVO(   $fila['usuario'],
                                                $fila['privilegio'],
                                                $fila['estado']
                                            );
                }

                return $usuario;

This is the User class

    public function getUsuario(){
        return $this->usuario;
    }

    public function setUsuario($usuario){
        $this->usuario = $usuario;
    }

    public function getClave(){
        return $this->clave;
    }

    public function setClave($clave){
        $this->clave = $clave;
    }
etc....

The table has 5 fields: user, password, privilege, status, idperson And in the loguin function I want to capture only User, Privilege and Status.

And if I do a print_r ($ user) after while {} it shows me

usuarioVO Object ( [usuario:usuarioVO:private] => [clave:usuarioVO:private] => [privilegio:usuarioVO:private] => [estado:usuarioVO:private] => [idpersona:usuarioVO:private] => )

He shows them empty and shows me all the fields. What is the problem?

    
asked by Piropeator 10.02.2018 в 21:26
source

1 answer

1

The problem in this case is that your class should:

  • Having declared the members that represent the entity UsuarioVO . Which are usually private
  • Have a method constructor which, according to the logic of your program, should receive in parameter the value of each member of the class and assign it by $this .

We are going to apply this. I will comment in the same code some aspects to take into account.

Class:

class UsuarioVO
{
    private $usuario;
    private $privilegio;
    private $estado;
    private $clave;

    /*
     *Cada parémetro lo declaramos como $parametro=NULL
     *para poder crear instancias de la clase sin parámetros
     *o sólo con algunos parámetros determinados
     *Si no lo hacemos así, tendremos un montón de
     *Warning:  Missing argument  
     *por cada parámetro que omitamos al crear instancias de la clase
     */

    public function __construct($usuario=NULL, $privilegio=NULL, $estado=NULL)
    {
     /*
      *Asignamos los valores recibidos a cada miembro de la clase
     */
        $this->usuario=$usuario;
        $this->privilegio=$privilegio;
        $this->estado=$estado;
    }


    public function getUsuario(){
        return $this->usuario;
    }

    public function setUsuario($usuario){
        $this->usuario = $usuario;
    }

    public function getClave(){
        return $this->clave;
    }

    public function setClave($clave){
        $this->clave = $clave;
    }

    public function getUsuario(){
        return $this->usuario;
    }

    public function setUsuario($usuario){
        $this->usuario = $usuario;
    }

    public function getClave(){
        return $this->clave;
    }

    public function setClave($clave){
        $this->clave = $clave;
    }
}

Function% co_of%

I will allow myself to optimize it. In PDO you do not need login (see comment in the code).

Also, if you only wait one row in the result, put bindParam at the end of the query: LIMIT 1 , and in that case access the result without needing SELECT usuario, privilegio, estado FROM sc_usuario WHERE usuario = :usuario AND clave = :clave LIMIT 1 , doing this: while . (I have not corrected that in the code because I do not know if you expect one or more results.) Anyway, the instance of the class will save only the last result found inside the $fila = $resultado->fetch(PDO::FETCH_ASSOC); , so the while does not make sense to use it in this case).

public function login($usuario, $clave){
    try {
            /*Convendría usar LIMIT 1*/
            $query = "SELECT usuario, privilegio, estado FROM sc_usuario WHERE usuario = :usuario AND clave = :clave"; 

            $BD = new conecta();

            $resultado = $BD->prepare($query);
            /*Creamos un array con los parámetros*/
            $arrParams=array(":usuario"=>$usuario, ":clave"=>$clave);
            /*Pasamos los parámetros en el execute*/
            $resultado->execute($arrParams);

            while ($fila = $resultado->fetch(PDO::FETCH_ASSOC)) {
                $usuario = new UsuarioVO(   $fila['usuario'],
                                            $fila['privilegio'],
                                            $fila['estado']
                                        );
            }

            return $usuario;
        }
        //... resto del código

Another possible way to do it

In PDO we can obtain an instance of our class mapped from the result set. In that way, we work with that object using their own methods. That's the purpose of while :

  

PDO::FETCH_CLASS : returns a new instance of the requested class, matching the columns of the result set with the names of the properties of the class, and calling the constructor afterwards, unless PDO::FETCH_CLASS is also provided. If PDO::FETCH_PROPS_LATE includes fetch_style (for example, PDO::FETCH_CLASSTYPE ), then the name of the class is determined from the value of the first column.

     

PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE in the PHP Manual

Since you raised the question in a comment, when we use PDO::FETCH_CLASS we do not invoke all fields of the class, but we indicate to PDO what the mode of obtaining for this statement should be .

However, when you do setFetchMode , you will have a complete object in $usuario = $stmt->fetch() , but this is the same as if you do $usuario , that is, a full instance of the class is created.

In the tests I have done, if the members of the class have the same name as the columns in the table, PDO intelligently assigns the member. That is, in a new UsuarioVO where you use only one column or certain columns, PDO assigns the value obtained to each column, I think based on the name (it would be something interesting to explore later). Columns that are not included in SELECT PDO assign them the value SELECT .

Clarified this, if you are interested in this form, you could proceed more or less like this:

Class:

The NULL could look like this. You will see that we do not put anything in the constructor. PDO will assign each member its corresponding value.

class UsuarioVO
{
    private $usuario;
    private $privilegio;
    private $estado;
    private $clave;

    public function __construct()
    {

    }   

    public function getUsuario(){
        return $this->usuario;
    }

    public function setUsuario($usuario){
        $this->usuario = $usuario;
    }

    public function getClave(){
        return $this->clave;
    }

    public function setClave($clave){
        $this->clave = $clave;
    }
}

Query:

First, you should include your class with Clase or include .

Then, in the code:

public function login($usuario, $clave){
    try {
            $query = "SELECT usuario, privilegio, estado FROM sc_usuario WHERE usuario = :usuario AND clave = :clave LIMIT 1";

            $BD = new conecta();

            $stmt = $BD->prepare($query);
            /*Creamos un array con los parámetros*/
            $arrParams=array(":usuario"=>$usuario, ":clave"=>$clave);
            /*Pasamos los parámetros en el execute*/
            $stmt->execute($arrParams);

            $stmt->setFetchMode(PDO::FETCH_CLASS, 'UsuarioVO' );
            $stmt->execute();
            $usuario = $stmt->fetch();
            return $usuario;
        }
        //... resto del código

You will notice that I have added require to the query. I guess you expect a single row in the query. The LIMIT 1 is also not necessary. Here, if there are several results, there will be only one instance of the class with the last value. If you need an instance for each value, then the while would make sense, but you should create an array of objects while ...

What has happened above has been:

  • with UsuarioVO we tell PDO that we want an instance of class setFetchMode in the results.
  • once the query has been executed, we assign the new object in a variable: UsuarioVO
  • we return that object. You can access each value by calling the methods of the class. For example, for the $usuario = $stmt->fetch(); , you would: usuario

If you do a echo $persona->getUsuario(); , you will see something similar to this result (it is a proof of concept that I did, applying the code explained above). You will see that there is a var_dump($usuario) object in this case and each column of the Persona has been assigned to the different members of the class.:

object(Persona)#4 (3) {
  ["persona_id":"Persona":private]=>
  string(1) "2"
  ["persona_nom":"Persona":private]=>
  string(8) "Santiago"
  ["ciudad_id"]=>
  string(1) "2"
}

This is a little known utility of PDO and it can be very interesting when we work with SELECT .

I hope it serves you.

    
answered by 11.02.2018 / 01:03
source