Foros del Web » Programando para Internet » PHP »

PHP OO JSON, clases y Arrays, ¿mala combinación?

Estas en el tema de JSON, clases y Arrays, ¿mala combinación? en el foro de PHP en Foros del Web. Saludos. Llevo unas semanas estudiando PHP, y estoy empezando con las clases (objetos), pero estoy teniendo problemas al combinar clases JSON y arrays, pero antes ...
  #1 (permalink)  
Antiguo 02/04/2013, 14:37
 
Fecha de Ingreso: abril-2013
Ubicación: Madrid
Mensajes: 4
Antigüedad: 11 años, 1 mes
Puntos: 0
Pregunta JSON, clases y Arrays, ¿mala combinación?

Saludos.

Llevo unas semanas estudiando PHP, y estoy empezando con las clases (objetos), pero estoy teniendo problemas al combinar clases JSON y arrays, pero antes de nada voy a aclararlo:

La página que estoy haciendo simula ser una página de venta de ropa, calzado y complementos de prueba.

El esquema sería algo así:
  • Página principal donde se incluyen los enlaces a jquery.js(con librerías jquery), js1.js (que contiene los scripts) y clases.php(donde está la clase para manejar los productos).
    En la página hay un "combo" que permite seleccionar la categoría de los productos (calzado, ropa, accesorios), y debajo el listado de productos.
  • clases.php Donde está la clase, la cual contiene un array con los productos y sus características, así como una función que muestra los productos filtrando por categoría, o en caso de no haber filtro, muestra todos.
  • ajax.php Aquí se cogerá la categoría que pasemos por POST desde la página principal, y devolverá el listado de productos en función de la categoría seleccionada en el combo
  • js.js scripts, entre los que está en que mediante ajax (Json) mandará a ajax.php la categoría sacada del combo, cuando éste cambie ( .change() )

Ahora pongo como tengo la clase y el array que hay en el:
Código PHP:
    class listado_productos{
        
        public function 
__construct() {
            
$this -> productos[] = array(1,"Zapato",1);
            
$this -> productos[] = array(2,"Zapatilla",1);
            
$this -> productos[] = array(3,"Bota",1);
            
$this -> productos[] = array(4,"Falda",2);
            
$this -> productos[] = array(5,"Pantalón",2);
            
$this -> productos[] = array(6,"Camisa",2);
            
$this -> productos[] = array(7,"Bolso",3);
            
$this -> productos[] = array(8,"Pulsera",3);
        }

        function 
mostrar($categoria 0){
            
$lista "";
            if (
$categoria==0){
            
                for(
$i $i count($this -> productos[0]) ; $i++){
                    
$lista .= "<li>".$this -> productos[$i][1]."</li>";
                }
                echo 
"<ul>".$lista."</ul>";
            }
            else{
                for(
$i $i count($this -> productos[0]) ; $i++){
                    if (
$catgegoria == $this -> productos[$i][2]){
                        
$lista .= "<li>".$this -> productos[$i][1]."</li>";
                    }
                }
                echo 
"<ul>".$lista."</ul>";
            }
        }
    } 
Si llamo a la clase desde la página principal , se muestra correctamente el listado de productos, y lo mismo si meto el parámetro de la categoría.

el problema viene cuando intento hacer el filtro al cambiar de categoría en el combo.

el js.js sería así:
Código PHP:
$(document).ready(function(){
    $(
"#filtro").change(function(){
        $.
post("ajax.php?lista=filtro",{ categoria:$("#filtro").val()},function(datos){
            $(
"#productos").html(datos));
        },
"json");
    });
}); 
y el ajax.php:
Código PHP:
include "clases.php";
    
$vr $_GET["lista"];
    
$categoria $_POST["categoria"];
    switch (
$vr){
        case 
"filtro":
            
$filtro = new listado();
            
$filtrado $filtro -> mostrar($categoria);
            echo 
json_encode($filtrado);
        break;
    } 
El caso es que en el firebug me pone que envío bien los datos al ajax.php, pero de ahí no vuelve a la página principal.

Inlcuso he probado a poner literalmente:
Código PHP:
include "clases.php";
    
$vr $_GET["lista"];
    
$categoria $_POST["categoria"];
    switch (
$vr){
        case 
"filtro":
            echo 
json_encode("prueba");
        break;
    } 
y tampoco funcionaba.

En cambio quitando el include si:
Código PHP:
    $vr $_GET["lista"];
    
$categoria $_POST["categoria"];
    switch (
$vr){
        case 
"filtro":
            echo 
json_encode("prueba");
        break;
    } 
De lo que deduzco que igual hay alguna incompatibilidad entre las clases y json. ¿Alguien podría decirme que puedo hacer?, o ¿qué hago mal?
  #2 (permalink)  
Antiguo 02/04/2013, 14:43
Avatar de dashtrash
Colaborador
 
Fecha de Ingreso: abril-2007
Ubicación: Ni en Sevilla,ni en Sanlúcar..qué más da..
Mensajes: 927
Antigüedad: 17 años, 1 mes
Puntos: 270
Respuesta: JSON, clases y Arrays, ¿mala combinación?

Lo que llamas "incompatibilidad" creo que es más bien un "problema" con ese include.
- Si estás aprendiendo, y no quieres liarte, comienza puliendo el php ( y mostrando datos directamente al navegador, en una pagina en blanco) o js (cargando ficheros json prefabricados).
- Para este caso en concreto, mira en el firebug la respuesta que devuelve ajax.php
- Si no tienes activado display_errors y html_errors en tu php.ini, mejor que los actives.
  #3 (permalink)  
Antiguo 02/04/2013, 15:22
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: JSON, clases y Arrays, ¿mala combinación?

Exacto, el problema viene justamente en tu include, hay que ver que tienes en clases.php, y como bien te dice dashtrash, activa el reporte de errores, es la forma más efectiva para ver si hay un problema.
  #4 (permalink)  
Antiguo 02/04/2013, 16:08
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 3 meses
Puntos: 206
Respuesta: JSON, clases y Arrays, ¿mala combinación?

En el método de la clase listado "filtrar" no esás devolviendo una cadena, la estás imprimiendo con ECHO. Asi que luego en el PHP llamado por AJAX, cuando llamas a filtrar, estás esperando un STRING para hacerle el json_encode.

Asi que se llamará a la función, se imprimirá el <ul> ... </ul> en html normal y corriente, y luego cuando la función regrese sin devolver nada, se hará el ECHO de JSON_ENCODE de una cadena a null.

Lo único que tienes que hacer es hacer un RETURN "<ul>".$lista."</ul>"; en vez del ECHO, en la clase listado. Además en "mostrar" has usado alguna vez la variable mal escrita $catgegoria.

También te faltaría declarar el atributo listado.
Por ejemplo,
class listado{
private $productos=array();
...
}
  #5 (permalink)  
Antiguo 03/04/2013, 07:15
 
Fecha de Ingreso: abril-2013
Ubicación: Madrid
Mensajes: 4
Antigüedad: 11 años, 1 mes
Puntos: 0
Respuesta: JSON, clases y Arrays, ¿mala combinación?

Bueno, antes de nada, gracias por ayudarme con el problemilla.

Para que quede claro, lo que intento es filtrar los productos según categoría, es decir, que cuando cargue la página por primera vez se muestren todos los productos sin filtrar, y cuando cambie de categoría en el "combo", cargue de nuevo los productos, pero solo los de esa categoría (salvo que vuelva a seleccionar la opción por defecto).

Yo he creído que lo mejor sería con Json, pero desconozco si habrá alguna otra forma mas sencilla o recomendable.

En cualquier caso, pongo como tengo todo escrito:
  • Página principal:
    Código PHP:
    <html xmlns="http://www.w3.org/1999/xhtml">

    <head>
        <title>Ejercício</title>
        <script type="text/javascript" src="../js/jquery.js"></script>
        <script type="text/javascript" src="js.js"></script>
        <?php include "clases.php"?>
    </head>

    <body>
        <div>
            <select name="filtro" id="filtro">
                <option value="0" >Categoría</option>
                <option value="1" >Calzado</option>
                <option value="2" >Ropa</option>
                <option value="3" >Accesorios</option>
            </select>
        </div>
        <div name="productos" id="productos">
        <?php
            $lista 
    = new listado_productos();
            echo 
    $lista -> mostrar();
        
    ?>
        </div>
    </body>

    </html>
  • clases.php:
    Código PHP:
    <?php 
        
    class listado_productos{
            private 
    $productos = array();
            public function 
    __construct() {
                
    $this -> productos[] = array(1,"Zapato",1);
                
    $this -> productos[] = array(2,"Zapatilla",1);
                
    $this -> productos[] = array(3,"Bota",1);
                
    $this -> productos[] = array(4,"Falda",2);
                
    $this -> productos[] = array(5,"Pantalón",2);
                
    $this -> productos[] = array(6,"Camisa",2);
                
    $this -> productos[] = array(7,"Bolso",3);
                
    $this -> productos[] = array(8,"Pulsera",3);
            }

            function 
    mostrar($categoria 0){
                
    $lista "";
                if (
    $categoria==0){
                    for(
    $i $i count($this -> productos[0]) ; $i++){
                    
    $lista .= "<li>".$this -> productos[$i][1]."</li>";
                    }
                    return 
    "<ul>".$lista."</ul>";
                }
                else{
                    for(
    $i $i count($this -> productos[0]) ; $i++){
                        if (
    $categoria == $this -> productos[$i][2]){
                            
    $lista .= "<li>".$this -> productos[$i][1]."</li>";
                        }
                    }
                    return 
    "<ul>".$lista."</ul>";
                }
            }
        }
    ?>
  • js.js:
    Código HTML:
    $(document).ready(function(){
    		
    	$("#sFiltro").change(function(){
    	$("#dCarrito").hide();
    		$.post("ajax.php?cat=algo",{ cat:$("#sFiltro").val()},function(datos){
    			alert("datos");
    		},"json");
    	});
    });
    
  • ajax.php:
    Código PHP:
    <?php
        
    include "clases.php";
        
    $vr $_GET["lista"];
        
    $categoria $_POST["categoria"];
        switch (
    $vr){
            case 
    "filtro":
                
    $filtro = new listado_productos();
                
    $filtrado $filtro -> mostrar($categoria);
                echo 
    json_encode($filtrado);
            break;
        }
    ?>

Tal como está, la primera vez me carga los datos mas o menos bien, salvo por que me he dado cuenta de que no recorre todas las filas del array bidimensional, si no solo las 3 primeras. Se debe a que "count($this -> productos[0])" me da un valor de 3, que es el nº de "columnas" no de filas, he probado con "count($this -> productos[])" o "count($this -> productos)", y me salta error, pero bueno, es algo secundario.

El tema está en que cuando cambio de opción en el combo, me pasa bien los parámetros y el POST al ajax.php, pero no vuelve a la página principal.

En el firebug me pone en la pestaña de respuesta:
Código:
"<ul><li>Zapato<\/li><li>Zapatilla<\/li><li>Bota<\/li><\/ul>"
pero no aparece la pestaña de JSON que aparece cuando todo está OK.
  #6 (permalink)  
Antiguo 03/04/2013, 10:39
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: JSON, clases y Arrays, ¿mala combinación?

Te faltaría enviar las cabeceras:
Código PHP:
Ver original
  1. header('Content-type: text/json');

Para indicarle al browser que lo que vas a enviar es JSON.

Saludos.
  #7 (permalink)  
Antiguo 03/04/2013, 13:42
 
Fecha de Ingreso: abril-2013
Ubicación: Madrid
Mensajes: 4
Antigüedad: 11 años, 1 mes
Puntos: 0
Respuesta: JSON, clases y Arrays, ¿mala combinación?

Cita:
Iniciado por GatorV Ver Mensaje
Te faltaría enviar las cabeceras:
Código PHP:
Ver original
  1. header('Content-type: text/json');

Para indicarle al browser que lo que vas a enviar es JSON.

Saludos.
Pero ¿dónde tendría que poner eso?, es que estoy algo perdida. Las pruebas que había hecho hasta ahora con $.post y json y que me han funcionado, no requerían poner header.
  #8 (permalink)  
Antiguo 03/04/2013, 17:51
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 3 meses
Puntos: 206
Respuesta: JSON, clases y Arrays, ¿mala combinación?

El count del FOR es así:

count($this -> productos)

y el js:

Código Javascript:
Ver original
  1. $(document).ready(function(){
  2.        
  3.     $("#sFiltro").change(function(){
  4.     $("#dCarrito").hide();
  5.         $.post("ajax.php",{ cat:$("#sFiltro").val()},function(datos){
  6.             alert(datos);
  7.         },"json");
  8.     });
  9. });
  #9 (permalink)  
Antiguo 03/04/2013, 19:26
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: JSON, clases y Arrays, ¿mala combinación?

El header debe de ir en ajax.php ya que es el archivo que los devuelve los datos en JSON.
  #10 (permalink)  
Antiguo 04/04/2013, 09:36
 
Fecha de Ingreso: abril-2013
Ubicación: Madrid
Mensajes: 4
Antigüedad: 11 años, 1 mes
Puntos: 0
Respuesta: JSON, clases y Arrays, ¿mala combinación?

Al final, tras varios ensayos errores he conseguido que funcione como quiero, metiendo el contenido de ajax.php directamente en la página donde está la clase.

Sigo sin entender por qué funciona de una forma y no de otra la verdad, si el código es el mismo.
  • Página principal:
    Código PHP:
    <html xmlns="http://www.w3.org/1999/xhtml">

    <head>
        <title>Ejercício</title>
        <script type="text/javascript" src="../js/jquery.js"></script>
        <script type="text/javascript" src="js.js"></script>
        <?php include "clases.php"?>
    </head>

    <body>
        <div>
            <select name="filtro" id="filtro">
                <option value="0" >Categoría</option>
                <option value="1" >Calzado</option>
                <option value="2" >Ropa</option>
                <option value="3" >Accesorios</option>
            </select>
        </div>
        <div name="productos" id="productos">
        <?php
            $lista 
    = new listado_productos();
            echo 
    $lista -> mostrar();
        
    ?>
        </div>
    </body>

    </html>
  • clases.php:
    Código PHP:
    <?php 
        $vr 
    $_GET["lista"];
        
    $categoria $_POST["cat"];
        switch (
    $vr){
            case 
    "prueba":
                
    $filtro = new listado_productos();
                
    $filtrado $filtro -> mostrar($categoria);
                echo 
    json_encode($filtrado);
            break;
        }

        class 
    listado_productos{
            private 
    $productos = array();
            public function 
    __construct() {
                
    $this -> productos[] = array(1,"Zapato",1);
                
    $this -> productos[] = array(2,"Zapatilla",1);
                
    $this -> productos[] = array(3,"Bota",1);
                
    $this -> productos[] = array(4,"Falda",2);
                
    $this -> productos[] = array(5,"Pantalón",2);
                
    $this -> productos[] = array(6,"Camisa",2);
                
    $this -> productos[] = array(7,"Bolso",3);
                
    $this -> productos[] = array(8,"Pulsera",3);
            }

            function 
    mostrar($categoria 0){
                
    $lista "";
                if (
    $categoria==0){
                    for(
    $i $i count($this -> productos) ; $i++){
                    
    $lista .= "<li>".$this -> productos[$i][1]."</li>";
                    }
                    return 
    "<ul>".$lista."</ul>";
                }
                else{
                    for(
    $i $i count($this -> productos) ; $i++){
                        if (
    $categoria == $this -> productos[$i][2]){
                            
    $lista .= "<li>".$this -> productos[$i][1]."</li>";
                        }
                    }
                    return 
    "<ul>".$lista."</ul>";
                }
            }
        }
    ?>
  • js.js:
    Código HTML:
    $(document).ready(function(){
    		
    	$("#filtro").change(function(){
    		$.post("clases.php?lista=prueba",{ cat:$("#filtro").val()},function(datos){
    			alert("datos");
    		},"json");
    	});
    });
    

Etiquetas: arrays, clases, html, json
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 00:36.