entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

3votos

Alternar dos banners en cada refresco de la página en PHP

Hola quería que me ayudarais con el siguiente problema,

Resulta que quiero que al refrescar/cargar la pagina web me alterne dos imágenes banners de modo que en cada carga muestre una distinta.

Ojo no la quiero random ya que de ese modo lo consigo hacer(efecto que no deseo ya que a lo mejor cada dos, tres... refrescos me la alterna). Se me ocurre guardar un flag en la BD como valor a 1 de modo que si recargo de nuevo compruebo el valor, si es igual a 1 cargo el siguiente banner y lo pongo a 2 el flag y así al revés poniéndolo de nuevo a 1. Pero no querría legar hacer este procedimiento...

También quiero hacerla sin necesidad de utilizar sesiones ni cookies.

Espero vuestra respuesta, saludos!

0voto

carlossevi comentado

A no ser que no te esté interpretando bien no tiene mucho sentido lo que quieres hacer. ¿Cual es el objetivo? ¿En qué mejora ese comportamiento al que obtienes con random? Los inconvenientes están muy claros a nivel de rendimiento y recursos necesarios ¿ventajas?

4 Respuestas

2votos

Leonardo-Tadei Puntos227320

Hola Pabeni,

las sesiones (las que se usan con sesion_*()) son un mecanismo nativo de PHP que no usa la DB ni tampoco usa recursos del lado del cliente que ya no estén en uso por visitar la página.

Se puede hacer con sesiones así:

session_start();
if( ! isset($_SESSION["banner"])) {
    $_SESSION["banner"] = 1; // si no hay valor de la sesión, pone un default
}
// dependiendo del valor, pone un banner u otro
if($_SESSION["banner"] == 1) {
   $banner = 'ruta/banner1.png';
   $_SESSION["banner"] = 2;
} else {
   $banner = 'ruta/banner2.png';
   $_SESSION["banner"] = 1;
}

Luego usás en el SRC de la imagen el valor de la variable $banner.

Si tuvieras más de 2 banners, es mejor cambiar el IF por un SWITCH, y si tenés ganas de jugar, delegar la responsabilidad de determinar el banner siguiente en un Objeto que implemente una patrón de diseño State (lo que para un caso tan simple es un poco como matar moscas a cañonazos ;-) )

Esto es un mecanismo que no usa procedimientos alternativos al propio lenguaje... si no podés aplicar esta solución, tendrás que contarnos mejor el contexto y las restricciones (estoy pensando que tu pregunta no es el caso real de uso, sino una simplificación para poder escribirlo en eD, y tal vez no sea un equivalente correcto a tu problema.

Saludos cordiales!

0voto

pabeni comentado

Digamos que lo que busco es un método alternativo ya que las demás soluciones que anteriormente se mencionan ya las conocía y era para ver que soluciones me proponíais. Digamos que lo que pretendo con esto es ampliar aun mas los conocimientos en cuanto a posibilidades existan. De ser como me comentáis parece que la idea que tenia en un principio era cierta(la de ser imposible).

Un saludo maestros!

0voto

pabeni comentado

Por cierto Leonardo-Tadei probando tu código he comprobado que no me funciona como debería, la prueba que he realizado es la siguiente:

<?php
    session_start();

    if(!isset($_SESSION["banner"])){
        $_SESSION["banner"] = 1; // si no hay valor de la sesión, pone un default
    }
    // dependiendo del valor, pone un banner u otro
    if($_SESSION["banner"] = 1){
       $banner = 'ruta/banner1.png';
       $_SESSION["banner"] = 2;
    }else{
       $banner = 'ruta/banner2.png';
       $_SESSION["banner"] = 1;
    }
?>
<!DOCTYPE html>

<html lang="es">
    <head>
        <title>Titulo de la web</title>
        <meta charset="utf-8" >
    </head>
    <body>
        <?php
            echo "<img src='$banner'>";
        ?>
    </body>
</html>

Logicamente cambiando la ruta donde tengo los banners. Y siempre me muestra la misma cuando cierro la pagina o la recargo.

Espero su respuesta, un saludo!

0voto

GusGarsaky comentado

Movido como respuesta.

0voto

pabeni comentado

Hola Gus Garsaky,

En ningún momento estoy haciendo uso de Javascript....Gracias de todos modos por responder.

Saludos!

0voto

Leonardo-Tadei comentado

Hola @pabeni,

hay un error en el código que te envió: un = en lugar de un ==... eso me pasa por escribir las respuestas de código directamente acá :-(

// dependiendo del valor, pone un banner u otro
if($_SESSION["banner"] == 1){

con esa corrección semántica funciona alternando las imágenes correctamente.

Volviendo a la interesante discusión sobre este tema, la cuestión es que para saber qué banner mostrar, tenés que almacenar el banner que sigue (o el actual) en algún lado, ya sea en el cliente o en el servidor.

Hacerlo en el servidor es más compatible, en el sentido que funciona en todos los navegadores. Sin embargo guardarlo en el servidor en una DB es mucho más costoso que almacenarlo en una sesión, al menos para un sitio con 5000 usuarios concurrentes o menos.

La cuestión se reduce entonces a la pregunta "en dónde guardar?" y luego a la pregunta "cómo guardarlo?".

La solución de Gus más abajo es idéntica a la mía, salvo que el guarda el nombre de la imagen además de la bandera, con lo que lo almacenado es mayor.

Saludos cordiales!

0voto

Leonardo-Tadei comentado

Me gustaba más mi otra respuesta ;-)

1voto

white Puntos75880

podria ser con localstorage?

<script type="text/javascript">

    var images = [
        'http://placehold.it/350x150',
        'http://placehold.it/350x151'
    ];

    document.addEventListener('DOMContentLoaded', function(){

        if (localStorage.current_banner) {
            localStorage.current_banner = parseInt(localStorage.current_banner) + 1;

            if(parseInt(localStorage.current_banner) > images.length -1)
                localStorage.current_banner = 0;

        } else
            localStorage.current_banner = 0;

            current = parseInt(localStorage.current_banner);
            document.getElementById('banner').src = images[current];

    });
</script>

tambien podrias hacer uso de:

  • en php: memcache, apc, file cache.
  • escribir en ficheros.
  • una base de datos.

pero afectaria el performance, de cierta forma.

no veo mucho sentido no usar sesiones ni cookies, cual podria ser la razon?

0voto

pabeni comentado

Hola white, antes de nada gracias por responder.

Como comente en el apartado de antes quiero hacerlo sin la necesidad de procedimientos alternativos al propio lengua lenguaje PHP, con esto quiero decir sin hacer uso de: BD, ficheros, localstorage etc...

A mi parecer a lo mejor me equivoco pero creo que con lo sencillo que parece puede ser imposible ya que hay que memorizar de alguna manera ese estado y al refrescar la pagina se perdería. Pero quiero una posible solución ya que se que sois unos monstruos en el desarrollo web.

Espero vuestra respuesta, un saludo!

0voto

white comentado

se me ocurrio algo, es muy cutre la alternativa, pero pense en tener a los banners en bas64 y compararlos con un "banner.jpg" que se creara cada refresh:

<?php

    $images = array(
        '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'
    );

    if(!file_exists('banner.jpg')){
        $Base64Img = base64_decode($images[0]);
        file_put_contents('banner.jpg', $Base64Img);
    }
    else
    {
        $banner_img = file_get_contents('banner.jpg');
        $img_data = md5(base64_encode($banner_img));
        $is_current = (md5($images[0]) == $img_data);
        $next_data = $is_current ? $images[1] : $images[0];

        if($is_current)
            unlink('banner.jpg');

        file_put_contents('banner.jpg', base64_decode($next_data));
    }

    echo '<img src="banner.jpg">';

sigo pensando que es luchar con el performance la forma en que quieres resolver tu duda.

0voto

carlossevi comentado

Si quieres tomar una decisión (elegir el banner a mostrar) basada en una condición anterior (cuál se mostró la última vez) necesitas arrastrar información de una ejecución a otra inevitablemente. Posibles opciones:

  • Petición con parámetros (GET, POST...)
  • Sesión
  • Ficheros
  • Base de datos
  • Almacenamiento en navegador

Algunas te permiten alternar el banner entre peticiones del mismo usuario y otras alternarlo entre todas las peticiones. Realmente tengo curiosidad por saber qué te hace tener un requerimiento tan raro.

0voto

Leonardo-Tadei comentado

No entiendo tu propuesta @white... si las imaǵenes estuvierasn codificadas en base64 o si estuvieran en un archivo, no cambia el problema de tener que almacenar el estado de qué banner fue visto para alternarlos, que es justamente la pregunta de @pabeni ...

0voto

white comentado

Es una alternativa mas al tema, de cierta forma pense que el tema no era una duda no aplicada en un caso real. no es una solucion a lo que pide, lo que pide @pabeni con las restricciones que puso, no es posible realizarlo.

1voto

GusGarsaky Puntos5480

Aquí tienes el código que hace lo que deseas. He comentado el código para no explayarme mucho aquí.

<?php
if(!isset($_SESSION)) {
    session_start();
}
$images = array(
    1 => "http://i.imgur.com/oCX8Md2.jpg",
    2 => "http://i.imgur.com/Y4n6RjM.jpg"
);

$index = rand(1,2); // alterna entre 1 y 2

/* si la variable de sesión "index" está establecida y
    además es igual al índice random y si:
   1.- Es igual a 1, pasa a ser 2.
   2.- Es igual a 2, pasa a ser 1.

   La variable de sesión 'index', es una variable que
   almacena el índice anterior obtenido por rand(1,2).
   Si cuando se refresca la página y se saca un rand(1,2)
   igual al anterior, la imagen no cambiaría, entonces
   se evalúa, si es igual al índice anterior se cambia.
   De ésta manera, el rand(1,2) siempre alterna entre 1 y 2.
  */
if(isset($_SESSION["index"])) {
    if($_SESSION["index"] == $index) {
        if($index == 1)
            $index = 2;
        else
            $index = 1;
    }
}
// guarda el indice temporal para la próxima vez que se recarge
$_SESSION["index"] = $index;
$_SESSION["img"] = $images[$index]; // asigna la imagen con el índice establecido

?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Demo cambiar imagen</title>
    <style>
        body {
            background-image: url("<?= $_SESSION['img']?>");
            background-size: cover;
        }
    </style>
</head>
<body>

</body>
</html> 

UPDATE: demo

1voto

Leonardo-Tadei Puntos227320

Hola @pabeni,

ya charlamos de por qué no se puede esto más arriba... así que acá va una "solución" tramposa:

<?php
    $u = date("U");
    $delay = 1;
    if(isset($_GET["a"]) && isset($_GET["t"]) ){
        if($_GET['t']+$delay < $u) {

            switch($_GET["a"]) {
            case '1':
                header("Location:?a=2&t=$u");       
                break;
            case '2':
                header("Location:?a=1&t=$u");       
                break;
            }
        }
    } else {
        header("Location:?a=1&t=$u");   
    }

    switch($_GET["a"]) {
        case '1':
            $banner = 'pegasus.gif';
            break;
        case '2':
            $banner = '1.jpg';
            break;
        default:$banner = '1.jpg';
    }
?>
<!DOCTYPE html>
<html lang="es">
    <head>
        <title>Banner</title>
        <meta charset="utf-8" >
    </head>
    <body>
        <?php
            print "<img src='$banner' />";
        ?>
    </body>
</html>

No funciona si refrescás muy rápido, pero es solucionable usando más resolución en la toma del tiempo y ajustando el delay.

La trampa es que uso el propio URL como "memoria" de lo que está pasando.

Saludos cordiales!

0voto

white comentado

muy buena solucion leonardo C: tenia la misma idea pero tuve problemas con el redireccionamiento, no se me ocurrió nunca usar el tiempo como valor, aporto con un poquito, para el delay se podria usar microtime asi evitamos el problema del refresh rapido, tambien si el usuario tiene mas valores en la url, podria usar http_build_query con un query establecido.

<?php
    $u = round(microtime(true) * 1000);
    $delay = 100;
    $query = $_GET;

    if(isset($_GET["a"]) && isset($_GET["t"]) ){

        if($_GET['t']+$delay < $u) {
            if(in_array($_GET['a'], array('1', '2')))
            {
                $query['a'] = ($_GET['a'] == 1 ? 2 : 1);
                $query['t'] = $u;
            }

            header("Location:?" . http_build_query($query));
        }
    } else {
        $query['a'] = 1;
        $query['t'] = $u;
        header("Location:?" . http_build_query($query));
    }

    switch($_GET["a"]) {
        case '1':
            $banner = 'http://placehold.it/300&text=1';
            break;
        case '2':
            $banner = 'http://placehold.it/300&text=2';
            break;
        default:$banner = 'http://placehold.it/300&text=3';
    }
?>

yo veo esto como una solucion dadas las restricciones puestas de @pabeni.

saludos.

0voto

Leonardo-Tadei comentado

Gracias @white!

Cuando decía que había que mejorar la resolución, justamente estaba pensando en microtime().

El problema de esta solución es que habría que ajustar el valor del delay dependiendo de la velocidad de respuesta de la red que se esté usando...

0voto

pabeni comentado

Perdonadme por no contestar antes, gracias Leonardo-Tadei ya me funciona y el ejemplo que me propones me hes valido.

Un saludo!

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta