2010-12-21 10 views
11

Nuestro equipo de desarrollo está debatiendo una mejor práctica general: ¿Es mejor acceder a una variable de sesión directamente desde una función en una clase de modelo o pase? la variable de sesión del controlador como un argumento para una función en la clase de modelo. Mira las dos ejemplos siguientes:PHP MVC Best Practice - Pasar la variable de sesión a la clase de modelo desde el controlador o acceder directamente en el modelo

Acceso variable de sesión directamente desde la clase del modelo a utilizar en una consulta:

class MyModel { 
    public function getUserPrefs($userID) { 
     $this->query("SELECT * FROM my_table WHERE id=$_SESSION['userID']"); 
    } 
} 

o pasar la variable de sesión desde el controlador a una función en la clase del modelo en función argumento:

class MyController { 
    public function displayUsers() { 
     $this->model->getUserPrefs($_SESSION['userID']); 
    } 
} 

class MyModel { 
    public function getUserPrefs($userID) { 
     $this->query("SELECT * FROM my_table WHERE id=$userID"); 
    } 
} 

el razonamiento para pasarlo al modelo desde el controlador está así que todos los datos que se hace referencia está llegando desde un punto de entrada, que siendo el controlador.

¿Qué se reconoce como una mejor práctica?

Respuesta

14

La segunda versión (pasando $ _SESSION ['userId'] como argumento para el método) da como resultado una clase más desacoplada, y por lo tanto más flexible. Ir con eso

+0

Sí, de ahí 'controller' es el objeto principal que decide qué se debe obtener de los modelos y se envía a las vistas. +1 – RobertPitt

+0

+1 Un controlador se llama controlador por un motivo. Su trabajo es controlar la entrada (una variable de sesión en ese caso) y pasarla al controlador apropiado (vista, modelo, biblioteca, etc.). – netcoder

+1

Una nota adicional es que creo que deberías estar usando una clase "envoltorio" llamada algo así como "Sesión" que incorpora toda la funcionalidad de obtener/configurar variables de sesión. De esta forma, puede cambiar a usar algo como Memcache con poco esfuerzo al cambiarlo en un archivo/clase. – MikeMurko

1

Tenga en cuenta que "sesión" es simplemente otro modelo. Sin embargo, el primer enfoque es inaceptable. ¿Qué sucede si desea buscar las preferencias de otros usuarios simplemente para compararlas con algo? Usa el segundo enfoque.

5

NUNCA desea tener variables de sesión en su modelo. Siempre debe pasar estas variables como parámetros a la función en el modelo. Esto también hace que su código sea más ampliable y flexible. Considere un modelo que obtiene un usuario por su id. Usted puede escribir una función como:

function find_by_id() { 
    // SELECT * FROM Users WHERE user_id = $_SESSION['user_id']; 
} 

Sin embargo, lo que si ahora lo que permite construir una funcionalidad de administración con una función de búsqueda de usuario? Su modelo está codificado para usar el user_id de la sesión, pero desea poder pasar su propia identificación. Usted sería mejor:

function find_by_id($id) { 
    // SELECT * FROM Users WHERE user_id = $_SESSION['user_id'] 
} 

y en su controlador

$user = Model::find_by_id(1); 
//or 
$user = Model::find_by_id($_SESSION['user_id']); 
//etc 

En este caso, sin embargo, yo realmente considerar la posibilidad de su código aún más flexible:

function find($ids) { 
    // this is sudo code, but you get the idea 
    if(is_array($ids)) 
    $ids = implode(',', $ids); // if an array of ids was passed, implode them with commas 
    SELECT * FROM Users WHERE user_id IN ($ids); 
} 

Esto permite ¡usted puede obtener múltiples usuarios en UNA consulta! Que es mucho más eficiente. Luego, en su opinión:

foreach($users as $user){ 
    // iterate over each user and do stuff 
} 

También debe considerar el uso de una clase singelton para un usuario para limitar la carga de base de datos. Crear una clase de instancia no cambia llamada CurrentUser (por ejemplo) como:

class CurrentUser { 

    private static $user; 

    // we never instantiate it -its singleton 
    private function __construct() {} 

    public function user() { 
    return self::$user; 
    } 

} 

Este es un ejemplo muy básico de una clase Singleton y le falta un montón de cosas. Si quieres saber más sobre clases singleton, publica otra pregunta.

0

Estoy de acuerdo con Seth re. "También debería considerar usar una clase singelton para que un usuario limite la carga de la base de datos. Cree una clase de instancia no cambiante llamada CurrentUser".

En mi aplicación pseudo-MVC tengo usuario de clase (es decir, usuario actual) con métodos para sesión, obtención de información de usuario, roles, etc., y miembro de clase (es decir, cualquier usuario) con métodos para registrar nuevos usuarios, obteniendo/actualizando sus propiedades, etc., pero nada que ver con las sesiones, por ejemplo. Además, es un escenario único, por lo que el usuario actual es estático y no requiere mucha interacción con el DB.

Por lo tanto, en mi caso, mi controlador y mi vista hacen llamadas a los métodos de usuario, p.

User::getId() o User::getGroups().

+0

Estoy confundido por qué un singleton tiene menos interacción con el db? Aún tiene que crear este objeto en la carga de la página, ¿correcto? – MikeMurko

+0

No cambia la frecuencia con la que interactúa con DB. La ventaja de singleton es que no tiene que __construirlo todo el tiempo. Por lo tanto, funciona para objetos que deben crearse solo una vez en la aplicación, p. Usuario actual. Sin embargo, no funcionará para hacer una lista de muchos usuarios, ya que tendría que crear una instancia de la clase para cada uno de ellos. –

Cuestiones relacionadas