← PHP EspañolChapter 13 of 13

Mejores Prácticas

## Objetivos de Aprendizaje - Escribir código PHP seguro - Seguir estándares de codificación - Usar Composer para gestión de dependencias - Implementar manejo de errores - Optimizar rendimiento ## Conceptos Básicos de Seguridad ### Validación de Entrada ```php ['min_range' => 0, 'max_range' => 150] ]); ?> ``` ### Prevención de Inyección SQL ```php prepare("SELECT * FROM users WHERE id = :id"); $stmt->execute(['id' => $id]); // $id is safe // NEVER do this! $sql = "SELECT * FROM users WHERE id = " . $_GET['id']; // DANGEROUS! ?> ``` ### Prevención de XSS ```php

'); ?> ``` ### Hashing de Contraseñas ```php ``` ### Seguridad de Subida de Archivos ```php $maxSize) { echo "File too large"; } // Never trust the file extension $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); ?> ``` ### Seguridad de Sesión ```php 0, 'path' => '/', 'domain' => '', 'secure' => true, 'httponly' => true, 'samesite' => 'Strict' ]); // Check for session hijacking if (isset($_SESSION['ip']) && $_SESSION['ip'] !== $_SERVER['REMOTE_ADDR']) { session_destroy(); } ?> ``` ## Configuración de PHP ### Recomendaciones de php.ini ```ini ; Display errors - disable in production display_errors = Off log_errors = On error_log = /var/log/php_errors.log ; Security expose_php = Off allow_url_fopen = Off allow_url_include = Off ; Session session.cookie_httponly = 1 session.cookie_secure = 1 session.use_strict_mode = 1 ; File uploads file_uploads = On upload_max_filesize = 5M max_file_uploads = 10 ``` ### Reporte de Errores ```php ``` ### Manejador de Errores Personalizado ```php ``` ## Estándares de Codificación ### Reglas Básicas de PSR-12 ```php ``` ### Indentación y Espaciado ```php isValid()) { $item->process(); } } } // Space around operators $sum = $a + $b; $name = "Hello, " . $world; // No space between function name and parentheses $length = strlen($text); array_push($items, $newItem); ?> ``` ### Convenciones de Nomenclatura ```php ``` ## Composer ### composer.json ```json { "name": "myapp/application", "description": "My PHP Application", "type": "project", "license": "MIT", "require": { "php": ">=8.1", "ext-pdo": "*", "ext-json": "*", "monolog/monolog": "^3.0", "guzzlehttp/guzzle": "^7.0" }, "require-dev": { "phpunit/phpunit": "^10.0", "fakerphp/faker": "^1.9.1" }, "autoload": { "psr-4": { "App\\": "src/" } }, "autoload-dev": { "psr-4": { "Tests\\": "tests/" } }, "scripts": { "test": "phpunit", "post-autoload-dump": [ "@php artisan package:discover --ansi" ] }, "config": { "optimize-autoloader": true, "preferred-install": "dist", "sort-packages": true } } ``` ### Comandos de Composer ```bash # Install dependencies composer install # Update dependencies composer update # Add new package composer require monolog/monolog # Add dev dependency composer require --dev phpunit/phpunit # Remove package composer remove monolog/monolog # Update single package composer update monolog/monolog # Generate autoload files composer dump-autoload # List installed packages composer show # Check for security advisories composer audit ``` ### Autoloading ```php ``` ### PSR-4 Autoloading ```php ``` ## Manejo de Errores ### Bloques try-catch ```php prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$id]); $user = $stmt->fetch(); if (!$user) { throw new Exception("User not found"); } } catch (PDOException $e) { // Log database errors error_log("Database error: " . $e->getMessage()); echo "A database error occurred"; } catch (Exception $e) { // Handle other errors error_log("Error: " . $e->getMessage()); echo "An error occurred: " . $e->getMessage(); } ?> ``` ### Excepciones Personalizadas ```php userId = $userId; parent::__construct($message, $code, $previous); } public function getUserId(): int { return $this->userId; } } // Usage throw new UserNotFoundException(42, "User with ID 42 not found"); ?> ``` ### Jerarquía de Excepciones ```php ``` ## Consejos de Rendimiento ### Output Buffering ```php Hello"; // Get content without sending $content = ob_get_contents(); // Clean buffer ob_end_clean(); // Or flush buffer ob_end_flush(); ?> ``` ### Memoria y Bucles ```php ``` ### Caching ```php time() - 3600) { $data = json_decode(file_get_contents($cacheFile), true); } else { $data = fetchFromDatabase(); file_put_contents($cacheFile, json_encode($data)); } // For production: use Redis, Memcached, or OPcache ?> ``` ### opcache ```ini ; php.ini opcache.enable=1 opcache.memory_consumption=128 opcache.max_accelerated_files=10000 opcache.revalidate_freq=2 ``` ## Conceptos Básicos de Testing ### Ejemplo de PHPUnit ```php assertEquals("Alice", $user->getName()); $this->assertEquals("alice@example.com", $user->getEmail()); } public function testPasswordHashing(): void { $password = "secret123"; $hashed = password_hash($password, PASSWORD_DEFAULT); $this->assertTrue(password_verify($password, $hashed)); $this->assertFalse(password_verify("wrong", $hashed)); } } ?> ``` ## Documentación ### DocBlocks ```php ``` ## Resumen - Siempre validar y sanear entrada del usuario - Usar declaraciones preparadas para prevenir inyección SQL - Usar `htmlspecialchars()` para prevenir XSS - Hacer hash de contraseñas con `password_hash()` - Regenerar ID de sesión después del login - Establecer `declare(strict_types=1)` al inicio de los archivos - Seguir estándares de codificación PSR-12 - Usar Composer para gestión de dependencias - Manejar excepciones con bloques try-catch - Registrar errores, no mostrarlos en producción - Usar output buffering para salida compleja - Cachear operaciones costosas - Escribir tests con PHPUnit

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →