2012-05-30 31 views
31

Estoy tratando de volver a aprender algunos conceptos básicos de PHP para hacer un script de inicio de sesión simple, sin embargo recibo un error que no he recibido antes (hice el mismo script hace poco más de un año y nunca tuve este error . que simplifica el código tanto como pude para probar para ver qué área era problemático y aquí está la cuestión:

<?php 
$user = $_POST["username"]; 
if($user != null) 
{ 
    echo $user; 
    echo " is your username"; 
} 
else 
{ 
    echo "no username supplied"; 
} 
?> 

Ahora bien, este código funciona bien cuando envío una variable a la secuencia de comandos, pero cuando no existe ninguna variable suministrado arroja un error. En teoría, esto estará bien porque si no se proporciona un nombre de usuario/contraseña, entonces se espera un error. Verificaré esto antes de que el código se envíe al script, sin embargo, me temo que de alguna manera una cuerda en blanco puede filtrarse y escupir alguna ONU error conocido Aquí está el error que consigo:

(!) Notice: Undefined index: username in C:\wamp\www\verify_login.php on line 2 

Call Stack 

    Time Memory Function Location 
1 0.0003 668576 {main}() ..\verify_login.php:0 

ningún nombre de usuario suministra

como se puede ver el código registra que ninguna variable se suministra, pero da salida y el error que supongo significa que no se encontró una variable se esperaba uno o algo así. ¿Alguien puede aclarar esto por mí?

+0

publique su código para el formulario. Parece que _POST [nombre de usuario] no está configurado –

+0

Porque si está haciendo todo correctamente, acaba de nombrar en el método de la página HTML 'get' y está capturando el parámetro con '$ _POST'. En su lugar, debe cambiarle el nombre a $ _GET. Eso es todo. – CodeToLife

Respuesta

39

En PHP, una variable o elemento de matriz que nunca se ha establecido es diferente de uno cuyo valor es null; intentar acceder a un valor de unset es un error de tiempo de ejecución.

Eso es lo que te encuentras: la matriz $_POST no tiene ningún elemento en el índice "username", por lo que el intérprete aborta tu programa antes de que llegue a la prueba de nulidad.

Afortunadamente, puede probar la existencia de una variable o elemento de matriz sin intentar acceder a él; eso es lo que hace el operador especial isset:

if (isset($_POST["username"])) 
{ 
    $user = $_POST["username"]; 
    echo $user; 
    echo " is your username"; 
} 
else 
{ 
    $user = null; 
    echo "no username supplied"; 
} 

Esto parece que va a explotar exactamente de la misma manera que el código, cuando PHP trata de obtener el valor de $_POST["username"] pasar como argumento a la función isset().Sin embargo, isset() no es en realidad una función, sino una sintaxis especial reconocida antes de la etapa de evaluación, por lo que el intérprete de PHP verifica la existencia del valor sin intentar recuperarlo.

También vale la pena mencionar que, como los errores de tiempo de ejecución van, un índice de matriz faltante se considera de menor importancia (se le asigna el nivel E_NOTICE). Si cambia el nivel error_reporting para que los avisos se ignoren, su código original funcionará tal como está escrito, con el intento de acceso a la matriz devolviendo null. Pero eso se considera una mala práctica, especialmente para el código de producción.

Nota al margen: PHP hace la interpolación de cadenas, por lo que los echo instrucciones en el bloque if se puede combinar en una sola:

echo "$user is your username"; 
+5

Gracias. Respuesta muy completa pero simple sobre por qué me sale este error y cómo resolverlo. No solo quería una respuesta de "Cómo solucionar/deshacerme de este error", quería entenderla y eso es lo que hizo por mí, gracias. –

+0

@ViperCode su variable '$ _POST [" username "]' no se configuró – Bender

6

Uso:

if (isset($_POST['user'])) { 
    //do something 
} 

Pero probablemente debería utilizar una validación más adecuada. Pruebe con una simple expresión regular o una implementación sólida de Zend Framework o Symfony.

http://framework.zend.com/manual/en/zend.validate.introduction.html

http://symfony.com/doc/current/book/validation.html

O incluso la incorporada en el filtro de extensión:

http://php.net/manual/en/function.filter-var.php

entrada del usuario Nunca confianza, ser inteligente. No confíes en nada Siempre asegúrate de que lo que recibas sea realmente lo que esperas. Si debe ser un número, asegúrese de que sea un número.

Mucho código mejorada:

$user = filter_var($_POST['user'], FILTER_SANITIZE_STRING); 
$isValid = filter_var($user, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => "/^[a-zA-Z0-9]+$/"))); 

if ($isValid) { 
    // do something 
} 

de desinfección y validación.

+1

alternativamente, puede usar 'array_key_exists ($ _ POST, 'user')' – mpen

+0

Me gusta lo que ha dicho sobre asegurarse. Esto va a ser básicamente un script de inicio de sesión y planeo usar mysql_real_escape(); Yo creo que es lo que se llama. los nombres de usuario serán cualquier combinación de cosas y las contraseñas solo deben ser MD5, hash en el programa antes de enviarse al script.También debo señalar que esto es una validación para un juego, no para un sitio. –

+0

Nunca, NUNCA, use mysql_real_escape(). Obtenga información sobre declaraciones preparadas y comience a usar PDO. http://php.net/manual/pdo.prepared-statements.php – vinnylinux

1

Cuando dicen:

$user = $_POST["username"]; 

Usted está pidiendo el PHP intérprete para asignar $user el valor de la matriz $_POST que tiene una clave (o índice) de username. Si no existe, PHP lanza un ataque.

Uso isset($_POST['user']) para comprobar la existencia de esa variable:

if (isset($_POST['user'])) { 
    $user = $_POST["username"]; 
    ... 
+0

Gracias, al igual que lo explicó mark reed. –

3

Su código asume la existencia de algo:

$user = $_POST["username"]; 

PHP está dejando saber que no hay un "nombre de usuario "en la matriz $_POST. En este caso, sería más seguro para comprobar si el valor isset() antes de intentar acceder a ella:

if (isset($_POST["username"])) { 
    /* ... proceed ... */ 
} 

Como alternativa, puede secuestrar el operador || para asignar un valor predeterminado:

$user = $_POST["username"] || "visitor" ; 

Siempre que el nombre del usuario no sea falsey, puede considerar que este método es bastante confiable. Una ruta mucho más segura a los valores de asignación sería utilizar el operador ternario:

$user = isset($_POST["username"]) ? $_POST["username"] : "visitor" ; 
0

tratar

if(isset($_POST['username'])) 
    echo $_POST['username']." is your username"; 
else 
    echo "no username supplied"; 
+1

Gracias. Simplemente no me había encontrado con este error antes y ahora lo entiendo. –

-2

pregunta relacionada:What is the best way to access unknown array elements without generating PHP notice?

Usando la respuesta de la pregunta anterior, puede obtener un valor de $ _POST sin generar un aviso de PHP si la clave no existe.

echo _arr($_POST, 'username', 'no username supplied'); 
// will print $_POST['username'] or 'no username supplied' 
+0

Esto está mal en muchos niveles ... – vinnylinux

+0

Downvoters & @vinnylinux: ¿Por qué está mal? – flowfree

+0

Probablemente porque no produce el resultado que desea OP '[username] es tu nombre de usuario' (no soy el que votó negativamente, si eso importa, entonces la razón puede ser diferente)? – tigrang

1

En lugar de isset() se puede usar algo más corto consiguiendo errores silenciados, es @$_POST['field']. Luego, si el campo no está configurado, no obtendrá ningún error impreso en una página.

1

Prueba esto:

yo uso esto en todas partes donde hay una petición $ _POST.

$username=isset($_POST['username']) ? $_POST['username'] : ""; 

esto es sólo un booleano mano resumen, si isset fijará a $ _POST [ 'nombre de usuario'], si no, entonces se fijará a una cadena vacía.

ejemplo

Uso:

if($username===""){ echo "Field is blank" } else { echo "Success" }; 
1

Antes de PHP 5.2.0 y superior se debe utilizar filter_input() que está especialmente creado para eso para conseguir un usuario introduce externos específicos, tales como obtener, las variables de correos o por su nombre y galletas opcionalmente lo filtra para evitar cualquier ataque XSS/Injection en su sitio. Por ejemplo:

$user = filter_input(INPUT_POST, 'username'); 

Es posible utilizar uno de INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER o INPUT_ENV.

Mediante el uso de tercera argumento opcional, se puede extender por diversas filters (por validating, sanitizing, filtering o other), por ejemplo, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_ENCODED, etc.

Por ejemplo:

<?php 
$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS); 
$search_url = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_ENCODED); 
echo "You have searched for $search_html.\n"; 
echo "<a href='?search=$search_url'>Search again.</a>"; 
?> 

La sintaxis es:

mixto filter_input (int tipo $, string $ variable_name [, filtro int $ = FILTER_DEFAULT [, mezclado $ opciones]])

(PHP 5> = 5.2.0, PHP 7)

Consulte también: Why is better to use filter_input()?

0

Sé que esto es antiguo puesto, pero puedo ayudar a alguien:

function POST($index, $default=NULL){ 
     if(isset($_POST[$index])) 
     { 
      if(!empty(trim($_POST[$index])))  
       return $_POST[$index]; 
     } 
     return $default; 
    } 

Este código es mi función básica de POST lo que yo uso en cualquier lugar. Aquí puedes poner filtros, expresiones regulares, etc. Es más rápido y limpio. Mi función POST avanzada es más complicada para aceptar y verificar matrices, tipo de cadena, valores predeterminados, etc. Déjenos trabajar su imaginación aquí.

Es fácil puede comprobar nombre de usuario así:

$username = POST("username"); 
if($username!==null){ 
    echo "{$username} is in the house."; 
} 

También he añadido $default cadena que se puede definir un valor por defecto si la POST no está activo o no existe contenido.

echo "<h1>".POST("title", "Stack Overflow")."</h1>"; 

Jugar con él.