2009-08-18 3 views
5

Tengo que procesar unos 20 parámetros de POST, y no estoy seguro de dónde hacerlo.¿Debo acceder a POST-Parameters en el modelo o pasar como argumentos de método desde el controlador?

Podría definir cada uno como un argumento del método en el modelo, y pasarlos desde el controlador cuando se llame al método. Esto daría como resultado un gran trabajo y haría que la llamada a la función sea menos legible, debido a la cantidad de argumentos.

O podría llamar al método en el modelo y acceder directamente a los parámetros.

Pasar los parámetros como argumentos me daría más control sobre a qué parámetros accede la función, y la documentación sería más fácil de entender. Pero si se agregaran nuevos parámetros más adelante, tendrían que agregarse al final de la llamada al método, para no interrumpir todas las llamadas existentes. Imagino que esto sería bastante confuso si sucede algunas veces, ya que los argumentos no se pueden agrupar de manera lógica.

Si accedo al parámetro en el modelo, no se deben pasar parámetros del controlador al modelo, haciendo que el método llame a terser. Pero no tengo control sobre los parámetros a los que se accede, ya que pueden agregarse o eliminarse fácilmente y sin restricciones. Esto requeriría una mayor disciplina de los otros desarrolladores, y no me gusta depender de eso, porque tarde o temprano alguien está obligado a "simplemente (agregar | cambiar | corregir) esto muy rápido".

No estoy seguro de qué camino tomar. Tiendo a hacerlo todo solo en el modelo, ya que es más rápido de escribir, parece más fácil de mantener (sin caos argumental) y conceptualmente se ajusta mejor a mi visión de un modelo. Por otro lado, no estoy seguro de si mi visión de un modelo es correcta, y si terminará en un caos si dependo de los otros desarrolladores para actualizar siempre la documentación después de cada cambio.

Entonces, ¿qué debo hacer?

+0

Opté por no aceptar ninguna respuesta a mi pregunta, ya que no hay una respuesta clara. En general, seguiría el enfoque de Ignas y Lucas, ya que los datos están mejor restringidos. Para este caso en nuestra aplicación, la respuesta de karims encaja mejor. – Thomas

Respuesta

1

Bueno, ¿por qué no puedes simplemente aceptar una matriz (asociativa) como parámetro en ese método del modelo y luego pasarle la matriz $ _POST completa? Al menos en mi opinión, no rompería la encapsulación.

EDIT: Y si no te gusta el uso de matrices asociativas para eso, también puede utilizar los llamados "objetos Plain Old" (objetos que sólo se utilizan para transportar datos, como estructuras en C). Por ejemplo, si esto implicaba guardar un formulario de registro presentado:

class UserData 
{ 
    protected $name; 
    protected $username; 
    protected $password; 

    public function getName() { /* <...> */ } 
    public function setName() { /* <...> */ } 
    /* other accessors go here */ 
} 

class UserController extends Controller 
{ 
    public function register() 
    { 
     $userData = UserData::create() 
      ->setName($_POST['name']) 
      ->setUsername($_POST['username']) 
      ->setPassword($_POST['password']); 
     Users::add($userData); 
    } 
} 

Esto permitirá utilizar tipos de datos estrictos en Usuarios :: agregar y también hacen que el proceso de documentación más fácil.

+0

Agregué otra solución a mi respuesta como respuesta a este comentario del autor: "La pregunta es realmente similar, pero no me gusta pasar matrices asociativas <...>" –

+0

Como respondí a daff, definitivamente preferiría pasar objetos a matrices asociativas , Voy a tener tu ejemplo en mente. – Thomas

0

Respondí a similar question hace un tiempo. Imho debes pasarlos, p. como ya se propuso como una matriz asociativa (y hacer todos los controles de seguridad antes). De esa manera, puedes reusar fácilmente tus clases.

+2

La pregunta es de hecho similar, pero no me gusta pasar matrices asociativas. Para la documentación y el propósito de la restricción son básicamente inútiles, porque no puedo (o solo con un inmenso esfuerzo) documentar o restringir su contenido. Se convierten en un recipiente para cualquier cosa que quiera arrojar allí. En este caso, la verificación se realiza en el controlador, y si falla, nunca se llamará al método en el modelo. Por lo tanto, pasar una matriz asociativa no tiene ningún beneficio para acceder directamente a $ _POST. – Thomas

+0

Bueno, pero es una estructura de lenguaje básico de PHP, ¿por qué no usarlo? Por otro lado, si tiene un diseño OO apropiado, nunca tendrá que procesar 20 parámetros en una llamada a función. – Daff

+0

El problema que veo con las matrices es su "holgura", cada desarrollador puede agregar o eliminar campos, y nadie se daría cuenta. Las clases son mejores, ya que definen cómo se estructuran los datos. Pero en este caso seguiré karim79, ya que no cambiamos los valores en POST-Array. – Thomas

0

Controlador. Porque los datos de solicitud y la manipulación del modelo no son lo mismo. Por lo tanto, se requerirá poner la lógica basada en datos de solicitud en el modelo para todas las demás solicitudes posibles, y eso es malo

+0

No creo que acceder a los parámetros cuente como lógica. Validación, etc. ya está hecho el controlador. Además, este método solo tiene sentido para este caso, por lo que no hay planes para reutilizarlo para otra solicitud. – Thomas

1

He tenido problemas con este mismo problema, y ​​la solución que se me ocurrió es flexible, mantiene mi código reutilizable y es tolerante a los cambios en el front-end: me gusta usar setters. Por supuesto, tener un regulador para cada valor individual es un dolor, por lo que los datos de agrupación de formas lógicas ayuda:

 
$user = new User(); 
$user->setName($_POST['lastName'],$_POST['firstName']); 
$user->setAddress($_POST['address1'],$_POST['address2'],$_POST['city'],$_POST['state'],$_POST['zip']); 

Usted consigue el punto.Una vez guardado en las variables del objeto, puede usar estos valores en todos los métodos de su objeto.

Hacer que sus modelos dependan de superglobales es tan inflexible. También hace que las pruebas unitarias sean un dolor.

+0

Esta es una sugerencia interesante. Tristemente, en este caso, no puedo agrupar contextualmente ningún parámetro, así que tendría que tener un setter para cada parámetro, y así la solución karim79 hace las cosas más fáciles. Pero lo tendré en cuenta para otros casos. – Thomas

0

Aquí es lo que hago ...

//Object Oriented POST Replacement 
    if ($_SERVER['REQUEST_METHOD'] == 'POST') 
    { 
     $_POST = json_decode(file_get_contents('php://input')); 
    } 

que estoy escribiendo sobre todo las API que transfieren información a través de JSON con el Content-Type: application/json. Sin embargo, esto funcionará (y es mejor en mi opinión) no importa cómo se esté rellenando $_POST.

Lo que sea que estés haciendo, sugiero convertir el $_POST superglobal en un objeto. En sus modelos, acepte un solo objeto como argumento y obtenga propiedades o subpropiedades.

A partir de ahí, simplemente establezca sus métodos de controlador para llamar a los métodos de modelo con su objeto orientado a objetos $_POST superglobal como el único argumento.

Cuestiones relacionadas