PHP Design Patterns
Design patterns are typical solutions to common problems in software design. They are templates designed to help write reusable and maintainable code.
Singleton
The Singleton pattern ensures a class has only one instance and provides a global point of access to it.
class Singleton {
private static $instance;
private function __construct() {}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
}
$instance = Singleton::getInstance();
Factory
The Factory pattern provides a way to create objects without specifying the exact class of the object that will be created.
interface Shape {
public function draw();
}
class Circle implements Shape {
public function draw() {
echo "Drawing Circle";
}
}
class Square implements Shape {
public function draw() {
echo "Drawing Square";
}
}
class ShapeFactory {
public static function createShape($type) {
if ($type == 'circle') {
return new Circle();
} elseif ($type == 'square') {
return new Square();
}
return null;
}
}
$shape = ShapeFactory::createShape('circle');
$shape->draw(); // Output: Drawing Circle
Strategy
The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable.
interface PaymentStrategy {
public function pay($amount);
}
class CreditCardPayment implements PaymentStrategy {
public function pay($amount) {
echo "Paying $amount using Credit Card.";
}
}
class PayPalPayment implements PaymentStrategy {
public function pay($amount) {
echo "Paying $amount using PayPal.";
}
}
class ShoppingCart {
private $paymentStrategy;
public function __construct(PaymentStrategy $paymentStrategy) {
$this->paymentStrategy = $paymentStrategy;
}
public function checkout($amount) {
$this->paymentStrategy->pay($amount);
}
}
$cart = new ShoppingCart(new PayPalPayment());
$cart->checkout(100); // Output: Paying $100 using PayPal.
Observer
The Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified.
class Subject {
private $observers = [];
public function attach($observer) {
$this->observers[] = $observer;
}
public function notify() {
foreach ($this->observers as $observer) {
$observer->update();
}
}
}
class Observer {
public function update() {
echo "Observer notified!";
}
}
$subject = new Subject();
$observer1 = new Observer();
$observer2 = new Observer();
$subject->attach($observer1);
$subject->attach($observer2);
$subject->notify(); // Output: Observer notified! Observer notified!
Advanced Database Interaction
PDO (PHP Data Objects)
PDO provides a consistent way to interact with databases and supports various database management systems.
$dsn = 'mysql:host=localhost;dbname=testdb';
$username = 'root';
$password = '';
try {
$pdo = new PDO($dsn, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->query('SELECT * FROM users');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['name'];
}
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
Prepared Statements
Prepared statements help prevent SQL injection by separating SQL logic from data.
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => 'user@example.com']);
$user = $stmt->fetch();
Transactions
Transactions ensure that a series of operations either all succeed or all fail, maintaining data integrity.
try {
$pdo->beginTransaction();
$pdo->exec("INSERT INTO users (name, email) VALUES ('John', 'john@example.com')");
$pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE user_id = 1");
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
echo "Failed: " . $e->getMessage();
}
ORM (Object-Relational Mapping) with Doctrine
Doctrine is a powerful ORM for PHP, allowing developers to interact with the database using PHP objects.
/**
* @Entity @Table(name="users")
**/
class User {
/** @Id @Column(type="integer") @GeneratedValue **/
private $id;
/** @Column(type="string") **/
private $name;
// getters and setters...
}
Error Handling and Exception Management
Try, Catch, and Finally
Error handling in PHP can be managed using try-catch blocks.
try {
$pdo->query('INVALID SQL');
} catch (PDOException $e) {
echo 'Error: ' . $e->getMessage();
} finally {
echo 'This block always executes';
}
Custom Exception Handling
You can create custom exception classes to handle specific errors.
class CustomException extends Exception {}
try {
throw new CustomException("Custom error occurred");
} catch (CustomException $e) {
echo $e->getMessage();
}
Error Logging and Debugging Techniques
Logging errors to a file can help with debugging.
/** @var string $message */
ini_set('log_errors', 1);
ini_set('error_log', '/path/to/php-error.log');
error_log('A custom error message');
echo $message;
Comments #12