PHP¶
Table of Contents¶
- 1. Getting Started
- 1. Installing PHP (CLI, Web, Docker)
- 2. Your First Script
- 3. PHP CLI Basics
- 4. Types, Strict Types, and Casting
- 2. Language Fundamentals
- 5. Variables, Constants, and Operators
- 6. Control Flow (if, switch, loops)
- 7. Arrays (indexed, associative, deep tricks)
- 8. Functions, Type Hints, and Attributes
- 9. Error Handling and Exceptions
- 3. OOP and Modern PHP
- 10. Classes, Interfaces, Traits
- 11. Inheritance, Visibility, and Final
- 12. Magic Methods and Immutability
- 13. Namespaces and Autoloading
- 4. The PHP Ecosystem
- 14. Composer and composer.json
- 15. PSR Standards (PSR-1/4/12, PSR-3/6/7/11/14)
- 16. Popular Libraries and Utilities
- 5. Web Development Essentials
- 17. Superglobals and Request Handling
- 18. Sessions and Cookies (Secure Flags)
- 19. Templating, Escaping, and Output
- 20. Routing Concepts (Vanilla and Libraries)
- 6. Database Access (PDO)
- 21. Connecting with PDO and DSNs
- 22. Prepared Statements and Transactions
- 23. Migrations, Query Builders, and ORMs
- 7. Security First (Do This, Avoid That)
- 24. Configuration Hardening (php.ini)
- 25. XSS Prevention and Contextual Escaping
- 26. SQL Injection: Prepared or Perish
- 27. CSRF, SameSite, and Anti-CSRF Tokens
- 28. File Uploads and Path Traversal
- 29. Command Injection and Dangerous Functions
- 30. Passwords: password_hash and Argon2
- 31. Cryptography: sodium and OpenSSL
- 32. HTTP Security Headers (CSP, HSTS, etc.)
- 33. Deserialization and unserialize Risks
- 8. APIs and HTTP Clients
- 34. Building RESTful Endpoints
- 35. JSON Handling and Validation
- 36. HTTP Clients (Guzzle, Symfony HttpClient)
- 9. Testing, Quality, and Tooling
- 37. PHPUnit and Pest
- 38. Static Analysis (Psalm, PHPStan)
- 39. Coding Standards (PHP-CS-Fixer, PHPCS)
- 40. Security Scanners and Linters
- 10. Performance and Caching
- 41. OPcache, JIT, and Benchmarks
- 42. Caching (APCu, Redis, HTTP)
- 43. Queues and Workers
- 11. DevOps and Deployment
- 44. Docker and PHP Images
- 45. Nginx/Apache Configs and PHP-FPM
- 46. Environment Variables and Secrets
- 12. Framework Glimpse
- 47. Laravel: A Taste of Artisanal PHP
- 48. Symfony: Components and Full-Stack
- 49. Slim and Microframeworks
- 13. Troubleshooting and FAQ
- 50. Common Pitfalls
- 51. Debugging and Logging
- 52. Glossary
- Appendix
- A. php.ini Reference Snippets
- B. Composer Templates
- C. Security Checklists
- D. Humor and Easter Eggs
- E. Further Reading
Part 1: Getting Started¶
1. Installing PHP (CLI, Web,-Docker)¶
- Linux (Debian/Ubuntu): sudo apt get update && sudo apt get install -y php php cli php fpm php mbstring php xml php curl php zip
- macOS: brew install php
- Windows: Use official binaries or WSL2 with Ubuntu + apt
- Docker (recommended for consistency): docker run --rm -it -v $PWD:/app -w /app php:8.2-cli php -v
2. Your First Script¶
index.php
<?php declare(strict_types=1);
echo "Hello, PHP ".PHP_VERSION."\n";
3. PHP CLI Basics¶
- php -v: version
- php -m: modules
- php -S 127.0.0.1:8000 -t public: dev server
4. Types, Strict Types, and Casting¶
- Add declare(strict_types=1) at top to enable strict parameter/return checks.
- Scalar types: int, float, string, bool
- Mixed and union types (PHP 8): function f(int|string $v): string { ... }
- Nullability: ?string
Part 2: Language Fundamentals¶
5. Variables, Constants, and Operators¶
$u = "alice"; $n = 42; $pi = 3.14; $ok = true;
const APP = 'myapp';
echo APP.' user='.$u.' n='.(string)$n.' pi='.$pi."\n";
6. Control Flow (if, switch,-loops)¶
$status = 'admin';
if ($status === 'admin') {
echo "Welcome!";
} elseif ($status === 'user') {
echo "Hi user";
} else {
echo "Guest";
}
for ($i=0; $i<3; $i++) echo $i;
$j=0; while ($j<3) { echo $j++; }
7. Arrays (indexed, associative, deep-tricks)¶
$ports = [22,80,443];
$headers = ['Accept' => 'application/json', 'User-Agent' => 'phpscout/1.0'];
$ports[] = 8080; echo $ports[1]; // 80
foreach ($headers as $k=>$v) echo "$k: $v\n";
// Array helpers
$nums = [1,2,3,4];
$evens = array_filter($nums, fn($x)=>$x%2===0);
$double = array_map(fn($x)=>$x*2, $nums);
$sum = array_sum($nums);
8. Functions, Type Hints, and Attributes¶
declare(strict_types=1);
function greet(string $name): string { return "Hello, $name"; }
function add(int $a, int $b): int { return $a + $b; }
Attributes (PHP 8):
#[Deprecated]
function old_way(): void {}
9. Error Handling and Exceptions¶
try {
throw new RuntimeException('Oops');
} catch (RuntimeException $e) {
error_log($e->getMessage());
}
Part 3: OOP and Modern PHP¶
10. Classes, Interfaces, Traits¶
interface Greeter { public function greet(): string; }
trait Logger { public function log(string $m): void { error_log($m); } }
final class User implements Greeter {
use Logger;
public function __construct(private string $name) {}
public function greet(): string { return "Hi, I am {$this->name}"; }
}
11. Inheritance, Visibility, and Final¶
- public/protected/private control visibility
- final prevents extension; good for maintaining invariants
12. Magic Methods and Immutability¶
- __construct, __toString, __get/__set, __invoke
- Consider immutable value objects for safety: no setters, construct all at once
13. Namespaces and Autoloading¶
namespace App; class Thing {}
// composer.json autoload: {"psr-4": {"App\\": "src/"}}
Part 4: The PHP Ecosystem¶
14. Composer and composer.json¶
composer.json minimal:
{
"name": "acme/app",
"type": "project",
"require": {
"php": ">=8.1"
},
"autoload": {
"psr-4": {"App\\": "src/"}
}
}
15. PSR Standards (PSR-1/4/12,-PSR-3/6/7/11/14)¶
- PSR-1/12: coding style guidelines
- PSR-4: autoloading
- PSR-3: logging interfaces
- PSR-6/16: caching
- PSR-7/17: HTTP messages & factories
- PSR-11: container interface
- PSR-14: event dispatcher
16. Popular Libraries and Utilities¶
- HTTP client: guzzlehttp/guzzle, symfony/http client
- Dotenv: vlucas/phpdotenv
- Logging: monolog/monolog
- Validation: respect/validation, symfony/validator
- Template: twig/twig, platesphp/plates
Part 5: Web Development Essentials¶
17. Superglobals and Request Handling¶
- $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION, $_SERVER
- Avoid $_REQUEST; be explicit
$name = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_STRING) ?? '';
18. Sessions and Cookies (Secure-Flags)¶
session_set_cookie_params([
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
session_start();
$_SESSION['uid'] = 123;
setcookie('theme', 'dark', [
'expires' => time()+86400,
'path' => '/', 'secure' => true, 'httponly' => true, 'samesite' => 'Lax'
]);
19. Templating, Escaping, and Output¶
- Use htmlspecialchars($v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') for HTML
- For attributes/URLs/JS/CSS contexts, use appropriate escaping (or a template engine handling contexts)
20. Routing Concepts (Vanilla and-Libraries)¶
Simple router (vanilla):
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
if ($path === '/health') echo json_encode(['ok'=>true]);
Part 6: Database Access-(PDO)¶
21. Connecting with PDO and DSNs¶
$pdo = new PDO('mysql:host=localhost;dbname=app;charset=utf8mb4', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
22. Prepared Statements and Transactions¶
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute([':email' => $email]);
$user = $stmt->fetch();
$pdo->beginTransaction();
$pdo->prepare('UPDATE accounts SET balance=balance-? WHERE id=?')->execute([$amt,$from]);
$pdo->prepare('UPDATE accounts SET balance=balance+? WHERE id=?')->execute([$amt,$to]);
$pdo->commit();
23. Migrations, Query Builders, and ORMs¶
- Migrations: doctrine/migrations, laravel/framework (artisan)
- Query builders/ORMs: doctrine/dbal, doctrine/orm, illuminate/database
Part 7: Security First (Do This, Avoid-That)¶
24. Configuration Hardening-(php.ini)¶
display_errors = Off
log_errors = On
expose_php = Off
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax
25. XSS Prevention and Contextual Escaping¶
$title = $_GET['title'] ?? '';
echo htmlspecialchars($title, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
26. SQL Injection: Prepared or Perish¶
- Always use prepared statements (placeholders); never concatenate user input into SQL
27. CSRF, SameSite, and Anti-CSRF Tokens¶
// Generate
authenticate_user();
if (empty($_SESSION['csrf'])) $_SESSION['csrf'] = bin2hex(random_bytes(32));
// Validate
if (!hash_equals($_SESSION['csrf'], $_POST['csrf'] ?? '')) die('Bad CSRF');
28. File Uploads and Path Traversal¶
$okTypes = ['image/png','image/jpeg'];
if (isset($_FILES['f']) && in_array(mime_content_type($_FILES['f']['tmp_name']), $okTypes, true)) {
$name = bin2hex(random_bytes(8)).'.png';
move_uploaded_file($_FILES['f']['tmp_name'], __DIR__.'/uploads/'.$name);
}
29. Command Injection and Dangerous Functions¶
- Avoid shell_exec/system/passthru; if necessary, escape with escapeshellarg and use allowlists
30. Passwords: password_hash and Argon2¶
$hash = password_hash($password, PASSWORD_ARGON2ID);
if (password_verify($input, $hash)) { /* ok */ }
31. Cryptography: sodium and OpenSSL¶
// libsodium secretbox (authenticated encryption)
$k = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$cipher = sodium_crypto_secretbox($plaintext, $nonce, $k);
$plain = sodium_crypto_secretbox_open($cipher, $nonce, $k);
32. HTTP Security Headers (CSP, HSTS,-etc.)¶
header('Content-Security-Policy: default src \'self\'');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: SAMEORIGIN');
header('Referrer-Policy: no referrer when downgrade');
header('Strict-Transport-Security: max age=31536000; includeSubDomains');
33. Deserialization and unserialize Risks¶
- Avoid unserialize on untrusted data; prefer JSON
- If using unserialize, use allowed classes option and consider read only DTOs
Dev aside: If your input says “trust me bro,” it’s lying. Always validate.
Part 8: APIs and HTTP Clients¶
34. Building RESTful Endpoints¶
header('Content-Type: application/json');
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'GET') echo json_encode(['status' => 'ok']);
35. JSON Handling and Validation¶
$raw = file_get_contents('php://input');
$data = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
if (!isset($data['id']) || !is_int($data['id'])) { http_response_code(400); }
36. HTTP Clients (Guzzle, Symfony-HttpClient)¶
$client = new \GuzzleHttp\Client();
$res = $client->get('https://httpbin.org/get');
$body = json_decode((string)$res->getBody(), true);
Part 9: Testing, Quality, and Tooling¶
37. PHPUnit and Pest¶
- composer require --dev phpunit/phpunit
- tests/ExampleTest.php
use PHPUnit\Framework\TestCase; class ExampleTest extends TestCase { public function testAdd() { $this->assertSame(4, 2+2); } }
38. Static Analysis (Psalm,-PHPStan)¶
- composer require --dev vimeo/psalm phpstan/phpstan
- Keep baselines updated; treat warnings as errors in CI
39. Coding Standards (PHP-CS-Fixer,-PHPCS)¶
- composer require --dev friendsofphp/php cs fixer squizlabs/php_codesniffer
- Enforce PSR-12
40. Security Scanners and Linters¶
- enlightn/security checker (or symfony CLI security:check)
- local php security checker
Part 10: Performance and Caching¶
41. OPcache, JIT, and Benchmarks¶
- Enable OPcache in production; JIT can help CPU-bound code
42. Caching (APCu, Redis,-HTTP)¶
apcu_store('k', 'v', 60); $v = apcu_fetch('k');
43. Queues and Workers¶
- Use queues for long tasks: laravel/horizon, symfony/messenger, php enqueue
Part 11: DevOps and Deployment¶
44. Docker and PHP Images¶
- php:8.2-fpm alpine for light containers
- Add extensions via docker php ext install; use multi stage builds
45. Nginx/Apache Configs and PHP-FPM¶
- Nginx upstream to php fpm; limit upload size; secure locations
46. Environment Variables and Secrets¶
- Use getenv() or Dotenv; never commit secrets
- Prefer external secret managers (Vault, AWS Secrets Manager)
Part 12: Framework Glimpse¶
47. Laravel: A Taste of Artisanal PHP¶
- Artisan CLI, Eloquent ORM, Blade templates, queues, events, policies
48. Symfony: Components and Full-Stack¶
- HttpKernel, Console, DependencyInjection, EventDispatcher, Messenger
49. Slim and Microframeworks¶
- Slim, Lumen, Mezzio for small services
Dev joke: My framework benchmarked at 1M RPS… after I removed all logic, I/O, and functionality.
Part 13: Troubleshooting and FAQ¶
50. Common Pitfalls¶
- Relying on loose comparisons (==)
- Not enabling strict types
- Echoing unescaped user input
- Building SQL with string concatenation
51. Debugging and Logging¶
- var_dump, xdebug, ray, monolog
- Never dump secrets to logs; set appropriate log rotation and permissions
52. Glossary¶
- PSR: PHP-FIG recommendations
- OPcache: bytecode cache for performance
- FPM: FastCGI Process Manager for PHP
Appendix¶
A. php.ini Reference Snippets¶
memory_limit = 256M
post_max_size = 8M
upload_max_filesize = 8M
max_execution_time = 30
error_reporting = E_ALL
log_errors = On
display_errors = Off
B. Composer Templates¶
{
"require": {
"monolog/monolog": "^3.0",
"guzzlehttp/guzzle": "^7.8"
},
"require dev": {
"phpunit/phpunit": "^11.0",
"vimeo/psalm": "^5.0",
"phpstan/phpstan": "^1.10",
"friendsofphp/php cs fixer": "^3.0"
}
}
C. Security Checklists¶
- Input validation and output escaping in all contexts
- Prepared statements for all DB access
- CSRF tokens for state changing requests
- Strict session cookie flags + SameSite
- Security headers (CSP, HSTS, X-Frame-Options, etc.)
- Avoid unserialize on untrusted data
- Regular dependency audits
D. Humor and Easter Eggs¶
- Linux joke: chmod -x life; still executable.
- Networking: I’d tell you a UDP joke, but you might not get it.
- Dev: My code has no bugs—it just develops new features spontaneously.
E. Further Reading¶
- PHP Manual: https://www.php.net/manual/en/
- PHP-FIG: https://www.php fig.org/psr/
- OWASP Cheat Sheet Series: https://cheatsheetseries.owasp.org/
- Composer: https://getcomposer.org/
- Symfony Docs: https://symfony.com/doc/current/index.html
- Laravel Docs: https://laravel.com/docs
Part 14: Advanced PHP Features¶
53. Generators and Yield¶
Generators allow you to create iterators without building arrays in memory.
function fibonacci($n) {
$a = 0; $b = 1;
for ($i = 0; $i < $n; $i++) {
yield $a;
[$a, $b] = [$b, $a + $b];
}
}
foreach (fibonacci(10) as $num) {
echo $num . ' ';
}
// Output: 0 1 1 2 3 5 8 13 21 34
- Use
yield fromto delegate to another generator. - Generators are memory efficient for large datasets.
54. Closures and Anonymous Functions¶
Closures capture variables from the enclosing scope.
$multiplier = 2;
$double = function($x) use ($multiplier) {
return $x * $multiplier;
};
echo $double(5); // 10
- Arrow functions (PHP 7.4+):
fn($x) => $x * 2; - Useful for callbacks, event handlers.
55. Traits in Depth¶
Traits can have properties, methods, and even abstract methods.
trait Loggable {
protected $log = [];
public function log($message) {
$this->log[] = $message;
}
abstract public function getLog();
}
class User {
use Loggable;
public function getLog() {
return $this->log;
}
}
- Multiple traits:
use Trait1, Trait2; - Conflict resolution:
use Trait1, Trait2 { Trait1::method insteadof Trait2; }
56. Reflection API¶
Inspect classes, methods, properties at runtime.
$ref = new ReflectionClass('User');
$methods = $ref->getMethods();
foreach ($methods as $method) {
echo $method->getName() . "\n";
}
- Useful for frameworks, testing, and dynamic code.
57. SPL (Standard PHP-Library)¶
Provides data structures like SplStack, SplQueue.
$stack = new SplStack();
$stack->push(1);
$stack->push(2);
echo $stack->pop(); // 2
- Iterators, observers, and more for advanced programming.
Part 15: PHP 8 Specific Features¶
58. Union Types and Intersection Types¶
function process(int|string $value): int|float {
return is_int($value) ? $value : (float)$value;
}
- Intersection types (PHP 8.1+):
Type1&Type2
59. Attributes-(Annotations)¶
#[Route('/api/user', methods:-['GET'])]
class UserController {
#[Inject]
public function __construct(private Logger $logger) {}
}
- Replace docblock annotations for cleaner code.
60. Match Expression¶
$result = match ($status) {
'success' => 'OK',
'error' => 'Fail',
default => 'Unknown',
};
- Exhaustive matching, no fallthrough.
61. Constructor Property Promotion¶
class Point {
public function __construct(
public float $x,
public float $y,
) {}
}
- Reduces boilerplate in classes.
62. Named Arguments¶
htmlspecialchars($string, double_encode: false);
- Improves readability, especially with many parameters.
63. Enums (PHP-8.1+)¶
enum Status {
case Pending;
case Approved;
case Rejected;
}
function checkStatus(Status $status) {
return match ($status) {
Status::Approved => 'Go ahead',
default => 'Wait',
};
}
- Type safe constants.
Part 16: Performance Optimization¶
64. Profiling with Xdebug¶
- Install Xdebug, enable profiling.
- Analyze cachegrind files with tools like KCacheGrind.
65. Memory Management¶
- Use unset() to free variables.
- Avoid large arrays; use generators.
- Monitor with memory_get_peak_usage().
66. Database Optimization¶
- Index columns properly.
- Use EXPLAIN to analyze queries.
- Connection pooling with persistent connections.
67. Code Optimization Tips¶
- Use === over ==.
- Cache expensive operations.
- Minimize includes; use autoloading.
Part 17: Deployment and Scaling¶
68. Load Balancing¶
- Use Nginx upstream for multiple PHP-FPM instances.
- Session affinity or shared storage for sessions.
69. Horizontal Scaling¶
- Stateless apps for easy scaling.
- Use Redis for shared cache/sessions.
70. Monitoring and Logging¶
- Tools: New Relic, Blackfire, Monolog.
- Log levels: DEBUG, INFO, WARNING, ERROR.
71. CI/CD Pipelines¶
- GitHub Actions, GitLab CI for automated testing and deployment.
- Docker for consistent environments.
Part 18: Common PHP Patterns and Best Practices¶
72. Singleton Pattern¶
class Database {
private static $instance;
private function __construct() {}
public static function getInstance() {
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
}
- Use sparingly; can make testing hard.
73. Factory Pattern¶
interface LoggerFactory {
public function createLogger(): Logger;
}
class FileLoggerFactory implements LoggerFactory {
public function createLogger(): Logger {
return new FileLogger();
}
}
- For object creation logic.
74. Dependency Injection¶
class UserService {
public function __construct(private Database $db, private Logger $logger) {}
}
- Use containers like Symfony DI or PHP-DI.
75. Repository Pattern¶
interface UserRepository {
public function findById(int $id): ?User;
public function save(User $user): void;
}
class PDOUserRepository implements UserRepository {
// Implementation
}
- Abstracts data access.
Part 19: PHP Ecosystem Deep Dive¶
76. Popular Frameworks Comparison¶
- Laravel: Full stack, artisan, eloquent.
- Symfony: Modular, components.
- CodeIgniter: Lightweight, simple.
- Yii: High performance, caching.
77. Microframeworks¶
- Slim: PSR-7, routing.
- Lumen: Laravel micro.
- Silex (deprecated, use Symfony).
78. CMS and E-commerce¶
- WordPress: Plugins, themes.
- Drupal: Flexible, modules.
- Magento: E-commerce focused.
79. Headless CMS¶
- Strapi, Directus for API-first.
Part 20: Troubleshooting and Advanced FAQ¶
80. Memory Leaks¶
- Check for circular references.
- Use weak references (PHP 7.4+).
81. Opcode Cache Issues¶
- Clear OPcache:
opcache_reset() - Check opcache_get_status()
82. Extension Conflicts¶
- Use php -m to list loaded extensions.
- Check phpinfo() for versions.
83. Debugging Tips¶
- Use var_dump with
in HTML.
- Xdebug breakpoints.
- Logging with context.
84. Performance Bottlenecks¶
- Profile with Tideways or Blackfire.
- Optimize loops, reduce DB calls.
Part 21: Code Examples and Snippets¶
85. File Upload Handler¶
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
$file = $_FILES['file'];
if ($file['error'] === UPLOAD_ERR_OK) {
$tmpName = $file['tmp_name'];
$name = basename($file['name']);
$uploadDir = '/uploads/';
$path = $uploadDir . $name;
if (move_uploaded_file($tmpName, $path)) {
echo 'Uploaded successfully';
}
}
}
86. Simple REST API¶
header('Content-Type: application/json');
$method = $_SERVER['REQUEST_METHOD'];
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
if ($method === 'GET' && $path === '/api/users') {
echo json_encode(['users' => [['id' => 1, 'name' => 'Alice']]]);
} elseif ($method === 'POST' && $path === '/api/users') {
$input = json_decode(file_get_contents('php://input'), true);
// Save to DB
echo json_encode(['id' => 2, 'name' => $input['name']]);
} else {
http_response_code(404);
}
87. Pagination Helper¶
function paginate(array $items, int $page, int $perPage): array {
$offset = ($page 1) * $perPage;
return array_slice($items, $offset, $perPage);
}
$users = range(1, 100); // Dummy data
$page1 = paginate($users, 1, 10);
88. Caching Decorator¶
class CacheDecorator {
private $cache;
private $service;
public function __construct(CacheInterface $cache, $service) {
$this->cache = $cache;
$this->service = $service;
}
public function expensiveMethod($param) {
$key = 'method_' . md5($param);
if ($this->cache->has($key)) {
return $this->cache->get($key);
}
$result = $this->service->expensiveMethod($param);
$this->cache->set($key, $result, 3600);
return $result;
}
}
89. Event Dispatcher¶
class EventDispatcher {
private $listeners = [];
public function addListener(string $event, callable $listener) {
$this->listeners[$event][] = $listener;
}
public function dispatch(string $event, $data = null) {
if (isset($this->listeners[$event])) {
foreach ($this->listeners[$event] as $listener) {
$listener($data);
}
}
}
}
// Usage
$dispatcher = new EventDispatcher();
$dispatcher->addListener('user.created', function($user) {
// Send email
});
$dispatcher->dispatch('user.created', $user);
90. Custom Exception Classes¶
class ValidationException extends Exception {
public function __construct($message, $field) {
parent::__construct($message);
$this->field = $field;
}
public function getField() {
return $this->field;
}
}
try {
throw new ValidationException('Invalid email', 'email');
} catch (ValidationException $e) {
echo 'Field: ' . $e->getField();
}
91. Configuration Manager¶
class Config {
private static $config = [];
public static function load($file) {
self::$config = require $file;
}
public static function get($key, $default = null) {
return self::$config[$key] ?? $default;
}
}
// config.php
return [
'db' => ['host' => 'localhost', 'user' => 'root'],
];
// Usage
Config::load('config.php');
$host = Config::get('db.host');
92. Template Engine-(Simple)¶
class Template {
private $vars = [];
public function set($key, $value) {
$this->vars[$key] = $value;
}
public function render($template) {
extract($this->vars);
ob_start();
include $template;
return ob_get_clean();
}
}
// template.php
<h1><?php echo $title; ?></h1>
<p><?php echo $content; ?></p>
// Usage
$tpl = new Template();
$tpl->set('title', 'Hello');
$tpl->set('content', 'World');
echo $tpl->render('template.php');
93. Rate Limiter¶
class RateLimiter {
private $cache;
private $maxRequests;
private $window;
public function __construct(CacheInterface $cache, $maxRequests = 100, $window = 60) {
$this->cache = $cache;
$this->maxRequests = $maxRequests;
$this->window = $window;
}
public function isAllowed($key) {
$current = time();
$windowStart = $current $this->window;
$requests = $this->cache->get($key, []);
$requests = array_filter($requests, fn($t) => $t > $windowStart);
if (count($requests) >= $this->maxRequests) {
return false;
}
$requests[] = $current;
$this->cache->set($key, $requests, $this->window);
return true;
}
}
94. Password Reset Flow¶
// Generate token
$token = bin2hex(random_bytes(32));
$_SESSION['reset_token'] = $token;
$_SESSION['reset_email'] = $email;
// Send email with link: /reset?token=$token
// In reset handler
if (isset($_GET['token']) && $_GET['token'] === $_SESSION['reset_token']) {
$newPassword = password_hash($_POST['password'], PASSWORD_ARGON2ID);
// Update DB
unset($_SESSION['reset_token']);
}
95. Image Resizer¶
function resizeImage($source, $dest, $width, $height) {
$info = getimagesize($source);
$mime = $info['mime'];
switch ($mime) {
case 'image/jpeg': $image = imagecreatefromjpeg($source); break;
case 'image/png': $image = imagecreatefrompng($source); break;
default: return false;
}
$resized = imagescale($image, $width, $height);
imagejpeg($resized, $dest);
imagedestroy($image);
imagedestroy($resized);
return true;
}
96. CSV Parser¶
function parseCsv($file) {
$data = [];
if (($handle = fopen($file, 'r')) !== false) {
while (($row = fgetcsv($handle, 1000, ',')) !== false) {
$data[] = $row;
}
fclose($handle);
}
return $data;
}
97. JSON Web Token-(JWT) Simple¶
// Note: Use a library like firebase/php jwt in production
function base64UrlEncode($data) {
return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($data));
}
function createJwt($payload, $secret) {
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);
$payload = json_encode($payload);
$headerEncoded = base64UrlEncode($header);
$payloadEncoded = base64UrlEncode($payload);
$signature = hash_hmac('sha256', $headerEncoded . '.' . $payloadEncoded, $secret, true);
$signatureEncoded = base64UrlEncode($signature);
return $headerEncoded . '.' . $payloadEncoded . '.' . $signatureEncoded;
}
98. WebSocket Server (Basic with-ReactPHP)¶
// Requires react/socket
$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server('127.0.0.1:8080', $loop);
$socket->on('connection', function (React\Socket\ConnectionInterface $connection) {
$connection->on('data', function ($data) use ($connection) {
$connection->write('Echo: ' . $data);
});
});
$loop->run();
99. Cron Job Scheduler¶
class Cron {
private $jobs = [];
public function addJob($expression, callable $callback) {
$this->jobs[] = ['expr' => $expression, 'callback' => $callback];
}
public function run() {
foreach ($this->jobs as $job) {
if ($this->matchesCron($job['expr'])) {
$job['callback']();
}
}
}
private function matchesCron($expr) {
// Simplified: check if current minute matches
$parts = explode(' ', $expr);
$minute = (int)$parts[0];
return date('i') == $minute;
}
}
// Usage: Run every minute at :00
$cron = new Cron();
$cron->addJob('0 * * * *', function() { echo 'Hourly task'; });
$cron->run();
100. Multi threading with pthreads-(Extension)¶
class Worker extends Thread {
public function run() {
echo 'Working in thread ' . $this->getThreadId() . "\n";
}
}
$workers = [];
for ($i = 0; $i < 5; $i++) {
$workers[] = new Worker();
$workers[$i]->start();
}
foreach ($workers as $worker) {
$worker->join();
}
Part 22: Extended Security Practices¶
101. Input Sanitization Deep Dive¶
- Use filter_var() for emails, URLs.
- Custom sanitizers for complex data.
102. Output Encoding Contexts¶
- HTML: htmlspecialchars
- JS: json_encode
- CSS: urlencode
- URLs: urlencode
103. Secure Session Management¶
- Regenerate session ID on login.
- Use session fixation protection.
104. API Security¶
- Rate limiting, API keys, OAuth.
- Validate all inputs, use JWT securely.
105. Third-Party Library Security¶
- Audit dependencies with composer audit.
- Keep libraries updated.
Part 23: PHP in the Cloud¶
106. AWS SDK for PHP¶
require 'vendor/autoload.php';
use Aws\S3\S3Client;
$s3 = new S3Client([
'version' => 'latest',
'region' => 'us east-1',
'credentials' => [
'key' => getenv('AWS_ACCESS_KEY'),
'secret' => getenv('AWS_SECRET_KEY'),
],
]);
$s3->putObject([
'Bucket' => 'my bucket',
'Key' => 'file.txt',
'Body' => 'Hello World',
]);
107. Google Cloud Platform¶
- Use google/cloud storage for GCS.
- App Engine for PHP apps.
108. Docker for PHP Apps¶
FROM php:8.2-fpm
COPY . /var/www/html
RUN docker php ext install pdo_mysql
EXPOSE 9000
109. Serverless PHP¶
- Use Bref for AWS Lambda.
- Deploy functions with serverless framework.
Part 24: Community and Resources¶
110. PHP Conferences¶
- php[tek], Laracon, SymfonyCon.
111. Online Communities¶
- Stack Overflow, Reddit r/PHP, PHP subreddit.
112. Books¶
- "Modern PHP" by Josh Lockhart.
- "PHP Objects, Patterns, and Practice" by Matt Zandstra.
113. Podcasts¶
- PHP Roundtable, Voices of the ElePHPant.
114. Blogs¶
- PHP.net, Laravel News, Symfony Blog.
Part 25: Future of PHP¶
115. PHP 8.1 Features¶
- Enums, readonly properties, fibers for async.
116. PHP 8.2¶
- Readonly classes, sensitive parameter redaction.
117. Upcoming Trends¶
- JIT improvements, more type safety.
118. Migration Guides¶
- From PHP 7 to 8: Use rector for automated upgrades.
Appendix¶
F. More php.ini Snippets¶
zend_extension=opcache.so
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=7963
G. Composer Templates¶
{
"require": {
"laravel/framework": "^10.0",
"symfony/http client": "^6.0",
"guzzlehttp/guzzle": "^7.0",
"monolog/monolog": "^3.0",
"vlucas/phpdotenv": "^5.0"
},
"require dev": {
"phpunit/phpunit": "^10.0",
"phpstan/phpstan": "^1.0",
"friendsofphp/php cs fixer": "^3.0",
"rector/rector": "^0.15"
},
"scripts": {
"test": "phpunit",
"lint": "phpstan analyse",
"fix": "php cs fixer fix"
}
}
H. Security Checklists¶
- Implement Content Security Policy (CSP).
- Use Subresource Integrity (SRI) for scripts.
- Regular security audits and penetration testing.
- Monitor for vulnerabilities in dependencies.
- Educate developers on secure coding practices.
I. More Humor¶
- Why did the PHP developer go broke? Because he used too many cents in his code (cents as in 100ths).
- PHP: Hypertext Preprocessor. Also known as "Please Help Programmers".
J. Extended Further Reading¶
- "PHP: The Right Way": https://phptherightway.com/
- "PHP Security Cheat Sheet": https://cheatsheetseries.owasp.org/cheatsheets/PHP_Security_Cheat_Sheet.html
- RFCs: https://wiki.php.net/rfc
- PHP Internals: https://www.phpinternalsbook.com/