ស្វែងយល់ PHP
ពីមូលដ្ឋានដល់ Expert
PHP (Hypertext Preprocessor) ជា Server-side language ដែលប្រើដោយ 77% នៃ Websites ទូទាំងពិភពលោក — WordPress, Laravel, Facebook (ដើម) ។ រៀន PHP 8.3 ពី Syntax រហូតដល់ REST API, OOP, Security។
- PHP Syntax, Tags, echo, Comments
- Variables, Data Types, Type Juggling
- if/else, switch, for, while, foreach
- Functions, Parameters, Return
- Arrays (indexed, associative, multi)
- String Functions, File I/O
- Forms, POST/GET, Validation
- MySQL PDO, CRUD Operations
- Sessions, Cookies, Authentication
- OOP: Class, Object, Inheritance
- Traits, Interfaces, Abstract Classes
- Exception Handling, Custom Errors
- Namespaces, Composer, Autoload
- REST API, JSON, Security
- XAMPP / WAMP / Laragon
- VS Code + PHP Intelephense
- PHP 8.0+ (ណែនាំ 8.3)
- Browser + phpMyAdmin
PHP Basics & Syntax
PHP Tags, echo/print, Comments, Operators, Type Casting, var_dump, Constants។
<?php // Single-line comment /* Multi-line comment */ # Also single-line // Output echo "Hello, World!\n"; // fast print("Hello PHP"); // returns 1 echo "Name: " . "ដារា"; // concatenation // Debug var_dump(42, true, "hello"); // type + value print_r([1, 2, 3]); // readable array // Constants define('APP_NAME', 'MyApp'); const VERSION = '1.0.0'; echo APP_NAME . " v" . VERSION; // MyApp v1.0.0 // Magic Constants echo __LINE__; // Current line number echo __FILE__; // Full file path echo __DIR__; // Directory of file echo __FUNCTION__; // Function name ?> <!-- Short echo tag --> <?= $name ?>
<?php // Arithmetic 10 + 3; 10 - 3; 10 * 3; 10 / 3; 10 % 3; // modulo = 1 2 ** 8; // power = 256 // Comparison 5 == '5'; // true (loose) 5 === '5'; // false (strict) 5 != 6; // true 5 !== '5'; // true (strict) // Spaceship (PHP 7+) 1 <=> 2; // -1 (less) 2 <=> 2; // 0 (equal) 3 <=> 2; // 1 (greater) // Null Coalescing (PHP 7+) $name = $_GET['name'] ?? 'Guest'; // Ternary $age = 20; $status = $age >= 18 ? 'Adult' : 'Minor'; // Null Coalescing Assignment (PHP 8+) $config['debug'] ??= false; ?>
Variables & Data Types
Variable declaration, Type system, Type casting, Type declarations (PHP 8), Enums។
<?php // Variables start with $ $name = "ដារា"; // string $age = 22; // integer $price = 9.99; // float $active = true; // boolean $nothing = null; // null // Type checking gettype($age); // "integer" is_string($name); // true is_int($age); // true is_null($nothing); // true isset($name); // true empty(""); // true // Type Casting $str = "42.5abc"; (int) $str; // 42 (float) $str; // 42.5 (string) 42; // "42" (bool) 0; // false (array) $name; // ["ដារា"] // Heredoc & Nowdoc $html = <<<EOT <p>Name: $name, Age: $age</p> EOT; $raw = <<<'EOT' No $variable parsing here EOT; ?>
<?php // Enums (PHP 8.1+) enum Status { case Active; case Inactive; case Pending; } // Backed Enum enum Color: string { case Red = 'red'; case Green = 'green'; case Blue = 'blue'; } $c = Color::Red; echo $c->value; // "red" $found = Color::from('green'); // Color::Green // Union Types (PHP 8.0+) function process(int|string $input): void { echo $input; } // Intersection Types (PHP 8.1+) function save(Countable&Iterator $col): void {} // Nullsafe Operator (PHP 8.0+) $city = $user?->getAddress()?->getCity()?->getName(); ?>
Control Flow
if/elseif/else, match, switch, for, while, do-while, foreach, break/continue, goto។
<?php $score = 85; // if / elseif / else if ($score >= 90) { echo "A"; } elseif ($score >= 80) { echo "B"; // ← output } else { echo "C"; } // match expression (PHP 8.0+) ← ល្អជាង switch $grade = match (true) { $score >= 90 => 'A', $score >= 80 => 'B', $score >= 70 => 'C', default => 'F', }; // switch switch ($grade) { case 'A': echo "Excellent"; break; case 'B': echo "Good"; break; default: echo "Pass"; } ?>
<?php // for for ($i = 0; $i < 5; $i++) { echo $i . " "; // 0 1 2 3 4 } // while $n = 1; while ($n <= 5) { echo $n++ . " "; } // do-while (run ម្ដងយ៉ាងហោចណាស់) do { echo "run once"; } while (false); // foreach — Array $fruits = ['ស្វាយ', 'ល្ហុង', 'មៀន']; foreach ($fruits as $fruit) { echo $fruit . "\n"; } // foreach — Associative Array $person = ['name' => 'ដារា', 'age' => 22]; foreach ($person as $key => $val) { echo "$key: $val\n"; } // break, continue, nested break for ($i = 0; $i < 10; $i++) { if ($i === 3) continue; // skip 3 if ($i === 7) break; // stop at 7 echo $i; } ?>
PHP Functions
Function declaration, Type hints, Return types, Default params, Variadic, Closures, Arrow functions, Named arguments, Fibers (PHP 8.1)។
<?php // Basic function function greet(string $name, string $lang = 'km'): string { return $lang === 'km' ? "សួស្ដី $name!" : "Hello $name!"; } echo greet('ដារា'); // សួស្ដី ដារា! echo greet('Dara', 'en'); // Hello Dara! // Named arguments (PHP 8.0+) greet(lang: 'en', name: 'Dara'); // Variadic function sum(float ...$nums): float { return array_sum($nums); } sum(1, 2, 3, 4); // 10 // Pass by Reference function addTax(float &$price, float $rate = 0.1): void { $price *= (1 + $rate); } $price = 100.0; addTax($price); // $price = 110 // Closure $multiply = function(int $a, int $b): int { return $a * $b; }; $multiply(3, 4); // 12 // Arrow Function (PHP 7.4+) ← auto-capture $tax = 0.1; $addTax = fn(float $p) => $p * (1 + $tax); $addTax(100); // 110.0 // use — Closure capture $prefix = "ណ"; $greetKm = function($name) use ($prefix): string { return "$prefix$name"; }; ?>
PHP Arrays
Indexed, Associative, Multidimensional Arrays, Array Functions (sort, map, filter, reduce)។
<?php // Indexed Array $nums = [1, 2, 3, 4, 5]; $nums[] = 6; // append // Associative Array $user = [ 'name' => 'ដារា', 'email' => 'dara@mail.com', 'age' => 22, ]; echo $user['name']; // ដារា // Multi-dimensional $students = [ ['name' => 'ដារា', 'grade' => 'A'], ['name' => 'ពិសី', 'grade' => 'B'], ]; echo $students[0]['name']; // ដារា // Array Functions count($nums); // 6 array_push($nums, 7); // add end array_pop($nums); // remove end array_shift($nums); // remove start array_unshift($nums, 0); // add start array_slice($nums, 1, 3); // [2,3,4] array_merge($a, $b); // merge array_unique($nums); // remove duplicates in_array(3, $nums); // true array_key_exists('name', $user);// true array_keys($user); // ['name','email','age'] array_values($user); // ['ដារា','dara@mail.com',22] // Functional Array $doubled = array_map(fn($n) => $n * 2, $nums); $evens = array_filter($nums, fn($n) => $n % 2 === 0); $total = array_reduce($nums, fn($c, $n) => $c + $n, 0); // Sort sort($nums); // ASC (reindex) rsort($nums); // DESC asort($user); // ASC (keep keys) ksort($user); // sort by keys usort($students, fn($a, $b) => $a['name'] <=> $b['name']); ?>
String & File Functions
String manipulation, Regular Expressions, File Read/Write, Directory functions, JSON encoding/decoding។
<?php $s = " Hello PHP World! "; strlen($s); // 20 trim($s); // "Hello PHP World!" ltrim($s); rtrim($s); // left/right trim strtolower($s); // "hello php world!" strtoupper($s); // "HELLO PHP WORLD!" ucfirst($s); // "Hello..." ucwords($s); // capitalize each word str_replace('PHP', 'JavaScript', $s); substr($s, 1, 5); // "Hello" strpos($s, 'PHP'); // 7 (position) str_contains($s, 'PHP'); // true (PHP 8) str_starts_with($s, ' H'); // true str_ends_with($s, '! '); // true str_pad('42', 5, '0', STR_PAD_LEFT); // "00042" str_repeat('-', 20); // "--------------------" explode(' ', $s); // split → array implode(',', $arr); // join → string sprintf("%.2f", 3.14159); // "3.14" // Regex preg_match('/^\d+$/', '123'); // 1 preg_replace('/\s+/', '-', $s); // replace spaces preg_split('/[\s,]+/', $s); // split by space/comma preg_match_all('/\w+/', $s, $m); // all words ?>
<?php // Read file $content = file_get_contents('data.txt'); $lines = file('data.txt'); // array of lines // Write file file_put_contents('log.txt', "Log entry\n", FILE_APPEND); // fopen / fclose $fh = fopen('data.txt', 'r'); while (($line = fgets($fh)) !== false) { echo $line; } fclose($fh); // File checks file_exists('file.txt'); // true/false is_file('file.txt'); // is file is_dir('folder'); // is directory mkdir('uploads', 0755, true); unlink('old.txt'); // delete file // JSON $data = ['name' => 'ដារា', 'age' => 22]; $json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); $back = json_decode($json, true); // true = array echo $back['name']; // ដារា ?>
Forms & Superglobals
$_GET, $_POST, $_REQUEST, $_FILES, $_SERVER, $_ENV, Form Validation, Sanitization, CSRF Protection។
<?php // $_POST — Form submission if ($_SERVER['REQUEST_METHOD'] === 'POST') { // Sanitize $name = htmlspecialchars(trim($_POST['name'] ?? '')); $email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL); $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT); // Validate $errors = []; if (empty($name)) $errors[] = 'ឈ្មោះមិនអាចទទេ'; if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = 'Email មិនត្រឹមត្រូវ'; if ($age === false || $age < 1) $errors[] = 'អាយុមិនត្រឹមត្រូវ'; if (empty($errors)) { echo "✅ Form OK"; } else { foreach ($errors as $e) echo "❌ $e<br>"; } } // $_GET — URL parameters $id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT); $page = max(1, (int)($_GET['page'] ?? 1)); // $_FILES — File Upload if (isset($_FILES['avatar'])) { $file = $_FILES['avatar']; $allowed = ['image/jpeg', 'image/png', 'image/webp']; if (in_array($file['type'], $allowed) && $file['size'] < 2_000_000) { move_uploaded_file( $file['tmp_name'], 'uploads/' . basename($file['name']) ); } } // CSRF Token session_start(); $_SESSION['csrf'] ??= bin2hex(random_bytes(32)); ?> <input type="hidden" name="csrf" value="<?= htmlspecialchars($_SESSION['csrf']) ?>">
MySQL + PDO
PDO Connection, Prepared Statements, CRUD, Transactions, Error Handling, Pagination។
<?php // ─ CONNECTION ─ $dsn = "mysql:host=localhost;dbname=school_db;charset=utf8mb4"; try { $pdo = new PDO($dsn, 'root', '', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]); } catch (PDOException $e) { die("Connection failed: " . $e->getMessage()); } // ─ CREATE (INSERT) ─ $stmt = $pdo->prepare(" INSERT INTO students (name, email, age, grade) VALUES (:name, :email, :age, :grade) "); $stmt->execute([ ':name' => 'ដារា', ':email' => 'dara@mail.com', ':age' => 22, ':grade' => 3.8, ]); $id = $pdo->lastInsertId(); // ─ READ (SELECT) ─ $stmt = $pdo->prepare("SELECT * FROM students WHERE age > :age ORDER BY grade DESC"); $stmt->execute([':age' => 18]); $students = $stmt->fetchAll(); // Single row $student = $pdo->prepare("SELECT * FROM students WHERE id=?"); $student->execute([ $id ]); $row = $student->fetch(); // ─ UPDATE ─ $pdo->prepare("UPDATE students SET grade=? WHERE id=?") ->execute([4.0, $id]); // ─ DELETE ─ $pdo->prepare("DELETE FROM students WHERE id=?") ->execute([$id]); // ─ TRANSACTION ─ try { $pdo->beginTransaction(); // ... multiple queries ... $pdo->commit(); } catch (PDOException $e) { $pdo->rollBack(); throw $e; } ?>
Sessions & Cookies
session_start, $_SESSION, $_COOKIE, setcookie, Login/Logout System, Remember Me, Flash Messages។
<?php // ─ SESSION ─ session_start(); // ALWAYS first! // Set $_SESSION['user_id'] = 42; $_SESSION['username'] = 'ដារា'; $_SESSION['is_admin'] = false; // Read echo $_SESSION['username'] ?? 'Guest'; // Unset one unset($_SESSION['user_id']); // Destroy (logout) session_unset(); session_destroy(); // ─ COOKIES ─ // setcookie(name, value, expires, path, domain, secure, httponly) setcookie('remember', 'token_value', [ 'expires' => time() + (86400 * 30), // 30 days 'path' => '/', 'secure' => true, 'httponly' => true, 'samesite' => 'Strict', ]); echo $_COOKIE['remember'] ?? ''; setcookie('remember', '', time() - 1); // delete // ─ LOGIN SYSTEM ─ function login(PDO $pdo, string $email, string $pass): bool { $stmt = $pdo->prepare("SELECT * FROM users WHERE email=? LIMIT 1"); $stmt->execute([$email]); $user = $stmt->fetch(); if ($user && password_verify($pass, $user['password'])) { session_regenerate_id(true); // prevent session fixation $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['name']; return true; } return false; } // Hash password $hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]); // Flash Messages $_SESSION['flash'] = ['type' => 'success', 'msg' => 'Login OK!']; $flash = $_SESSION['flash'] ?? null; unset($_SESSION['flash']); // show once ?>
OOP & Classes
Class, Object, Constructor, Properties, Methods, Access Modifiers, Inheritance, Abstract, Static, readonly (PHP 8.1)។
<?php abstract class Animal { private static int $count = 0; // Constructor Promotion (PHP 8.0+) public function __construct( protected readonly string $name, protected int $age, ) { self::$count++; } // Abstract method — subclass must implement abstract public function speak(): string; public function info(): string { return "{$this->name} ({$this->age} yrs)"; } public static function getCount(): int { return self::$count; } // Magic methods public function __toString(): string { return $this->info(); } } class Dog extends Animal { private array $tricks = []; public function speak(): string { return "{$this->name}: ហ្វូ ហ្វូ!"; } public function learn(string $trick): static { $this->tricks[] = $trick; return $this; // fluent / method chaining } } $dog = new Dog('Rex', 3); $dog->learn('sit')->learn('stay')->learn('roll'); echo $dog->speak(); // Rex: ហ្វូ ហ្វូ! echo Animal::getCount(); // 1 ?>
Traits & Interfaces
Interface, implements, Trait, use, conflict resolution, final class, readonly class (PHP 8.2)។
<?php // Interface — contract (no implementation) interface Payable { public function pay(float $amount): bool; public function getBalance(): float; } interface Notifiable { public function notify(string $msg): void; } // Trait — reusable code blocks trait Timestampable { private ?string $createdAt = null; public function setCreatedAt(): void { $this->createdAt = date('Y-m-d H:i:s'); } public function getCreatedAt(): ?string { return $this->createdAt; } } trait SoftDeletable { private bool $deleted = false; public function softDelete(): void { $this->deleted = true; } public function isDeleted(): bool { return $this->deleted; } } // Class using multiple interface + trait class BankAccount implements Payable, Notifiable { use Timestampable, SoftDeletable; public function __construct( private float $balance = 0 ) {} public function pay(float $amount): bool { if ($amount > $this->balance) return false; $this->balance -= $amount; return true; } public function getBalance(): float { return $this->balance; } public function notify(string $msg): void { echo $msg; } } // readonly class (PHP 8.2) readonly class Money { public function __construct( public float $amount, public string $currency ) {} } ?>
Error Handling
try/catch/finally, Custom Exceptions, Exception hierarchy, set_error_handler, Logging។
<?php // Custom Exception hierarchy class AppException extends \RuntimeException {} class ValidationException extends AppException { public function __construct( private readonly array $errors, string $message = 'Validation failed' ) { parent::__construct($message); } public function getErrors(): array { return $this->errors; } } class DatabaseException extends AppException {} class NotFoundException extends AppException {} // try / catch / finally function findUser(PDO $pdo, int $id): array { $stmt = $pdo->prepare("SELECT * FROM users WHERE id=?"); $stmt->execute([$id]); $user = $stmt->fetch(); if (!$user) { throw new NotFoundException("User #$id not found"); } return $user; } try { $user = findUser($pdo, 999); } catch (NotFoundException $e) { echo "404: " . $e->getMessage(); } catch (DatabaseException | AppException $e) { // Multiple catch (PHP 8) error_log($e->getMessage()); echo "Internal Error"; } finally { echo "Always runs"; // cleanup } // Global error handler set_exception_handler(function(\Throwable $e) { http_response_code(500); error_log($e); echo json_encode(['error' => $e->getMessage()]); }); ?>
Namespaces & Composer
Namespaces, use/as, PSR-4 Autoloading, Composer, composer.json, Packages, Autoload Classes។
<?php // src/Models/User.php namespace App\Models; class User { public function __construct( public readonly int $id, public readonly string $name, ) {} } // src/Services/UserService.php namespace App\Services; use App\Models\User; use App\Repositories\UserRepository; use PDO; class UserService { public function __construct( private UserRepository $repo ) {} public function findById(int $id): ?User { return $this->repo->find($id); } } ?>
REST API & JSON
RESTful routing, HTTP methods, Headers, Response codes, JWT basics, API versioning, Rate limiting concept។
<?php // api/index.php — Simple REST Router header('Content-Type: application/json'); header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS'); function respond(mixed $data, int $code = 200): void { http_response_code($code); echo json_encode([ 'success' => $code < 400, 'data' => $data, ], JSON_UNESCAPED_UNICODE); exit; } $method = $_SERVER['REQUEST_METHOD']; $uri = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/'); $parts = explode('/', $uri); $body = json_decode(file_get_contents('php://input'), true) ?? []; // Route: GET /api/users if ($method === 'GET' && $parts[1] === 'users') { if (isset($parts[2])) { // GET /api/users/{id} $id = (int) $parts[2]; respond(['id' => $id, 'name' => 'ដារា']); } respond([['id' => 1, 'name' => 'ដារា']]); } // POST /api/users if ($method === 'POST' && $parts[1] === 'users') { if (empty($body['name'])) respond(['errors' => ['name required']], 422); respond($body, 201); } respond(['error' => 'Route not found'], 404); ?>
<?php // Simple JWT (concept — use firebase/php-jwt in production) function base64url(string $data): string { return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); } function createJWT(array $payload, string $secret): string { $header = base64url(json_encode(['alg'=>'HS256', 'typ'=>'JWT'])); $payload['iat'] = time(); $payload['exp'] = time() + 3600; $body = base64url(json_encode($payload)); $sig = base64url(hash_hmac('sha256', "$header.$body", $secret, true)); return "$header.$body.$sig"; } // Bearer token middleware $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; if (preg_match('/^Bearer\s(.+)/', $authHeader, $m)) { $token = $m[1]; // verify token... } ?>
Security & Performance
SQL Injection, XSS, CSRF, Password Hashing, Rate Limiting, OPcache, Caching strategies, php.ini security settings។
<?php // ── SQL INJECTION Prevention ── // ❌ NEVER: string interpolation in SQL // $pdo->query("SELECT * FROM users WHERE id = $_GET[id]"); // ✅ ALWAYS: Prepared Statements $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$_GET['id']]); // ── XSS Prevention ── // ❌ NEVER echo raw user input // echo $_POST['comment']; // ✅ ALWAYS escape output echo htmlspecialchars($_POST['comment'], ENT_QUOTES, 'UTF-8'); // ── CSRF Protection ── function csrf_token(): string { session_start(); return $_SESSION['csrf'] ??= bin2hex(random_bytes(32)); } function csrf_verify(): void { session_start(); $token = $_POST['_csrf'] ?? ''; if (!hash_equals($_SESSION['csrf'] ?? '', $token)) { http_response_code(403); die('CSRF token mismatch'); } } // ── Password Hashing ── $hash = password_hash($password, PASSWORD_ARGON2ID); $verify = password_verify($input, $hash); $needsRehash = password_needs_rehash($hash, PASSWORD_ARGON2ID); // ── Rate Limiting (simple) ── function rateLimit(string $key, int $max = 60, int $window = 60): bool { session_start(); $now = time(); $data = $_SESSION['rate_'.$key] ?? ['count'=>0, 'reset'=>$now+$window]; if ($now > $data['reset']) $data = ['count'=>0, 'reset'=>$now+$window]; $data['count']++; $_SESSION['rate_'.$key] = $data; return $data['count'] <= $max; } // ── Security Headers ── header("X-Frame-Options: DENY"); header("X-Content-Type-Options: nosniff"); header("X-XSS-Protection: 1; mode=block"); header("Referrer-Policy: strict-origin-when-cross-origin"); header("Content-Security-Policy: default-src 'self'"); header("Strict-Transport-Security: max-age=31536000; includeSubDomains"); ?>
សូមអបអរ! អ្នកបានបញ្ចប់មេរៀន PHP ទាំងអស់ ១៥ — ពី Syntax ដំបូងរហូតដល់ OOP, PDO, API, Security! ជំហានបន្ទាប់: Laravel Framework, Symfony, PHP Unit Testing!