Establecer un objeto devuelto desde PDO en su propia clase

Tengo una clase llamada Admin , y tiene exactamente los mismos campos que los que están en mi tabla de admins en la base de datos: id , email , pwhash , pwnonce , name , permissions .

Mi clase se ve así (simplificado hacia abajo):

 class Admin { var $id, $email, $pwhash, $pwnonce, $name, $permissions; function auth() { // checks the session and attempts to authenticate the user } function login($email,$pw) { // authenticate the user and start a session for them. } } 

El problema es que quiero usar PDO para buscar un objeto usando la clase actual y asignarlo al objeto actual.

Antes, buscaba una matriz asociada y asignaba todas las variables una a una, pero ahora, dado que estoy cambiando mi sistema para usar PDO, quiero que devuelva una instancia de la clase Admin , que asigno al actual.

Por ejemplo, en el método auth() , debería ser algo como esto:

 function auth() { if (!isset($_SESSION['id'])) return false; $id = $_SESSION['id']; // create PDO connection and assign to $dbh $sth = $dbh->prepare('SELECT * FROM admins WHERE id = ?'); $sth->execute(array($id)); $sth->setFetchMode(PDO::FETCH_CLASS,get_class($this)); $obj = $sth->fetch(); if (!is_object($obj)) return false; $this = $obj; // I know this won't work, but anyway... } 

Así que lo intenté, y como había sospechado, no me deja asignar el valor de $this . Sin embargo, todavía quiero usar la funcionalidad de mapeo de objetos de PDO, entonces ¿cómo puedo asignar el objeto devuelto por PDO a la instancia en la que estoy?

En lugar de intentar anular $this , devuelve el objeto en cuestión:

 return $obj; 

Entonces úsalo así:

 $admin = $admin->auth(); 

Que anularía el objeto de administración actual.


Aunque un mejor enfoque sería asignar las variables al objeto actual, o usar una clase de abstracción, tendría más sentido.

Intenta decir lo que estás haciendo en voz alta. Le está diciendo a un Admin que se auth() y luego se reemplace por un nuevo Admin que esté autenticado. En su lugar, debe tener un AdminManager procesar la solicitud de autenticación y devolver un objeto Admin , o hacer que el Admin mismo se autentique y luego completar los detalles en ese mismo objeto.

Aparte de tener sentido, también está evitando duplicados y pérdidas de memoria en su aplicación.

Si quiere buscar un objeto nuevo de una clase determinada, usa PDO::FETCH_CLASS . Sin embargo, si desea escribir valores de propiedades en un objeto existente que ya tiene, use PDO::FETCH_INTO , así:

  $sth->setFetchMode(PDO::FETCH_INTO, $this); $sth->execute(); $sth->fetch(); 

Tenga en cuenta que las propiedades en las que desea escribir deben ser de acceso público, ya sea directamente o mediante un método mágico __set() .

Sin embargo, debes considerar cuidadosamente la respuesta de @ Truth. No es bueno tener la misma clase (¡mucho menos el mismo objeto !) Ser responsable tanto del acceso a la base de datos como de representar un registro. Haga que una clase sea responsable de administrar los registros de autorización y otra para los registros.

Podría usar la sobrecarga para redirigir cada llamada a su objeto de base de datos.

 class Admin { function auth() { // [...] $this->pdo_obj = $obj; } function __get($attribute) { return $this->pdo_obj->$attribute; } // Implement __set, __isset, ... here } 

A la variable que denominó $ obj se le asigna una matriz asociativa, que es lo que devuelve fetch (). Cada elemento de esa matriz tiene una clave que es el nombre de columna de la tabla y un valor que es el valor para esa fila y columna. Como tiene variables de instancia en su clase que corresponden a la misma, puede configurarlas con:

 $this->id = $obj['id']; $this->email = $obj['email']; 

… etc para cada uno.