Introducción: ¿Por qué PHP es tan traicionero para los principiantes?
PHP sigue siendo uno de los lenguajes más populares para el desarrollo web, pero su baja barrera de entrada a menudo lleva a la formación de malos hábitos. Los desarrolladores novatos, inspirados por la simplicidad de la sintaxis, a menudo se olvidan de la seguridad, el rendimiento y los estándares modernos. En este artículo, analizaremos los principales errores de los desarrolladores PHP principiantes que pueden convertir tu código en una pesadilla de mantener y en una vulnerabilidad para ataques.
No solo enumeraremos los problemas: verás ejemplos de código en PHP con errores y sus versiones corregidas. Esto te ayudará a aplicar las prácticas correctas de inmediato.
1. Ignorar la seguridad: Inyecciones SQL y XSS
El error más crítico es confiar en los datos del usuario. Los principiantes a menudo insertan variables directamente en consultas SQL o las muestran en la página sin filtrar.
Error: Concatenación en consultas SQL
Un ejemplo clásico de vulnerabilidad:
// INCORRECTO: vulnerable a inyección SQL$id = $_GET['id'];$query = "SELECT * FROM users WHERE id = $id";$result = mysqli_query($link, $query);Un atacante puede pasar ?id=1 OR 1=1 y obtener todos los datos de la tabla.
Solución: Consultas preparadas (PDO)
Usa PDO o mysqli con expresiones preparadas:
// CORRECTO: PDO con consulta preparada$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");$stmt->execute(['id' => $_GET['id']]);$result = $stmt->fetchAll();Error: Mostrar datos sin escapar (XSS)
Si muestras datos de la base de datos o de $_GET directamente, corres el riesgo de sufrir un ataque XSS:
// INCORRECTO: vulnerable a XSSecho "Hola, " . $_GET['name'];Solución: htmlspecialchars
Siempre escapa la salida:
// CORRECTO: escapando HTMLecho "Hola, " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');2. Usar construcciones y funciones obsoletas
Muchos tutoriales de hace 10 años enseñan a usar funciones mysql_* o etiquetas cortas. Esto no solo es inseguro, sino que puede no funcionar en los hosting modernos.
Error: Funciones mysql_*
// INCORRECTO: extensión obsoleta$link = mysql_connect('localhost', 'user', 'pass');mysql_select_db('test', $link);Esta extensión fue eliminada en PHP 7, y el código simplemente fallará con un error.
Solución: Migrar a PDO o MySQLi
// CORRECTO: PDO - enfoque moderno y seguro$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');Error: Etiquetas cortas
// INCORRECTO: puede estar deshabilitado en php.ini<? echo "Hello"; ?>Solución: Solo etiquetas completas
// CORRECTO: usa siempre <?php<?php echo "Hello"; ?>3. Mal manejo de formularios y datos
Los desarrolladores principiantes a menudo olvidan verificar si se envió el formulario y usan $_REQUEST en lugar de arrays superglobales específicos.
Error: Falta de verificación del método de envío
// INCORRECTO: el código se ejecuta incluso con una solicitud GET$name = $_POST['name'];// ... procesamientoSolución: Verificar REQUEST_METHOD
// CORRECTO: verificamos que el formulario fue enviadoif ($_SERVER['REQUEST_METHOD'] === 'POST') { $name = $_POST['name'] ?? ''; // ... validación y procesamiento}Error: Usar $_REQUEST
El array superglobal $_REQUEST combina GET, PO