URL treatment to avoid errors

3

I would like to know if there is any function or method to evaluate when the user enters in the URL unwanted text or erroneous data that may "malfunction" the web. That is: if you delete any extension of the URL or insert unwanted characters, which instead of returning an error such as:

Notice: Undefined index: idcabana in C:\xampp\htdocs\daw\modificar.php on line 57
No existe el ID

We can have the option of displaying a customized screen for that error to make it more visible and usable (using W3C or HTML5 or CSS), as a test, with putting a message in the form of echo "" would be enough.

Example: If we delete from http://localhost/daw/modificar.php?idcabana=3 , the last 4-5 characters, and press Enter, we have the following URL: http://localhost/daw/modificar.php?idcaba , which does not have any data and all the data that be passed to this page will be unrecognized, to avoid problems, put an echo ....

In this case, as expected "idcabana" and can not find it in the URL, it gives the error "Undefined index: idcabana".

HTML / PHP code:

<?php
    require_once "Clases/BD.php";
    require_once "Clases/Cabanas.php";
    require_once "Clases/Accesorios.php";
    require_once "conexion.php";
    //Si existe la sesión "administrador"..., la guardamos en una variable.
    if (isset($_SESSION['administrador'])){
        $administrador = $_SESSION['administrador'];
    }

    //Si pulsamos el botón "Modificar"...
    if(isset($_POST["modificar"])){
        $idcabana = $_POST["idcabana"];
        $nombre = $_POST["nombre"];
        $capacidad = $_POST["capacidad"];
        $descripcion = $_POST["descripcion"];
        $precio = $_POST["precio"];
        $array_accesorios = $_POST["accesorios"];
        BD::modificarCabana($idcabana, $nombre, $capacidad, $descripcion, $precio);
        BD::modificarAccesoriosPorCabana($idcabana, $array_accesorios);
        header("Refresh:0; url=panel_administrador.php");
    }

    //Si pulsamos el botón "Atras"...
    if(isset($_POST["atras"])){
        header("Refresh:0; url=panel_administrador.php");
    }
?>

<!DOCTYPE html>
<html lang="es">    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Modificar cabaña</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <link rel="stylesheet" href="css/estilos_modificar.css">
    </head>
    <body>
        <?php
        function in_multiarray($elemento, $array, $campo){
            $top = sizeof($array) - 1;
            $bottom = 0;
            while($bottom <= $top){
                if($array[$bottom][$campo] == $elemento)
                    return true;
                else 
                    if(is_array($array[$bottom][$campo]))
                        if(in_multiarray($elemento, ($array[$bottom][$campo])))
                            return true;
                $bottom++;
            }        
            return false;
        }

        //Guardamos en una variable los ids de las cabañas.
        $ids = BD::obtenerIDsCabanas();
        //Si ese id no está en la tabla cabanas, mostramos un error.
        if(!in_multiarray($_REQUEST["idcabana"], $ids, "idcabana")){
            echo "No existe el ID";
        }else{
        ?>
        <div id="sesion_administrador">
            <?php 
            if(isset($_SESSION['administrador'])){
                echo "Bienvenido ".$administrador."&nbsp;&nbsp;&nbsp;";
                echo "<a href='salir_administrador.php?salir=1'>Salir</a>"; //GET
                //_REQUEST = $_POST o $_GET
                if(isset($_REQUEST["salir"])){
                    unset($_SESSION["administrador"]);
                    header("Refresh:0; url=iniciar_sesion_administrador.php");
                }
            }
            ?>
        </div>
        <br/><br/><br/>
        <div id="mostrar_datos">
            <!-- Modificar cabaña -->
            <form action="modificar.php" name="modificar" id="modificar" method="POST">
            <?php $objeto_cabana = BD::datosCabana($_REQUEST["idcabana"]); ?>
                <label for="idcabana">ID: </label>
                    <?php $longitud_idcabana = strlen($objeto_cabana->getIdcabana()); ?>
                    <input type="text" size="<?php echo $longitud_idcabana; ?>" id="idcabana" name="idcabana" readonly="readonly" value="<?php echo $objeto_cabana->getIdcabana(); ?> "/>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!-- Aqui va: <br/><br/> -->
                <label for="nombre">Nombre: </label>
                    <?php $longitud_nombre = strlen($objeto_cabana->getNombre()); ?>
                    <input type="text" size="<?php echo $longitud_nombre; ?>" id="nombre" name="nombre" value="<?php echo $objeto_cabana->getNombre(); ?> "/>
                <br/><br/>
                <label for="capacidad">Capacidad: </label>
                    <?php
                    echo "<select name='capacidad'>";
                    for($i=1; $i<11; $i++){
                        if($i==$objeto_cabana->getCapacidad()){
                            echo "<option value='$i' selected>$i</option>";
                        }else{
                            echo "<option value='$i'>$i</option>";
                        }
                    }
                    echo "</select>";
                    ?>
                <br/><br/>
                <label for="descripcion">Descripción: </label>
                    <?php $longitud_descripcion = strlen($objeto_cabana->getDescripcion()); ?>
                    <input type="text" size="<?php echo $longitud_descripcion; ?>" id="descripcion" name="descripcion" value="<?php echo $objeto_cabana->getDescripcion(); ?> "/>
                <br/><br/>
                <label for="precio">Precio: </label>
                    <?php $longitud_precio = strlen($objeto_cabana->getPrecio()); ?>
                    <input type="text" size="<?php echo $longitud_precio; ?>" id="precio" name="precio" onkeypress="return soloNumeros(event);" value="<?php echo $objeto_cabana->getPrecio(); ?> "/>
                <br/><br/>

                <div class="mostrar_accesorios" id="mostrar_accesorios">
                    <center>
                        <h3><b>Accesorios</b></h3><br/>
                        <?php 
                        $objeto_accesorios = BD::obtenerAccesoriosPorCabana($_REQUEST["idcabana"]);
                        $todos_accesorios = BD::todosAccesorios();
                        foreach($todos_accesorios as $objeto){
                            $existe = false;
                            foreach($objeto_accesorios as $columna){
                                //Si el accesorio global está en el accesorio de la cabaña, true.
                                if($objeto->getIdaccesorio() == $columna->getIdaccesorio()){
                                    $existe = true;
                                    break;
                                }
                            }
                            if($existe){
                                echo "<div style='float:left; width:30%'><img src='imagenes/".$objeto->getDescripcion().".png' height='28px' width='34px' title='".$objeto->getDescripcion()."'/><br/><label for='accesorio".$objeto->getIdaccesorio()."'><input type='checkbox' value='".$objeto->getIdaccesorio()."' id='accesorio".$objeto->getIdaccesorio()."' name='accesorios[]' checked>".$objeto->getDescripcion()."</label></div>";
                            }else{
                                echo "<div style='float:left; width:30%'><img src='imagenes/".$objeto->getDescripcion().".png' height='28px' width='34px' title='".$objeto->getDescripcion()."'/><br/><label for='accesorio".$objeto->getIdaccesorio()."'><input type='checkbox' value='".$objeto->getIdaccesorio()."' id='accesorio".$objeto->getIdaccesorio()."' name='accesorios[]'>".$objeto->getDescripcion()."</label></div>";
                            }
                            $existe = false;        
                        }
                        ?>
                        <div style="clear:left"></div>
                        <br/><br/>
                        <form>
                            <input type="submit" value="Atrás" id="atras" name="atras" />
                        </form>
                        <!--<a href="javascript:history.back(-1);" title="Ir la página anterior">Atrás</a>-->
                        <input type="submit" value="Modificar" id="modificar" name="modificar" />
                    </center>
                </div>
            </form>
        </div>
        <?php 
        }
        ?>
    </body>
</html>
    
asked by omaza1990 14.12.2017 в 10:51
source

4 answers

5

The procedure that I have implemented on my website.

It is composed as follows:

First of all I get the information from Url example.com/detella.php?pro=1

Then the value obtained from the variable $url proceeded to make the query, to verify if that received information exists or not.

  if (isset($_GET['id'])) {
    $url = $_GET['id'];
    $stmt = $con->prepare("SELECT id,product,price FROM product WHERE id=? limit 1");
  }

$stmt->bind_param("i",$url);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($id, $product, $price);

if ($stmt->fetch()) {

  //Código
} else {
   include 'error404.php';
}

If the information received does not exist, a custom theme is displayed, whether the user enters the page directly with no value in the url example: example.com/detalle.php or if you enter incorrect values example.com/detalle.php?pro=3nfnnd the error template is shown, because the data obtained from the url does not match in the database.

Another example:

if ($stmt->num_rows>0) {
  $stmt->bind_result($id, $product, $price);
   while ($stmt->fetch()) {
     // code...
   }
}else{
  echo "No existe producto";
  //include 'error404.php';
}
    
answered by 14.12.2017 в 11:42
2

I use a code similar to this in an API, to control the URLs that are passed to the server.

In theory the code does the following:

  • Evaluate the request using $_GET['PATH_INFO']
  • Handle valid URLs using a $recursos_existentes array. If you pass a URL that is not in that array, you can raise an Exception or display the 404 error page or whatever you want.
  • In addition, it evaluates and controls the type of request that is being made. Here you can for example control that only the code works when the request is of type GET , etc.
  • This is a more complex script, which handles requests made to an API, using the MVC pattern. In it I do not redirect or include files, but I always use a View to always respond with a JSON object that shows, whether the errors, or the correct data.

    I have adapted it a bit to your problem. I have not tried it ... I hope I have not made any mistakes. If you are interested in exploring this possibility, try and comment on the results.

    I particularly like the style of how APIs work. That is, always generate a JSON and read said JSON in the View, showing what the JSON brings, whether it is an error, it is correct data. It seems to me an organized, effective style of programming and it's the way I'm programming now in PHP in general, not just in an API or in REST type requests.

    I hope it serves you.

    <?php
    
    // Extraer segmento de la url
    if (isset($_GET['PATH_INFO'])){
        $peticion = explode('/', $_GET['PATH_INFO']);
        $recurso = array_shift($peticion);
        $recursos_existentes = array('idcabana'); //Aquí completas el array con las url válidas
    
        // Comprobar si existe el recurso
        if (!in_array($recurso, $recursos_existentes)) {
            //El recurso no existe. Lanzar una excepción o incluir la página de error 404
        }else{
    
            //Obtener el método utilizado: Get, Post, Put, Delete...
            $metodo = strtolower($_SERVER['REQUEST_METHOD']);
    
            // Filtrar método
            switch ($metodo) {
            case 'get':
                switch ($recurso) {
    
                case 'idcabana':
                    //Lanzar consulta para obtener idcabana. El id estará en $peticion[0]
                    break;
    
                    //otros case
    
                default:
                    //Lanzar excepción o incluir mensaje de error
                    break;
    
                }
                /*
                        * Si interesan los métodos POST o PUT, definir las acciones de los mismos
                        * tal y como se ha hecho con GET más arriba
                        * Aquí no los he definido porque por el momento no interesan y el método delete
                        * lo he dejado vacío para proteger los datos...
                    */
    
                /*
                    case 'post':
                    case 'put':
                    */
    
            case 'delete':
                break;
    
            default:
                // Método no aceptado
                //Lanzar excepción o incluir mensaje de error
    
            }
    
        }
    
    }else{
    
        //No hay nada en el PATH_INFO. Lanzar excepción o incluir página con mensaje de error
    
    }
    
        
    answered by 14.12.2017 в 12:43
    1

    Let's see if we put some light.

    In this question are mixing 2 things, the concept of URI and the parameters or values that may or may not have a URI, that is, we are talking about composite URIs on the one hand we have the address of the resource protocolo + dominio + ruta and on the other the query, the values or parameters that are passed to said resource after the symbol ? .

    There are multiple ways to manage or control both the route and the past values, but both are usually addressed separately and differentiated.

    For this case we will focus on the http protocol on a server with apache and php, ignoring the rest.

    Web addresses

    The 2 most used methods for http requests in PHP are:

    • Control access to URLs directly in the server configuration. By default
    • Redirect all requests to a PHP file to have more control, which will be responsible for managing the routes and the methods used to access.

    For example with apache in file .htaccess

    ErrorDocument 500 /ruta/error_500.php 
    ErrorDocument 500 /ruta/error_500.php 
    ErrorDocument 500 /ruta/error_500.php 
    ErrorDocument 404 /ruta/error_404.php 
    ErrorDocument 401 /ruta/error_401.php 
    

    Sent parameters

    The way to validate the sent parameters is more controversial and the formulas used to cover this aspect vary greatly.

    The most optimal thing in my opinion is to create a class or function to assume this and not have to write redundant code since it is a resource that we use frequently.

    For example, you could create a small function to check if the parameters required for the script have been sent.

    function has_request(Array $parametros, $method='REQUEST') { 
        switch ($method) {
            case 'REQUEST':
                $data = $_REQUEST;
                break;
            // puedes añadir los otros case para post y get
            default:
                return false;
                break;
        }
    
        foreach($parametros as $key => $value) {
            if (!array_key_exists($value, $data)) {
                return false;
            }
        }
        return $parametros;
    } 
    
    
    
    
    $camposNecesarios = array ('id', 'idCabana');
    
    if ($campos = has_request($camposNecesarios)) {
        echo 'se enviaron los campos necesarios';
        print_r($campos);
    } else {
        echo 'No se enviaron los campos necesarios';
    } 
    
        
    answered by 14.12.2017 в 14:23
    1

    The famous Notice: Undefined index: idcabana in C:\xampp\htdocs\daw\modificar.php on line 57 is because sometimes there is no such variable $idcabana , to avoid this it is advisable to reset the variables at the beginning of the program.

    A possible example:

    //Reset.
    $idcabana = $nombre = $capacidad = NULL; 
    
    //Si pulsamos el botón "Modificar"...
    if(isset($_POST["modificar"])){
        $idcabana = $_POST["idcabana"];
        $nombre = $_POST["nombre"];
        $capacidad = $_POST["capacidad"];
        //etc..
    }
    //En caso que no existe dicha variable no va lanzar el 'Notice'.
    //Ya que al inicio lo hemos reseteo en NULL.
    echo $idcabana;
    

    With this simple you will avoid the Notice: Undefined index .


    You already have good answers to research and learn how to treat your url obtained by GET , I have encouraged to leave another alternative easy to understand.

    If you want to check that the url is defined and that its parameter is valid ( int ), you could create something like:

    //Reseteo.
    $idcabana = NULL;
    
    //Comprobamos si está definido nuestra URL (get).
    if (isset($_GET['idcabana'])) {
        //Comprobamos que nuestro 'ID' sea un entero.
        if (!filter_var($_GET['idcabana'], FILTER_VALIDATE_INT) === false) {
            //Obtenemos el ID desde la url.
            $idcabana = $_GET['idcabana'] ?: '';
        } else { //En caso que no es un ID valido podrías re direccionar a otra página.
            header('location: pagina-error.php');
            exit();
        }
    } else { //En caso que no existe el ID podrías re direccionar a otra página.
        header('location: pagina-error.php');
        exit();
    }
    
    //Comprobar que exista nuestro 'ID' con el que vamos a trabajar.
    if ($idcabana) {
    
         //Nuestro 'ID' existe.
        //Creas tu sentencia.
    
       //Compruebas sentencia.
       if(sentencia === true) {
           //Mensaje.
       } else {
          //Re direccionar a otra página.
       }
    
    }
    

    isset - Determines if a variable is defined and is not NULL.

    filter_var - Filter a variable with the indicated filter.
    filtros de validación - List of filters for validation.

        
    answered by 14.12.2017 в 23:26