1

Bueno resumidamente, estuve buscando la solución por varias horas y no encontré así que recurro a uds...

Resulta que tengo este error al intentar hacer un login al momento de hacer Submit con usuario y contraseña

Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in C:\xampp\htdocs\straga\controllers\connect.php:25 Stack trace: #0 C:\xampp\htdocs\straga\controllers\connect.php(25): PDOStatement->execute() #1 C:\xampp\htdocs\straga\controllers\connection.php(27): create_session_user(Object(PDO), 'tester6', 'tester6') #2 C:\xampp\htdocs\straga\index.php(6): require_once('C:\\xampp\\htdocs...') #3 {main} thrown in C:\xampp\htdocs\straga\controllers\connect.php on line 25

Según leí es por que el campo en la DB tiene como nombre "contraseña" y no "contrasena" , no puedo probar esa solución porque no puedo cambiar ese nombre del campo a contrasena, ya que lee esos datos para ejecutarlos en otra aplicación, no tengo el codigo de la otra aplicación así que no puedo modificar contraseña a contrasena en el codigo... Entonces mi pregunta es, si hay una manera de agregar algo al inicio de la pagina de login o algo, para que si tome lo que hay en el campo contraseña y no me muestre este error si no que siga?... el codigo lo dejo aca abajo.


function create_session_user($db, $username, $password)
{
if (!isset($username) || !isset($password))
    return;
if(!empty($username) && !empty($password))
{
if(!mb_eregi('[^a-zA-Z0-9_]', $username))
{
if(!mb_eregi('[^a-zA-Z0-9_[:punct:]]', $password))
{
$hash = ($password);
$id = trim($username);
$mdp = trim($hash);

global $login_db;

  $resultats = $login_db->prepare('SELECT * FROM cuentas WHERE cuenta=:cuenta AND contraseña=:contraseña') or die('Ha ocurrido un error.');
  $resultats->bindValue(':cuenta', $id, PDO::PARAM_STR);
  $resultats->bindValue(':contraseña', PDO::PARAM_STR);
  $resultats->execute(); //Aqui es donde dice que está el error
  $reponse = $resultats->fetch(PDO::FETCH_ASSOC);

if($reponse == TRUE)
{
    $_SESSION['id'] = $reponse['Id'];
    header('Location: login');
    exit();
}else 
    header('Location: login');
}else 
    header('Location: login');
}else 
    header('Location: login');
}else 
    header('Location: login');
}

Dante
  • 53
  • 6
  • Aparte de que las `ñ` y los acentos podrían dar problemas en algunos escenarios, esto puede resolverse aplicando una codificación adecuada (preferiblemente `utf8`) en los diferentes contextos: PHP, HTML, conexión PDO y Base de Datos. De todos modos el problema ahora está aquí: `$resultats->bindValue(':contraseña', PDO::PARAM_STR);` si observas, no estás padando el dato (que sería el segundo parámetro), deberías por tanto ponerlo así: **`$resultats->bindValue(':contraseña', $mdp, PDO::PARAM_STR);`** Por otra parte, no entiendo por qué todos tus `Location` van al mismo sitio ¿? – A. Cedano Mar 07 '20 at 22:59
  • Estás usando utf-8 como codificación de caracteres? – Pedro Mar 07 '20 at 23:02

1 Answers1

0

Es importante prestar atención a los mensajes de error, aunque estén en inglés, porque indican con claridad cuál es el problema.

En este caso el error es clarísimo:

 Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter
 number: parameter was not defined in ...

En cuanto veas invalid parameter number vete corriendo a revisar los parámetros... verás que en efecto aquí hay un error:

  $resultats->bindValue(':contraseña', PDO::PARAM_STR);

Ahí falta el parámetro, has puesto el marcador de nombre :contraseña y el tipo de dato, PDO::PARAM_STR, pero te falta el valor que debe sustituir el marcador. Asumiendo que es $mdp, el código debería quedar así:

  $resultats->bindValue(':contraseña', $mdp, PDO::PARAM_STR);

En cuanto al problema de la ñ, es cierto que su uso es desaconsejado, así como el uso de los acentos, porque en ciertos escenarios donde haya problemas de codificación se puede producir código erróneo. Pero eso se puede resolver estableciendo una codificación adecuada (por lo general utf8) en todos los niveles1.

Dado que no se puede cambiar el nombre de la columna, porque no tienes acceso a la base de datos, sí puedes mitigar un poco el problema cambiando al menos los marcadores:

$resultats = $login_db->prepare('SELECT * FROM cuentas WHERE cuenta=:cuenta AND contraseña=:mdp') or die('Ha ocurrido un error.');

Y luego:

$resultats->bindValue(':mdp', $mdp, PDO::PARAM_STR);

El marcador de :nombre es algo que puedes cambiar con toda libertad, porque es sólo eso, un marcador. Está claro que debes usar uno que haga referencia a aquello con lo que se está trabajando, para tener claridad en el código.


Notas

  1. Puedes consultar esta respuesta, donde se aborda el problema de la codificación en todos los niveles de una aplicación.
A. Cedano
  • 86,578
  • 19
  • 122
  • 221