[Solucionado] variables dinamicas dentro de funciones ( is_numeric($$variable) )

Iniciado por gAb1, 29 Marzo 2016, 03:54 AM

0 Miembros y 1 Visitante están viendo este tema.

gAb1

Hola, estoy intentando crear un script que declare y limpie las variables de formularios largos, donde hayan arrays de numeros y strings, pero utilizando un whitelist para los nombres de los elementos. Me están dando errores:

CitarWarning: Illegal string offset 'name' in /home/aet/website.com/pages/upload.php on line 34

Notice: Undefined variable: a in /home/aet/website.com/pages/upload.php on line 34
Y
CitarWarning: Illegal string offset 'name' in /home/aet/website.com/pages/upload.php on line 38

Notice: Undefined variable: a in /home/aet/website.com/pages/upload.php on line 38

De momento esto es lo que tengo:

Código (php) [Seleccionar]
$list = array('name' => 'mandatory', 'surname' => 'optional');

foreach ( $list as $name => $nouse ) {
   if (isset($_POST[$name])) {
       if ( is_array($_POST[$name]) ) {
           $$name = filter_input( INPUT_POST , $name , FILTER_SANITIZE_STRING , FILTER_REQUIRE_ARRAY );
           foreach ($$name as $key => $value) {
               $key = preg_replace('[a-z]', '', $key);
               if ( is_numeric($$name[$key]) ) { // this is line 34
                   $$key = (int) $$name[$key];
                   echo $report[$key] = $key . ' variable (from ' . $name . ' ) created1... <span style="color:green;">OK!</span><br>';
               } else {
                   $$key = $$name[$key];  // this is line 38
                   echo $report[$key] = $key . ' variable (from ' . $name . ' ) created2... <span style="color:green;">OK!</span><br>';
               }
           }
       } else {
           if ( is_numeric($_POST[$name]) ) {
               $$name = filter_input( INPUT_POST , $name , FILTER_SANITIZE_NUMBER_INT );
               echo $report[$name] = $name . ' variable created3... <span style="color:green;">OK!</span><br>';
           } else {
               $$name = filter_input( INPUT_POST , $name , FILTER_SANITIZE_STRING );
               echo $report[$name] = $name . ' variable created4... <span style="color:green;">OK!</span><br>';
           }
       }
   } else {
       if ($list[$name] == 'optional') {
           $$name = 0;
           echo $report[$name] = $name . ' (optional) variable not filled5... <span style="color:green;">OK!</span><br>';
       } else die('Error: You must fill all mandatory fields! (' . $name . ')');
   }
}


El html es de lo más sencillo, los arrays los tengo asi:

Código (html5) [Seleccionar]
<input type="text" name="address_book[name]" />
<input type="text" name="address_book[surname]" />


¿Alguna idea de por qué no funciona?  :-\

Gracias!

ivancea96

¿Y así?
Código (html) [Seleccionar]
<input type="text" name="name" />
<input type="text" name="surname" />

gAb1

Así seguramente funcionaria, pero el objetivo es automatizar para facilitar el proceso. Cuando hay formularios largos, con muchos campos (unos 40-50) se crean los arrays para agrupar y separar (organizar) los campos.

La cuestión es saber por qué no funciona y saber arreglarlo. Cuando los formularios apenas tienen 10-15 campos pues si que es mejor hacerlo a mano, pero cuando hay más de 40 la cosa cambia, además de poder usarlo en todos los formularios que necesites.

ivancea96

Si quieres automatizarlo, puedes poner un nombre del tipo address_book_name.

El caso es que le estas dando un nombre, y luego accedes a él con otro.

Si quieres pasar con el mismo nombre múltiples formularios, puedes pasar un hidden con un identificador del formulario:

Código (html) [Seleccionar]
<input type="hidden" name="type" value="address_book" />

Luego en el PHP, por ejemplo:

Código (php) [Seleccionar]
if($_POST['type'] == 'address_book') ...

Y ya, como sea que lo quieras hacer.


Si van a ser muchos campos de un mismo formulario, entonces no hay mucho más que decir. Todos van a tener nombres diferentes. Si quieres automatizar el acceso a todos estos, puedes ponerles un prefijo y acceder mediante el array de POST a los que tengan ese prefijo.

gAb1

No entiendo lo del hidden, pero entiendo que dices que no use arrays, sea por la razón que sea pero no la dices.

¿Por qué dices que le doy un nombre y luego accedo con otro? Creo que eso no es cierto, el script deja bien claro que el nombre del elemento es el usado para acceder al array:

Código (php) [Seleccionar]
$name = 'address_book';

$$name = $_POST[$name];

foreach ($$name as $key => $value) {
   if ( is_numeric($$name[$key]) ) {
       $$key = (int) $$name[$key];
   }
}


Si no me equivoco, lo de arriba es lo mismo que hacer:

Código (php) [Seleccionar]
$address_book = $_POST['address_book'];

foreach ($address_book as $key => $value) {
   if ( is_numeric($address_book[$key]) ) {
       $name/$surname = (int) $address_book[$key];
   }
}


No??

Si es incorrecto lo que intento hacer, dimelo, ya que no me estoy enterando de nada, ¿es un error en la manera de querer hacer esto?

Si no hay nada malo en usar arrays, preferiria hacerlo así a tener que llenar un whitelist con más de 40 nombres. Que pongan lo que quieran en los keys del array, el preg_replace dejará solo letras minusculas y con eso no se puede hacer nada, el prepare dará error al no tener las variables necesarias y no sé ejecutará nada en la base de datos, no veo el problema por ninguna parte.

Código (php) [Seleccionar]
if ($stmt->error()) {
   die('Database Error');
}


EDITO: Habia otro problema, que al parecer ninguno de los dos nos habiamos dado cuenta... La variable $name que contiene el valor del formulario estaba sobreescribiendo la variable $name del primer foreach... Le he cambiado el nombre y ahora puedo ver el mismo error para todos los campos del array address_book:

CitarWarning: Illegal string offset 'name' in /home/aet/website.com/pages/upload.php on line 34

Notice: Undefined variable: a in /home/aet/website.com/pages/upload.php on line 34

Warning: Illegal string offset 'name' in /home/aet/website.com/pages/upload.php on line 38

Notice: Undefined variable: a in /home/aet/website.com/pages/upload.php on line 38
name variable (from address_book ) created2... OK!

Warning: Illegal string offset 'surname' in /home/aet/website.com/pages/upload.php on line 34

Notice: Undefined variable: a in /home/aet/website.com/pages/upload.php on line 34

Warning: Illegal string offset 'surname' in /home/aet/website.com/pages/upload.php on line 38

Notice: Undefined variable: a in /home/aet/website.com/pages/upload.php on line 38
surname variable (from address_book ) created2... OK!

gAb1

Ok I got it! ;D

El problema está en que no necesito el nombre del elemento para declarar el array:

Código (php) [Seleccionar]
foreach ( $list as $element_name => $nouse ) {
    if (isset($_POST[$element_name])) {
        if ( is_array($_POST[$element_name]) ) {
            $filtered_data = filter_input( INPUT_POST , $element_name , FILTER_SANITIZE_STRING , FILTER_REQUIRE_ARRAY );
            foreach ($filtered_data as $key => $value) {
                $key = preg_replace('[a-z]', '', $key);
                if ( is_numeric($value) ) { // this is line 34
                    $$key = (int) $value;
                    echo $report[$key] = $key . ' variable (from ' . $element_name . ' ) created1... <span style="color:green;">OK!</span><br>';
                } else {
                    $$key = $value;  // this is line 38
                    echo $report[$key] = $key . ' variable (from ' . $element_name . ' ) created2... <span style="color:green;">OK!</span><br>';
                }
            }
        } else {
            if ( is_numeric($_POST[$element_name]) ) {
                $$element_name = filter_input( INPUT_POST , $element_name , FILTER_SANITIZE_NUMBER_INT );
                echo $report[$element_name] = $element_name . ' variable created3... <span style="color:green;">OK!</span><br>';
            } else {
                $$element_name = filter_input( INPUT_POST , $name , FILTER_SANITIZE_STRING );
                echo $report[$element_name] = $element_name . ' variable created4... <span style="color:green;">OK!</span><br>';
            }
        }
    } else {
        if ($list[$element_name] == 'optional') {
            $$element_name = 0;
            echo $report[$element_name] = $element_name . ' (optional) variable not filled5... <span style="color:green;">OK!</span><br>';
        } else die('Error: You must fill all mandatory fields! (' . $element_name . ')');
    }
}