Foros del Web » Programando para Internet » PHP »

[SOLUCIONADO] PHP OO Combinar funciones

Estas en el tema de Combinar funciones en el foro de PHP en Foros del Web. Hola, soy nuevo en esto de POO y MVC y tengo un problema. En mi controlador tengo una función que recibe una variable por GET ...
  #1 (permalink)  
Antiguo 10/08/2013, 19:57
 
Fecha de Ingreso: febrero-2013
Mensajes: 163
Antigüedad: 11 años, 2 meses
Puntos: 1
Combinar funciones

Hola, soy nuevo en esto de POO y MVC y tengo un problema. En mi controlador tengo una función que recibe una variable por GET (noticiaid), hace una consulta a la base de datos desde el modelo, y para finalizar procesa la vista: el SKIN de la página y el contenido, que es el resultado de la consulta. Mejor miren el código, se entiende mejor:

Código PHP:
require 'sistema/modelo/noticia.php';

class 
controlador {
    function 
noticia($noticiaid)
    {    
        
//con esto hago la consulta a la base de datos y cargo el resultado en $contenido
        
ob_start();
        
$noticia= new noticia();    
        
$array $noticia->noticias($noticiaid);
        
        if(
$array!='')
        {
            include 
'sistema/vista/'__SKIN__ .'/modulos/noticia.php';
            
$contenido ob_get_clean();    
        }
        else
        {
            
$contenido 'No hay registros';    
        }    

        
//con esto cargo el SKIN (vista.php)
        
include 'sistema/vista/'__SKIN__ .'/vista.php';     
    }

vista.php recibe $contenido y reemplaza un sector de la página.

Bueno ahora tengo este problema, el SKIN (vista.php) es una página con SECTORES (cabecera, lateral y contenido). Con esa función yo reemplazo el sector CONTENIDO. Pero qué pasa si quiero tener otra función, para cargar la cabera y el lateral separado del contenido? O sea, quiero tener el mismo resultado de esto pero quiero separarlo en 2 funciones:

Código PHP:
function noticia($noticiaid)
{    
    
//con esto cargo la cabecera
    
ob_start();
    include 
'sistema/vista/'__SKIN__ .'/sectores/cabecera.php';
    
$menu ob_get_clean();

    
//con esto cargo el lateral
    
ob_start();
    include 
'sistema/vista/'__SKIN__ .'/sectores/lateral.php';
    
$menu ob_get_clean();

    
//con esto cargo el contenido, es el mismo código que el anterior
    
ob_start();
    
$noticia= new noticia();    
    
$array $noticia->noticias($noticiaid);
        
    if(
$array!='')
    {
        include 
'sistema/vista/'__SKIN__ .'/modulos/noticia.php';
        
$contenido ob_get_clean();    
    }
    else
    {
        
$contenido 'No hay datos';    
    }        
    include 
'sistema/vista/'__SKIN__ .'/vista.php';     

Quiero tener separado una función que haga la consulta y cargue el CONTENIDO, y otra función para cargar la CABECERA y el LATERAL. Cómo puedo hacer eso? Estoy buscando pero no encuentro nada que se aplique a este ejemplo, o no estoy sabiendo buscar. Es que en realidad no sé bien que debo hacer. Gracias de antemano.


EDITO: ya encontré la solución. Creo una función para incluir un sector, luego desde la función noticia llamo a esa función con $this. Queda así:

Código PHP:
function cabecera()
{
    include 
'sistema/vista/'__SKIN__ .'/sectores/cabecera.php';
}

function 
noticia($noticiaid)
{    
    
//cargo la cabecera
    
ob_start();
    
$this->cabecera();
    
$menu ob_get_clean();

    
//cargo el contenido
    
ob_start();
    
$noticia= new noticia();    
    
$array $noticia->noticias($noticiaid);
        
    if(
$array!='')
    {
        include 
'sistema/vista/'__SKIN__ .'/modulos/noticia.php';
        
$contenido ob_get_clean();    
    }
    else
    {
        
$contenido 'No hay datos';    
    }        
    include 
'sistema/vista/'__SKIN__ .'/vista.php';     

Aunque todavía me quedan dudas, de esta forma tengo que crear una función para cada sector. Como hago para juntar los sectores CABECERA y LATERAL en una sola función, y luego usarlas en la función noticia? Sospecho que estoy haciendo una burrada, alquien tiene algún consejo?

Última edición por mathiasmontiel; 10/08/2013 a las 22:02
  #2 (permalink)  
Antiguo 10/08/2013, 23:12
Avatar de Nemutagk
Colaborador
 
Fecha de Ingreso: marzo-2004
Ubicación: México
Mensajes: 2.633
Antigüedad: 20 años
Puntos: 406
Respuesta: Combinar funciones

Lo que estas haciendo dista mucho de ser MVC, el Controlador no puede hacerse cargo de la vista, y eso es lo que estas haciendo, estas cargando los layout y dandoles formato, eso debe ser trabajo de otro objeto (el objeto vista), así como tienes una clase para los controladores y una para los modelos debes tener una exclusivamente para obtener los layout acomodarlos y mostrarlos, tu todo eso lo estas haciendo dentro de la acción del controlador!
__________________
Listo?, tendría que tener 60 puntos menos de IQ para considerarme listo!!!
-- Sheldon Cooper
http://twitter.com/nemutagk
PD: No contestaré temas vía mensaje personal =)
  #3 (permalink)  
Antiguo 11/08/2013, 13:35
 
Fecha de Ingreso: febrero-2013
Mensajes: 163
Antigüedad: 11 años, 2 meses
Puntos: 1
Respuesta: Combinar funciones

Gracias por tu respuesta.
Me confundí bastante ahora, hace poco estaba leyendo en un artículo: "El controlador no es nada mas que una función que la mayoría del tiempo llama a la vista y al modelo".Y como ejemplo ponía algo parecido a mi código, hacía una consulta desde el modelo y usaba un include para incluir a la vista. Y en la vista solo ponía simples echo para imprimir lo recibido.
Eso está mal, o es mi código lo que está mal? Este es el código de ejemplo que encontré:

Código PHP:
<?php

function user_controller($params) {
    if (
            !
is_array($params) ||
            !isSet(
$params[1]) ||
            !
is_numeric($params[1])
        )
            return 
false;
    
/* llamamos el modelo */
    
$dbu   = new User;
    
$users $dbu->Select(array("id"=>$params[1]));
    
/* incluimos la vista */
    /* la variable $users es visible para vista */
    
include("vista.php");
}

?>
  #4 (permalink)  
Antiguo 11/08/2013, 14:00
Avatar de Nemutagk
Colaborador
 
Fecha de Ingreso: marzo-2004
Ubicación: México
Mensajes: 2.633
Antigüedad: 20 años
Puntos: 406
Respuesta: Combinar funciones

El controlador únicamente se debe hacer cargo de la lógica (comparaciones, sumas, loops, etc), el modelo se encarga de suministrar datos (de una db por ejemplo, tanto acceder como persistir) y la vista es la que se encarga de generar el HTML (o xml o json o lo que sea que necesite el cliente), tu estas combinando el controlador y la vista, al hacer el include de "vista.php" estas dandole el trabajo al controlador de enviar y generar la vista, lo cual esta mal, otro objeto es el que se debe encargar de eso, de hecho, lo que normalmente se hace es que el controlador solo le envía los parámetros necesarios a la vista para que este genere el código final (el que se envía al navegador)...

En palabras mas simples debes crear otra clase (la clase view por ejemplo), a esta clase le pasas la vista que debe generar y el layout que vas a usar, aparte, le debes pasar las variables que vas a usar en la vista, por ejemplo, supongamos que vas a mostrar una tabla de usuarios, bueno, pues el controlador le pasa un array con todos los usuarios, la vista se encarga de acomodarlos por ejemplo en una tabla o en una lista para que se puedan leer sin problemas por los usuarios...
__________________
Listo?, tendría que tener 60 puntos menos de IQ para considerarme listo!!!
-- Sheldon Cooper
http://twitter.com/nemutagk
PD: No contestaré temas vía mensaje personal =)
  #5 (permalink)  
Antiguo 11/08/2013, 16:37
 
Fecha de Ingreso: febrero-2013
Mensajes: 163
Antigüedad: 11 años, 2 meses
Puntos: 1
Respuesta: Combinar funciones

Bueno creo que entendí más o menos lo que quisiste decir, y viendo otro ejemplo creo que se lo que hay que hacer. Pero me gustaría que lo veas y me sigas dando criticas constructivas. En ese ejemplo vi que crea funciones para:

- función para cargar una página
- función para reemplazar el contenido
- función para usar ambas funciones y cargar el layout
- función para mostrar la página 'generada'
- función para hacer la consulta, utilizar la funcion que carga el layout, y las demás funciones para cargar y reemplazar el contenido del modulo noticia.php. Y para finalizar, mostrar la página completa.

Al final mi código quedó así:

Código PHP:
<?php

require 'sistema/modelo/noticia.php';

class 
controlador 
{
    function 
noticia($noticia_id)
    {
        
$noticia = new noticia();    

        
//carga el layout con la función cargarVista
        
$pagina $this->cargarVista();

        
//carga la vista del modulo noticia.php, o sea del contenido noticia, para esta función
        
$moduloNoticia $this->cargarPagina('sistema/vista/modulos/noticia.php');

        
ob_start();
        
$array $noticia->noticias($noticia_id);
        if(
$array!='')
        {
            
$pagina $this->reemplazarContenido('/\#CONTENIDO\#/ms'$moduloNoticia $pagina);
        }
        else
        {
            
$pagina $this->reemplazarContenido('/\#CONTENIDO\#/ms' ,$moduloNoticia.' No hay registros' $pagina);
        }
        
        
//Muestro la página completa y chau
        
$this->mostrarPagina($pagina);
    }

    
//Función para cargar la vista/skin/layout
    
function cargarVista(){
        
$pagina= include 'sistema/vista/vista.php';
        
$cabecera $this->cargarPagina('sistema/vista/sectores/cabecera.php');
        
$pagina$this->reemplazarContenido('/\#CABECERA\#/ms' ,$cabecera $pagina);
        
$lateral $this->cargarPagina('sistema/vista/sectores/lateral.php');
        
$pagina $this->reemplazarContenido('/\#LATERAL\#/ms' ,$lateral $pagina);        
        return 
$pagina;
    }

    
//Función para cargar páginas
    
function cargarPagina($pagina)
    {
        return 
file_get_contents($pagina);
    }
    
    
//Función para mostrar las páginas
    
function mostrarPagina($html)
    {
        echo 
$html;
    }
    
    
//Función para reemplazar el contenido de las páginas
    
function reemplazarContenido($in='/\#CONTENIDO\#/ms'$out,$pagina)
    {
         return 
preg_replace($in$out$pagina);         
    }

}
?>
vista.php tiene palabras claves encerradas en ## que son los sectores que van a ser reemplazados.

O sea tengo la función para mostrar la página noticia (function noticia), le paso el layout de la función cargarVista, la vista del contenido que en este caso es el modulo noticia.php, y las variables de la consulta.

Aunque tu me dijiste que debo crear otra clase para pasar la vista a generar y el layout a usar, y aparte pasar las variables de la consulta. Y en el ejemplo vi que todo está en una misma clase pero en diferentes funciones, y que hay una función que hace uso de las demás funciones para mostrar la página completa. No es eso casi lo mismo? O sigo despistado del patron MVC y haciendo otra estructura :S
  #6 (permalink)  
Antiguo 11/08/2013, 16:42
Avatar de Nemutagk
Colaborador
 
Fecha de Ingreso: marzo-2004
Ubicación: México
Mensajes: 2.633
Antigüedad: 20 años
Puntos: 406
Respuesta: Combinar funciones

Mas o menos, el problema es que ESTAS COMBINANDO EL CONTROLADOR CON LA VISTA, pero vas por buen camino, lo que debes hacer es tomar esos "nuevos" métodos y colocarlos EN OTRA CLASE que puede llamarse VIEW y de la clase CONTROLLER le pasa las variables $pagina y $html y todas las variables que sean necesarias...

Ejemplo...
Código PHP:
Ver original
  1. <?php
  2.  
  3. $controller = new Controller();
  4. $view = new View();
  5. $view->cargarPagina($controller->getPagina());
  6. $view->mostrarPagina();

En el metodo mostrarPagina() haces los cambios pertinente, y envías el código al navegador (html, xml, json, etc)
__________________
Listo?, tendría que tener 60 puntos menos de IQ para considerarme listo!!!
-- Sheldon Cooper
http://twitter.com/nemutagk
PD: No contestaré temas vía mensaje personal =)
  #7 (permalink)  
Antiguo 11/08/2013, 18:07
 
Fecha de Ingreso: febrero-2013
Mensajes: 163
Antigüedad: 11 años, 2 meses
Puntos: 1
Respuesta: Combinar funciones

hm no había visto ese ejemplo que pusiste y me parece más práctico, voy a analizar mi código de nuevo. Pero más o menos ya estoy entendiendo y mientras tanto hice este código, entendí bien? En la clase controlador puse la función para hacer la consulta y devolver un array. Y en la clase vista puse las funciones para cargar los sectores de la página y una para recibir el array de la clase controlador, luego procesar la vista:


Código PHP:
//Clase del controlador
class controlador 
{

    
//Función del controlador que realiza la consulta desde el modelo y carga el resultado en un array
    
function consultaNoticia($url$noticia_id)
    {
                
$noticia = new noticia($url$noticia_id);
                
$array $noticia->noticias($url$noticia_id);
        return 
$array;
    }        
}

//Clase de la vista
class vista 
{

    
//Función que obtiene el array del controlador, procesa la vista y finalmente muestra la página
    
function mostrarNoticia($url$noticia_id)
    {
        
//Carga el skin/layout
        
$pagina $this->cargarVista();
        
        
//Obtiene el array desde el controlador
        
$consulta = new controlador;
        
ob_start();
        
$array $consulta->consultaNoticia($url$noticia_id);

        if(
$array!='')
        {
        
            
//Carga el modulo noticia.php
            
include 'sistema/vista/modulos/noticia.php';
            
$modulo ob_get_clean();
        
            
//Parsea el resultado
            
$pagina $this->reemplazarContenido('/\#CONTENIDO\#/ms'$modulo $pagina);
        }
        else
        {
            
$pagina $this->reemplazarContenido('/\#CONTENIDO\#/ms' ,$modulo.'No hay registros' $pagina);
        }
        
        
//Muestra la página completa y chau!
        
$this->mostrarPagina($pagina);
    }

    
//Función para cargar la vista/skin/layout
    
function cargarVista()
    {
        
$pagina $this->cargarPagina('sistema/vista/vista.php');
        
$cabecera $this->cargarPagina('sistema/vista/sectores/cabecera.php');
        
$pagina$this->reemplazarContenido('/\#CABECERA\#/ms' ,$cabecera $pagina);
        
$lateral $this->cargarPagina('sistema/vista/sectores/lateral.php');
        
$pagina $this->reemplazarContenido('/\#LATERAL\#/ms' ,$lateral $pagina);        
        return 
$pagina;
    }

    
//Función para cargar páginas
    
function cargarPagina($pagina)
    {
        return 
file_get_contents($pagina);
    }
    
    
//Función para mostrar las páginas
    
function mostrarPagina($html)
    {
        echo 
$html;
    }
    
    
//Función para reemplazar el contenido de las páginas
    
function reemplazarContenido($in='/\#CONTENIDO\#/ms'$out,$pagina)
    {
        return 
preg_replace($in$out$pagina);         
    }

}
?> 
  #8 (permalink)  
Antiguo 11/08/2013, 18:13
Avatar de Nemutagk
Colaborador
 
Fecha de Ingreso: marzo-2004
Ubicación: México
Mensajes: 2.633
Antigüedad: 20 años
Puntos: 406
Respuesta: Combinar funciones

Tu clase vista es muy dependiente del controlador (noticias), debería ser mas genérica, a lo que me refiero es que NO debería existir el método mostrarNoticia() en la clase vista, recuerda que la idea es reutilización de código, no estar creando una clase para cosa o tener métodos para exclusivos...
__________________
Listo?, tendría que tener 60 puntos menos de IQ para considerarme listo!!!
-- Sheldon Cooper
http://twitter.com/nemutagk
PD: No contestaré temas vía mensaje personal =)
  #9 (permalink)  
Antiguo 11/08/2013, 22:25
 
Fecha de Ingreso: febrero-2013
Mensajes: 163
Antigüedad: 11 años, 2 meses
Puntos: 1
Respuesta: Combinar funciones

Cambié mi código y me gustaría saber si es correcto o si algo está mal. Mi controlador lo unico que hace ahora es recibir los datos de modelo y enviarlo a la vista.

Código PHP:
require 'sistema/modelo/modelo.php';

class 
controlador 
{

    
//Función que carga la página de inicio. Hace una consulta desde el modelo, carga el resultado en $inicio luego lo envia a vista.php
    
function inicio()
    {
        
$clase = new modelo();
        
$inicio $clase->inicio();
        require(
'sistema/vista/vista.php');
    }    

    
//Función en caso de que reciba los parametros $url y $noticiaid, hace la consulta y lo mismo pero carga el resultado en $noticia y lo envia a vista.php
    
function consultaArticulo($url$noticiaid)
    {
        
$clase = new modelo();
        
$noticia $clase->noticia ($url$noticiaid);
        require(
'sistema/vista/vista.php');
    }    


Bueno ahora el controlador recibe los datos y lo envia a vista.php. Si vista.php recibe $inicio, muestra una cosa + el resultado. Pero si recibe $noticia, muestra otra cosa + otro resultado. Esto lo hago con if else, en vista.php. Qué está mal aquí?

Etiquetas: combinar, funciones, registro, variable
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:49.