สรุปสั้น
- เปิด
declare(strict_types=1);และใส่ type ให้ parameter กับค่าที่ return- เปรียบเทียบด้วย
===เหมือน JavaScript- array ของ PHP เป็นทั้ง list และ key-value ในตัวเดียว
- ความปลอดภัย 3 ข้อที่ห้ามพลาด: prepared statement กัน SQL injection,
htmlspecialcharsกัน XSS,password_hashเก็บรหัสผ่าน- คำสั่งฐานข้อมูลดูต่อที่ พื้นฐาน SQL
1. โครงไฟล์และตัวแปร
<?php
declare(strict_types=1); // บังคับชนิดข้อมูลให้ตรง ลดบั๊กแปลงชนิดเอง
$name = "Somchai"; // ตัวแปรขึ้นต้นด้วย $
$age = 30;
$price = 99.5;
$isActive = true;
$nothing = null;
echo "สวัสดี {$name} อายุ {$age}"; // string แบบ " แทรกตัวแปรได้
echo 'ไม่แทรก $name'; // string แบบ ' ไม่แทรกไฟล์ที่มีแต่ PHP ไม่ต้องปิดด้วย ?> ช่วยกันช่องว่างหลุดออกไปใน output
2. การเปรียบเทียบ
0 == "a" // false ใน PHP 8 (PHP 7 เป็น true!)
"1" == "01" // true ← แปลงเป็นตัวเลขก่อนเทียบ
"1" === "01" // falseใช้ === และ !== เสมอ ฟังก์ชันอย่าง in_array และ array_search ให้ส่ง true เป็นพารามิเตอร์ตัวที่ 3 เพื่อเทียบแบบเข้มงวด
$city = $user['address']['city'] ?? 'ไม่ระบุ'; // null coalescing: ไม่มี key ก็ไม่ error
$zip = $order?->customer?->zip; // nullsafe (PHP 8)3. Array
$fruits = ["apple", "banana"]; // แบบ list (index 0, 1, ...)
$user = ["name" => "Somchai", "age" => 30]; // แบบ key => value
$fruits[] = "mango"; // เพิ่มท้าย
foreach ($user as $key => $value) {
echo "$key: $value\n";
}ฟังก์ชันที่ใช้บ่อย:
array_map(fn($p) => $p * 1.07, $prices); // แปลงทุกตัว
array_filter($prices, fn($p) => $p > 90); // กรอง (key เดิมยังอยู่!)
array_values(array_filter(...)); // เรียง key ใหม่ 0, 1, 2
array_sum($prices);
in_array("apple", $fruits, true);
array_key_exists("name", $user);
count($fruits);
array_filterไม่รีเซ็ต keyผลลัพธ์อาจเป็น
[0 => ..., 2 => ...]พอแปลงเป็น JSON จะกลายเป็น object แทน array ครอบด้วยarray_values()ก่อนส่งออก
4. ฟังก์ชันและ type
function calcVat(float $amount, float $rate = 0.07): float
{
return round($amount * $rate, 2);
}
function findUser(int $id): ?User // ? = อาจคืน null
{
// ...
}
$double = fn(int $x): int => $x * 2; // arrow function (PHP 7.4+)match: แทน switch ที่ปลอดภัยกว่า
$label = match ($status) {
'paid' => 'ชำระแล้ว',
'pending' => 'รอชำระ',
default => 'ไม่ทราบสถานะ',
};match เทียบแบบ === คืนค่าได้ และถ้าไม่มีกรณีไหนตรงเลย (และไม่มี default) จะ throw error แทนที่จะเงียบ
5. OOP
namespace App\Services;
interface PaymentGateway
{
public function charge(int $amountSatang): bool;
}
final class OrderService
{
public function __construct(
private readonly PaymentGateway $gateway, // constructor promotion (PHP 8)
) {}
public function checkout(Order $order): void
{
if (! $this->gateway->charge($order->totalSatang)) {
throw new PaymentFailedException("ชำระเงินไม่สำเร็จ");
}
}
}- interface กำหนดว่า “ต้องมี method อะไร” ทำให้สลับตัวจริงหรือ mock ตอนเทสต์ได้
- constructor injection ส่งของที่ต้องใช้เข้ามาทาง constructor แทนการ
newเองข้างใน - enum (PHP 8.1) ใช้แทนค่าคงที่แบบ string
enum OrderStatus: string {
case Paid = 'paid';
case Pending = 'pending';
}
OrderStatus::from('paid'); // OrderStatus::Paid6. Composer และ autoload
composer require guzzlehttp/guzzleComposer จัดการ library และโหลด class ให้อัตโนมัติตามชื่อ namespace (มาตรฐาน PSR-4) แค่ require 'vendor/autoload.php'; ครั้งเดียว
7. Error และ Exception
try {
$service->checkout($order);
} catch (PaymentFailedException $e) {
// จัดการเฉพาะกรณีที่รู้วิธีแก้
} finally {
// ทำเสมอ เช่น ปิด connection
}อย่า catch (Exception $e) {} แล้วปล่อยว่าง ความผิดพลาดจะหายไปเงียบ ๆ และหาสาเหตุไม่เจอ
8. ความปลอดภัยที่ต้องทำทุกครั้ง
SQL injection → ใช้ prepared statement
// ❌ อันตราย: ผู้ใช้พิมพ์ ' OR 1=1 -- ก็ดึงข้อมูลได้ทั้งตาราง
$pdo->query("SELECT * FROM users WHERE email = '$email'");
// ✅ ปลอดภัย
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();XSS → escape ก่อนแสดงผล
echo htmlspecialchars($comment, ENT_QUOTES, 'UTF-8');รหัสผ่าน → hash เสมอ
$hash = password_hash($password, PASSWORD_DEFAULT);
if (password_verify($input, $hash)) { /* ถูกต้อง */ }ห้ามเก็บรหัสผ่านตรง ๆ และห้ามใช้ md5 หรือ sha1
จุดที่มักพลาด
- ใช้
==แล้วเจอการแปลงชนิดแปลก ๆ empty("0")เป็นtrue→ ถ้าต้องการเช็กว่ามีค่าไหม ใช้issetหรือเทียบตรง ๆ- ลืมว่า PHP 7 กับ 8 มีพฤติกรรมต่างกันบางจุด (เช่นการเทียบ string กับตัวเลข) → เช็กเวอร์ชันของ server ก่อน
- ใช้
floatกับเงิน → เก็บเป็นสตางค์ (int) หรือใช้ library ทศนิยม - query ใน loop (ปัญหา N+1) → ดูวิธีแก้ใน พื้นฐาน SQL
แหล่งอ้างอิง
- PHP Manual · https://www.php.net/manual/en/
- PHP The Right Way · https://phptherightway.com/