PHP Best Practices for Secure and Maintainable Code
Input Validation and Sanitization
One of the most critical aspects of secure PHP development is properly validating and sanitizing user input. Malicious input can lead to vulnerabilities such as SQL injection, cross-site scripting (XSS), and command injection. Always assume that all user input is untrusted.
Example: Validating and Sanitizing User Input
<?php
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
die("Invalid email address.");
}
$cleanInput = filter_var($_POST['username'], FILTER_SANITIZE_STRING);
?>
| Method | Purpose | Description |
|---|---|---|
filter_input() | Validate input | Checks if input matches a specific filter |
filter_var() | Sanitize or validate input | Applies a filter to a single variable |
htmlspecialchars() | Prevent XSS attacks | Converts special characters to HTML entities |
Error Handling and Logging
Proper error handling is essential for both debugging and security. In production environments, it's best to disable display errors and log them instead. This prevents attackers from gaining insight into your application's internal structure.
Example: Configuring Error Handling
<?php
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', '/path/to/your/error.log');
// Example of logging an error
error_log("Database connection failed: " . $e->getMessage());
?>
Security Measures
PHP provides several built-in functions and practices to enhance security. These include using prepared statements for database interactions, securing session management, and implementing HTTPS.
Example: Using Prepared Statements with PDO
<?php
$pdo = new PDO("mysql:host=localhost;dbname=test", "user", "password");
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
$user = $stmt->fetch();
?>
| Security Practice | Description |
|---|---|
| Prepared Statements | Prevent SQL injection by separating SQL logic from data |
| Session Security | Use session_start() and set session.cookie_secure for HTTPS |
| HTTPS | Encrypt data in transit between client and server |
Code Organization and Readability
Maintaining clean and organized code improves readability and makes it easier to maintain. Use consistent naming conventions, modularize code, and follow the PSR-12 coding standard.
Example: PSR-12 Naming Convention
<?php
class User {
private $username;
private $email;
public function __construct($username, $email) {
$this->username = $username;
$this->email = $email;
}
public function getUsername() {
return $this->username;
}
}
?>
| Convention | Description |
|---|---|
| Class Names | Use PascalCase |
| Method Names | Use camelCase |
| Variable Names | Use snake_case |
Dependency Management
Use Composer for managing PHP dependencies. It simplifies the process of including third-party libraries and ensures version control.
Example: Using Composer
composer require guzzlehttp/guzzle
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();
$response = $client->get('https://api.example.com/data');
echo $response->getBody();
?>