How PDOStatement :: fetchObject works

3

I'm trying to set the values returned from a query to an object of another class as follows:

public function select($id,Cliente $cliente) {
    $query = "SELECT * FROM compras WHERE id = :id AND email = :email";
    $stm = $this->conexao->prepare($query);
    //SETANDO PARAMETROS DA QUERY
    $stm->bindValue(':id',$id);
    $stm->bindValue(':email',$cliente->getEmail());
    //EXECUTANDO QUERY
    $stm->execute();
    //OBTENDO RESULTADO
    if($resultado = $stm->fetchObject('Compra')) {
      return $resultado;
    } else {
      return false;
    }
  }//select

How do I mount the magic% object_com% of the Purchase object?

    
asked by anonymous 07.10.2016 / 18:21

1 answer

4

In this case, you do not need to define a constructor. When you use PDOStatement::fetchObject to determine which object will be used to represent the data coming from a query, PDO will set values to properties directly, in the way that a simple array is made.

To understand this, you first need to understand that in PHP, for you to define a property value of a class, you do not need to declare it in the class. You can simply assign it directly, of course, as long as it has not been declared in the class as protected or private .

See:

Obj {
      public $nome;
}

$obj = new Obj;

$obj->nome = "Wallace"; // declarado
$obj->idade = 26; // Não declarado


var_dump($obj);

The result is:

object(Obj)#168 (2) {
  ["nome"]=>
  string(7) "Wallace"
  ["idade"]=>
  int(26)
}

Using magic methods

When you asked about the definition in the constructor, it was completely understandable that you want to add a behavior to your class to define how the values will be defined.

As I said, this is not possible with the constructor because PDOStatement::fetchObject does not use the constructor, but it will assign the values one by one (externally, so to speak).

The solution to circumvent this problem is to use the magic method called __set . With it you determine behavior for your class when a property is not declared or accessible in your object.

Example:

public function Obj {
      protected $items;

      public function __set($key, $value) {
            $this->items[$key] = $value;
      }
}

So the results would be different.

See:

$obj = new Obj;
$obj->nome = "Wallace";
$obj->idade = 26;

object(Obj)#165 (1) {
  ["items":protected]=>
  array(2) {
    ["nome"]=>
    string(7) "Wallace"
    ["idade"]=>
    int(26)
  }
}

Using the constructor

If you want to use the constructor, you will have to pass the desired results manually to the constructor.

 $array = $stmt->fetch(PDO::FETCH_ASSOC);

 new Obj($array);
    
07.10.2016 / 18:32