Registro de usuario, como puedo mejorar este código?

  • Autor Autor YeltsinReyes
  • Fecha de inicio Fecha de inicio

YeltsinReyes

Mi
Verificación en dos pasos activada
Verificado por Whatsapp
Verificado por Binance
Que tal, nunca eh hecho un registro de usuario con login y hoy me eh puesto a ver tutoriales, tengo este código y
me gustaría su opinión de si esta bien o como puedo mejorarlo?

Registrar usuario
PHP:
<?php

error_reporting(E_ALL);
require_once('conexion.php');

if(!empty($_POST)){
 
    $nombre = trim($_POST['nombre']);
    $nombre = mysqli_real_escape_string($con, $nombre);
 
    $correo = trim($_POST['correo']);
    $correo = mysqli_real_escape_string($con, $correo);
 
    $contrasena = trim($_POST['contrasena']);
    $contrasena = mysqli_real_escape_string($con, $contrasena);
 
    $recontrasena = trim($_POST['recontrasena']);
    $recontrasena = mysqli_real_escape_string($con, $recontrasena);

    $query = mysqli_query($con, 'SELECT correo FROM
    usuarios WHERE correo = "'.$correo.'" LIMIT 1');
 
    $numrows = mysqli_num_rows($query);
 
    if(!isset($nombre) or empty($nombre)){
        $alerts[] = 'Agrega tu nombre completo.';
    }
 
    if(!isset($correo) or empty($correo)){
        $alerts[] = 'Agrega tu correo electronico.';
    }
 
    if(!isset($contrasena) or empty($contrasena)){
        $alerts[] = 'Agrega tu contrasena.';
    }
 
    if(!isset($recontrasena) or empty($recontrasena)){
        $alerts[] = 'Repite tu contrasena.';
    }
 
    if($contrasena !== $recontrasena){
        $alerts[] = 'Las contrasena no son iguales.';
    }

    if(!isset($query) or empty($query)){
        $alerts[] = 'Error al verificar el correo electronico.';
    }
 
    if(!isset($numrows) or !empty($numrows)){
        $alerts[] = 'El correo electronico ya existe.';
    }

    if(!isset($alerts) or empty($alerts)){
     
        $contrasena = password_hash($contrasena, PASSWORD_DEFAULT);
     
        $query = mysqli_query($con, 'INSERT INTO usuarios (nombre, correo, contrasena)
        VALUES ("'.$nombre.'", "'.$correo.'", "'.$contrasena.'")');
     
        if(isset($query) && !empty($query)){
            $alerts[] = 'Usuario registrado!';
        } else {
            $alerts[] = 'Error al registrarte.';
        }
     
    }
 
    mysqli_close($con);
 
}

?>
 
Última edición:
Yo en primer lugar dejaría el estilo por procedimientos y aplicaría el codigo orientado a objetos, por otra parte verificaría si el correo es valido con filter_var() y el filtro "FILTER_VALIDATE_EMAIL", otra cosa importante que cambiaria de tu codigo es mover esas comprobaciones de campos vacíos y validación de contraseña en primer lugar, y si da error detener el flujo del registro para no hacer peticiones a la base de datos innecesariamente, finalmente si no hay ningún error, hacer la consulta a la db y comprobar si el email existe o no.
 
Ok bro, y que me dices para evitar inyecciones sql?
 
Tal como te dice el usuario anterior busca información sobre PDO_MYSQL. Es más seguro que mysqli.
 
Ok bro, y que me dices para evitar inyecciones sql?
Como te dicen, mejor PDO.

En todo caso, uses uno u otro, debes utilizar consultas con parámetros para asegurar que los datos que añaden están "sanitizados" y no contienen ninguna inyección de código.

Con mysqli lo puedes hacer más o menos así.

Insertar CODE, HTML o PHP:
$query = $conn->prepare('INSERT INTO usuarios (nombre, correo, contrasena) VALUES (?, ?, ?)');
$query->bind_param("sss", $nombre, $email, $password);
$query->execute();
 
Para fines didácticos se ve bien, igual como mencionaron, para el tema de acceso a BBDD me iría con PDO en vez de Mysqli. Por cierto la documentación de PHP tiene muy buenos ejemplos de conexiones y consultas usando excepciones y buenas prácticas. https://www.php.net/manual/es/book.pdo.php

¿Se puede mejorar? Sí, por supuesto. No sé si sepas POO, pero en ese caso lo metería en clases porque traes un bloque if de casi 30 líneas y al parecer va a crecer más y más... Pero bueno, esto es más tema de estilos.
 
Si preparo la consulta ya no tengo que usar mysqli_real_escape_string?
 
saludos, el proceso de registro de un usuario parece sencillo, pero en realidad es mucho mas complejo de lo que parece, espero que con este codigo pueda ayudaros a comprender mejor el proceso de registro:

conexion.php
PHP:
<?php

// datos de conexion
$DB_HOST = "127.0.0.1";
$DB_USER = "root";
$DB_PASS = "password";
$DB_NAME = "database";

// hash unico de encriptacion para las passwords almacenadas en la base de datos:
$encryption = "5o019-X4v3O6E8WBZVHTGL-l3Ty50-Y3rZvxNmt";

// creamos la conexion
$mysqli = @new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);
if (mysqli_connect_errno()) {
    echo 'No se ha podido establecer la conexion a la base de datos';
    die();
}

// funcion para asegurar los datos que se van a insertar en la base de datos
function escape($t){
    global $mysqli;
    return $mysqli->real_escape_string(trim(htmlspecialchars($t, ENT_QUOTES)));
}

// funcion para encriptar la contraseña
function encrypt($d){
    global $encryption;
    return sha1(str_rot13($d . $encryption));
}


?>



registro.php


PHP:
<?php
require_once('conexion.php');

// nos aseguramos que todos los datos enviados sean los correctos
if(isset($_POST['nombre'],$_POST['correo'],$_POST['contrasena'],$_POST['recontrasena'])){
    
    // si alguno de los datos esta vacio retorna con un error
    if(empty($_POST['nombre']) || empty($_POST['correo']) || empty($_POST['contrasena']) || empty($_POST['recontrasena']) ){
        echo 'Hay datos vacios';
        die(); // detenemos la ejecucion del script
    }
    
    echo registrar_usuario();
    die(); // detenemos la ejecucion del script
}


function registrar_usuario(){
    global $mysqli;
    
    // recogemos los datos
    $nombre = escape($_POST['nombre']);
    $correo = escape($_POST['correo']);
    $contrasena = escape($_POST['contrasena']);
    $recontrasena = escape($_POST['recontrasena']);
    
    
    // validamos el nombre de usuario
    if(!nombreValido($nombre)){
        return 'Nombre invalido';
    }
    
    // validamos la contraseña
    if(!validPassword($contrasena)){
        return 'password invalido, ingrese un password con al menos 3 caracteres';
    }
    
    // validamos la contraseña y la confirmacion de contraseña
    if($contrasena != $recontrasena){
        return 'las contraseñas no coinciden, por favor verifique';
    }
    
    
    // validamos el email
    if(!isEmail($correo)){
        return 'email no valido, por favor verifique';
    }
    
    // verificamos la existencia del email en nuestra base de datos
    if(userExists($correo)){
        return 'Ya existe un usuario asociado a ese email';
    }
    
    $mysqli->query( 'INSERT INTO usuarios (nombre, correo, contrasena) VALUES ("'.$nombre.'", "'.$correo.'", "'.$contrasena.'")');
    return 'registro exitoso, gracias p[or registrarse en nuestro sitio'; 
}

function nombreValido($name){
    $regex = 'a-zA-Z0-9\p{Arabic}\p{Cyrillic}\p{Latin}\p{Han}\p{Katakana}\p{Hiragana}\p{Hebrew}';
    if(preg_match('/^[' . $regex . ']{1,}([\-\_ ]{1})?([' . $regex . ']{1,})?$/ui', $name) && mb_strlen($name, 'UTF-8') <= 18 && !ctype_digit($name) && mb_strlen($name, 'UTF-8') >= 2){
        return true;
    }
    return false;
}

function validPassword($pass){
    if(strlen($pass) > 3){
        return true;
    }
}

function isEmail($email){
    if(filter_var($email, FILTER_VALIDATE_EMAIL) && !strstr($email, '+')){
        return true;
    }
}

function userExists($email){
    global $mysqli, $data;
    $check_email = $mysqli->query("SELECT user_id FROM `usuarios` WHERE LOWER(`correo`) = LOWER('$email')");
    if($check_email->num_rows > 0){
        return true;
    }
}

?>
 
Última edición: