PHP Beginner Guide

PHP for beginnersPHP สำหรับผู้เริ่มต้น

PHP Beginner Guide

From your first echo to a tested classตั้งแต่ echo แรกจนถึงคลาสที่มีเทสต์

PHP runs a large part of the web, from WordPress sites to Laravel apps. This guide teaches the language from the first line: variables, strings, decisions, loops, arrays, functions, classes, forms, databases and tests. Every example on this page runs real PHP 8.3 in your browser. Change the code, press Run, and see what happens. PHP ขับเคลื่อนเว็บจำนวนมาก ตั้งแต่เว็บ WordPress ไปจนถึงแอป Laravel คู่มือนี้สอนภาษา PHP ตั้งแต่บรรทัดแรก: ตัวแปร ข้อความ การตัดสินใจ ลูป อาร์เรย์ ฟังก์ชัน คลาส ฟอร์ม ฐานข้อมูล และการทดสอบ ทุกตัวอย่างในหน้านี้รัน PHP 8.3 จริงในเบราว์เซอร์ของคุณ ลองแก้โค้ด กด Run แล้วดูว่าเกิดอะไรขึ้น

Each example first shows the output it printed when I ran it with PHP 8.3.33 on the command line, so you can check your own run against it. New to programming logic? Start with Logic & Loops. Finished? Continue with the Laravel Beginner Guide. ทุกตัวอย่างจะแสดงผลลัพธ์ที่ได้จากการรันจริงด้วย PHP 8.3.33 ผ่าน command line ไว้ก่อน เพื่อให้เทียบกับผลที่คุณรันเองได้ ถ้ายังใหม่กับตรรกะการเขียนโปรแกรม ให้เริ่มจาก Logic & Loops ก่อน เรียนจบแล้วไปต่อที่ Laravel Beginner Guide

Shortcut: pressคีย์ลัด: กด Ctrl+Enter (⌘+Enter Mac) inside a code box to run it. The first run downloads PHP (about 13 MB); after that it starts in about a second.ในกล่องโค้ดเพื่อรันทันที การรันครั้งแรกจะดาวน์โหลด PHP (ประมาณ 13 MB) หลังจากนั้นจะเริ่มได้ในเวลาประมาณหนึ่งวินาที

  • Recorded onบันทึกจาก PHP 8.3.33
  • Runs in browserรันในเบราว์เซอร์ PHP 8.3 (WebAssembly)
  • Testsเทสต์ PHPUnit 12.5

Lesson 1 · Setupบทที่ 1 · ติดตั้ง

Getting startedเริ่มต้นใช้งาน

PHP is a program that reads a .php file, runs the code inside it, and prints the result. On a web server, that result is the HTML page a visitor sees. On your computer, it appears in the terminal. You can follow this whole page in the browser, but installing PHP lets you run files of your own. PHP คือโปรแกรมที่อ่านไฟล์ .php รันโค้ดข้างใน แล้วพิมพ์ผลลัพธ์ออกมา บนเว็บเซิร์ฟเวอร์ ผลลัพธ์นั้นคือหน้า HTML ที่ผู้เข้าชมเห็น ส่วนบนเครื่องของเราจะแสดงในเทอร์มินัล หน้านี้เรียนในเบราว์เซอร์ได้ทั้งหมด แต่การติดตั้ง PHP จะทำให้รันไฟล์ของตัวเองได้

SystemระบบInstallวิธีติดตั้ง
macOSbrew install php
Ubuntu / Debiansudo apt install php-cli php-mbstring php-sqlite3 php-xml
WindowsInstall Laravel Herd (includes PHP and Composer), or download PHP from windows.php.net.ติดตั้ง Laravel Herd (มี PHP และ Composer ให้ในตัว) หรือดาวน์โหลด PHP จาก windows.php.net

Then check that it works. php -v prints the version: จากนั้นตรวจว่าใช้งานได้ คำสั่ง php -v จะแสดงเวอร์ชัน:

Terminalเทอร์มินัลPHP 8.3.33 · macOS
$ php -v
PHP 8.3.33 (cli) (built: Jul 28 2026 17:56:10) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.33, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.33, Copyright (c), by Zend Technologies

Save the code below as hello.php and run it with php hello.php. Or press Run here. บันทึกโค้ดด้านล่างเป็นไฟล์ hello.php แล้วรันด้วยคำสั่ง php hello.php หรือกด Run ที่นี่ได้เลย

  • Every PHP file starts with <?php. Anything before it is printed as plain text.ไฟล์ PHP ทุกไฟล์เริ่มด้วย <?php ข้อความใดๆ ที่อยู่ก่อนหน้าจะถูกพิมพ์ออกมาเป็นข้อความธรรมดา
  • Every statement ends with a semicolon ;.ทุกคำสั่งต้องจบด้วยเซมิโคลอน ;
  • echo prints text. "\n" starts a new line.echo ใช้พิมพ์ข้อความ ส่วน "\n" คือการขึ้นบรรทัดใหม่
  • // starts a comment: PHP ignores the rest of the line.// คือคอมเมนต์ PHP จะไม่สนใจข้อความที่เหลือในบรรทัดนั้น
Tipเคล็ดลับ

The version line above says 8.3.33 in the recorded output and 8.3.11 after you press Run. Both are real: the recorded output comes from PHP installed on a Mac, and Run uses PHP compiled to WebAssembly inside your browser. Small differences like this, or file paths in error messages, are expected.บรรทัดเวอร์ชันด้านบนแสดง 8.3.33 ในผลลัพธ์ที่บันทึกไว้ และ 8.3.11 หลังจากกด Run ทั้งสองค่าเป็นของจริง ผลลัพธ์ที่บันทึกไว้มาจาก PHP ที่ติดตั้งบน Mac ส่วนปุ่ม Run ใช้ PHP ที่คอมไพล์เป็น WebAssembly ในเบราว์เซอร์ ความต่างเล็กๆ แบบนี้ หรือพาธไฟล์ในข้อความผิดพลาด จึงเป็นเรื่องปกติ

Lesson 2 · The basicsบทที่ 2 · พื้นฐาน

Variables & typesตัวแปรและชนิดข้อมูล

A variable is a named box that holds a value. In PHP every variable name starts with $. You don't declare a type: PHP works it out from the value you store. ตัวแปร (variable) คือกล่องที่มีชื่อสำหรับเก็บค่า ใน PHP ชื่อตัวแปรทุกตัวขึ้นต้นด้วย $ และไม่ต้องประกาศชนิดข้อมูล PHP จะรู้เองจากค่าที่เก็บลงไป

TypeชนิดHoldsเก็บอะไรExampleตัวอย่าง
stringtextข้อความ"Mya"
intwhole numberจำนวนเต็ม21
floatdecimal numberเลขทศนิยม1.62
booltrue or falseจริงหรือเท็จtrue
nullno valueไม่มีค่าnull
arraya list of values (lesson 6)รายการของค่า (บทที่ 6)[1, 2, 3]

echo prints a value. var_dump prints the type as well, which is what you want when something looks wrong. Note how echo would print true as 1 and false as nothing at all. echo พิมพ์ค่า ส่วน var_dump พิมพ์ชนิดข้อมูลด้วย ซึ่งมีประโยชน์มากเวลาที่มีอะไรดูผิดปกติ สังเกตว่า echo จะพิมพ์ true เป็น 1 และพิมพ์ false เป็นค่าว่างเปล่า

Tipเคล็ดลับ

Variable names are case-sensitive: $name and $Name are two different boxes. Use $camelCase names that say what they hold, like $totalPrice. To add to a string, use .=: $text .= "more";ชื่อตัวแปรแยกตัวพิมพ์เล็กใหญ่ $name กับ $Name เป็นคนละกล่องกัน ตั้งชื่อแบบ $camelCase ที่บอกว่าเก็บอะไร เช่น $totalPrice ถ้าจะต่อข้อความเพิ่ม ใช้ .= เช่น $text .= "more";

Lesson 3 · Textบทที่ 3 · ข้อความ

Stringsข้อความ (string)

Most of what a web app handles is text: names, emails, titles, messages. PHP has a built-in function for almost every text job. Here are the ones you'll use every day. ข้อมูลส่วนใหญ่ที่เว็บแอปต้องจัดการคือข้อความ เช่น ชื่อ อีเมล หัวข้อ และข้อความต่างๆ PHP มีฟังก์ชันสำเร็จรูปแทบทุกงานเกี่ยวกับข้อความ นี่คือฟังก์ชันที่จะได้ใช้ทุกวัน

Functionฟังก์ชันDoesทำอะไรExample → resultตัวอย่าง → ผลลัพธ์
trimremove spaces at both endsตัดช่องว่างหัวท้ายtrim(" a ") → "a"
strtoupperupper caseตัวพิมพ์ใหญ่strtoupper("php") → "PHP"
str_containsdoes it contain…?มีคำนี้อยู่ไหมstr_contains("php", "h") → true
str_replacereplace every matchแทนที่ทุกจุดที่ตรงstr_replace("a", "o", "cat") → "cot"
explodesplit into an arrayแยกเป็นอาร์เรย์explode(",", "a,b") → ["a", "b"]
implodejoin an arrayรวมอาร์เรย์เป็นข้อความimplode("-", ["a", "b"]) → "a-b"
number_formatformat a numberจัดรูปแบบตัวเลขnumber_format(1500) → "1,500"

Thai text needs the mb_ functionsข้อความภาษาไทยต้องใช้ฟังก์ชัน mb_

strlen, substr and friends count bytes. English letters are one byte each, but a Thai letter takes three. For Thai (or any non-English text), use the multibyte versions: mb_strlen, mb_substr, mb_strtoupper. strlen, substr และฟังก์ชันกลุ่มเดียวกันนับเป็นไบต์ ตัวอักษรภาษาอังกฤษใช้ตัวละหนึ่งไบต์ แต่ตัวอักษรไทยใช้สามไบต์ สำหรับภาษาไทย (หรือภาษาอื่นที่ไม่ใช่อังกฤษ) ให้ใช้ฟังก์ชันแบบ multibyte คือ mb_strlen, mb_substr, mb_strtoupper

Noteหมายเหตุ

mb_strlen("สวัสดี") is 6, not 5, because vowel and tone marks such as ั and ี are separate characters in Unicode. The � in the last line is half a Thai letter that the browser can't draw.mb_strlen("สวัสดี") ได้ 6 ไม่ใช่ 5 เพราะสระและวรรณยุกต์ เช่น ั และ ี นับเป็นตัวอักษรแยกใน Unicode ส่วน � ในบรรทัดสุดท้ายคือตัวอักษรไทยครึ่งตัวที่เบราว์เซอร์แสดงไม่ได้

Lesson 4 · Selectionบทที่ 4 · การเลือก

Decisionsการตัดสินใจ

if runs a block only when its condition is true. PHP checks if, then each elseif (one word in PHP), from top to bottom, runs the first block that matches and skips the rest. match picks a value by comparing one thing against a list of options. if จะรันบล็อกก็ต่อเมื่อเงื่อนไขเป็นจริง PHP ตรวจ if แล้วตามด้วย elseif แต่ละตัว (ใน PHP เขียนติดกันเป็นคำเดียว) จากบนลงล่าง รันบล็อกแรกที่ตรง แล้วข้ามที่เหลือ ส่วน match เลือกค่าโดยเทียบสิ่งหนึ่งกับรายการตัวเลือก

PHP has two kinds of equality. == converts both sides to the same type first. === also checks that the types match. Use === unless you have a reason not to. PHP มีการเปรียบเทียบความเท่ากันสองแบบ == จะแปลงทั้งสองฝั่งให้เป็นชนิดเดียวกันก่อน ส่วน === ตรวจด้วยว่าชนิดตรงกัน ให้ใช้ === เป็นหลัก เว้นแต่มีเหตุผลจริงๆ

WriteเขียนMeansความหมาย
=== !==same value and type / not the sameค่าและชนิดเหมือนกัน / ไม่เหมือนกัน
> < >= <=bigger, smaller, or equalมากกว่า น้อยกว่า หรือเท่ากับ
&& || !and, or, notและ หรือ ไม่
$a ?? $b$a, or $b if $a is null or missing$a หรือ $b ถ้า $a เป็น null หรือไม่มีอยู่
$ok ? $x : $ya one-line if/elseif/else แบบบรรทัดเดียว
Carefulระวัง

if ($score = 80) with one = stores 80 in $score and is always true. Comparing needs ===.if ($score = 80) ที่ใช้ = ตัวเดียว คือการเก็บ 80 ลงใน $score และเป็นจริงเสมอ การเปรียบเทียบต้องใช้ ===

Lesson 5 · Repetitionบทที่ 5 · การวนซ้ำ

Loopsการวนซ้ำ

for counts, while repeats as long as a condition stays true, and foreach walks through every item of an array. In PHP you'll use foreach most of all. for ใช้นับรอบ while ทำซ้ำตราบใดที่เงื่อนไขยังเป็นจริง และ foreach เดินผ่านทุกรายการในอาร์เรย์ ใน PHP จะได้ใช้ foreach บ่อยที่สุด

continue skips to the next round. break leaves the loop completely. continue ข้ามไปรอบถัดไป ส่วน break ออกจากลูปทันที

Tipเคล็ดลับ

Try deleting $left--; and pressing Run. The loop never ends, so this page stops it after 6 seconds. In a terminal, press Ctrl+C to stop a script.ลองลบ $left--; แล้วกด Run ลูปจะไม่มีวันจบ หน้านี้จึงหยุดมันให้หลัง 6 วินาที ถ้าอยู่ในเทอร์มินัล ให้กด Ctrl+C เพื่อหยุดสคริปต์

Lesson 6 · Dataบทที่ 6 · ข้อมูล

Arraysอาร์เรย์

An array holds many values in one variable. A list uses number keys that start at 0. An associative array uses text keys, like a small record. Arrays of records are how most data looks in PHP, including database rows. อาร์เรย์เก็บหลายค่าไว้ในตัวแปรเดียว แบบรายการ (list) ใช้คีย์เป็นตัวเลขเริ่มจาก 0 แบบ associative array ใช้คีย์เป็นข้อความ คล้ายระเบียนเล็กๆ อาร์เรย์ของระเบียนคือรูปแบบข้อมูลส่วนใหญ่ใน PHP รวมถึงแถวข้อมูลจากฐานข้อมูล

Functionฟังก์ชันDoesทำอะไร
count($a)number of itemsจำนวนสมาชิก
in_array($x, $a, true)is this value in the array? (true = strict)มีค่านี้ในอาร์เรย์ไหม (true = แบบเข้มงวด)
isset($a["key"])does this key exist (and is not null)?มีคีย์นี้อยู่ไหม (และไม่เป็น null)
sort($a)sort the array itself (returns true, not a new array)เรียงอาร์เรย์เดิม (คืน true ไม่ใช่อาร์เรย์ใหม่)
array_map(fn, $a)a new array with fn applied to every itemอาร์เรย์ใหม่ที่ผ่าน fn ทุกสมาชิก
array_filter($a, fn)only the items where fn returns true (keeps keys)เฉพาะสมาชิกที่ fn คืนค่าจริง (คีย์เดิมคงอยู่)
array_column($rows, "k")one column from an array of recordsดึงหนึ่งคอลัมน์จากอาร์เรย์ของระเบียน
array_sum max mintotal, largest, smallestผลรวม ค่ามากสุด ค่าน้อยสุด

Lesson 7 · Reuseบทที่ 7 · การนำกลับมาใช้ซ้ำ

Functionsฟังก์ชัน

A function is a named block of code you can call many times. It takes inputs (parameters) and sends a result back with return. Adding types to the parameters and the return value lets PHP catch mistakes for you, especially with declare(strict_types=1) at the top of the file. ฟังก์ชันคือบล็อกโค้ดที่มีชื่อ เรียกใช้ซ้ำได้หลายครั้ง รับข้อมูลเข้า (พารามิเตอร์) และส่งผลลัพธ์กลับด้วย return การระบุชนิดให้พารามิเตอร์และค่าที่คืนช่วยให้ PHP จับข้อผิดพลาดให้ได้ โดยเฉพาะเมื่อใส่ declare(strict_types=1) ไว้บนสุดของไฟล์

Scopeขอบเขต

A function can't see variables from outside it, and its own variables disappear when it returns. Pass values in as parameters, and send results out with return.ฟังก์ชันมองไม่เห็นตัวแปรที่อยู่ข้างนอก และตัวแปรของฟังก์ชันจะหายไปเมื่อ return แล้ว ให้ส่งค่าเข้าไปเป็นพารามิเตอร์ และส่งผลลัพธ์ออกมาด้วย return

Lesson 8 · Objectsบทที่ 8 · ออบเจกต์

Classes & objectsคลาสและออบเจกต์

A class is a blueprint. Each object you make from it with new has its own data (properties) and shares the same behaviour (methods). private means only code inside the class can touch a property, so the rest of the program has to go through the methods. Laravel is built from classes like this. คลาส (class) คือแม่แบบ ออบเจกต์ (object) แต่ละตัวที่สร้างด้วย new มีข้อมูลของตัวเอง (property) และใช้พฤติกรรมเดียวกัน (method) private หมายถึงเฉพาะโค้ดในคลาสเท่านั้นที่แตะ property นั้นได้ ส่วนอื่นของโปรแกรมต้องผ่าน method เท่านั้น Laravel ก็สร้างขึ้นจากคลาสแบบนี้

Assigning an object to another variable doesn't copy it. Both variables point to the same object. Use clone when you really want a copy. การกำหนดออบเจกต์ให้ตัวแปรอื่นไม่ได้เป็นการคัดลอก ตัวแปรทั้งสองชี้ไปที่ออบเจกต์เดียวกัน ถ้าต้องการสำเนาจริงๆ ให้ใช้ clone

WriteเขียนMeansความหมาย
new Cart()make an object from the classสร้างออบเจกต์จากคลาส
$cart->add($x)call a method on an objectเรียก method ของออบเจกต์
$thisinside a method: the current objectภายใน method: ออบเจกต์ปัจจุบัน
public privateusable from anywhere / only inside the classใช้ได้จากทุกที่ / เฉพาะในคลาส
__constructruns once when the object is createdทำงานครั้งเดียวตอนสร้างออบเจกต์
readonlycan be set once, never changedกำหนดค่าได้ครั้งเดียว แก้ไม่ได้อีก

Lesson 9 · When things go wrongบทที่ 9 · เมื่อเกิดปัญหา

Errors & exceptionsข้อผิดพลาดและ exception

PHP reports problems in two ways. A warning is printed, and the script keeps going. An error or exception stops the script, unless your code catches it. Read the message: it tells you what went wrong and on which line. PHP แจ้งปัญหาได้สองแบบ warning จะถูกพิมพ์ออกมาแล้วสคริปต์ทำงานต่อ ส่วน error หรือ exception จะหยุดสคริปต์ เว้นแต่โค้ดของเราจะ catch ไว้ อ่านข้อความให้ดี มันบอกว่าเกิดอะไรขึ้นและอยู่บรรทัดไหน

You can throw exceptions yourself when something is not allowed, and catch them where you know how to respond. try runs the risky code, catch handles one kind of exception, and finally always runs. เราโยน exception เองได้เมื่อมีสิ่งที่ไม่อนุญาต และ catch ไว้ตรงจุดที่รู้ว่าจะรับมืออย่างไร try ครอบโค้ดที่อาจผิดพลาด catch จัดการ exception ชนิดที่ระบุ และ finally ทำงานเสมอ

You seeสิ่งที่เห็นScriptสคริปต์Usual causeสาเหตุที่พบบ่อย
Warningkeeps goingทำงานต่อundefined variable or array key, a file that can't be openedตัวแปรหรือคีย์ของอาร์เรย์ที่ไม่มีอยู่ ไฟล์ที่เปิดไม่ได้
Parse errornever startsไม่เริ่มทำงานเลยa typo in the code, often a missing ; or }พิมพ์โค้ดผิด มักเป็นการลืม ; หรือ }
Fatal error: Uncaught …stopsหยุดan exception or error that no catch handledexception หรือ error ที่ไม่มี catch รับไว้

Lesson 10 · The webบทที่ 10 · เว็บ

Forms & the webฟอร์มและเว็บ

When a browser asks for a page, the server runs the PHP file and sends back whatever it prints. Values in the URL (?name=Mya) arrive in the array $_GET; values from a form sent with method="post" arrive in $_POST. Anything a visitor sends can contain HTML, so escape it with htmlspecialchars before you print it. เมื่อเบราว์เซอร์ขอหน้าเว็บ เซิร์ฟเวอร์จะรันไฟล์ PHP แล้วส่งสิ่งที่ถูกพิมพ์ออกมากลับไป ค่าใน URL (?name=Mya) จะมาอยู่ในอาร์เรย์ $_GET ส่วนค่าจากฟอร์มที่ส่งด้วย method="post" จะมาอยู่ใน $_POST ทุกอย่างที่ผู้เข้าชมส่งมาอาจมี HTML ปนอยู่ จึงต้อง escape ด้วย htmlspecialchars ก่อนพิมพ์

Labs on this page have no real URL, so the first line pretends one. Change the name and press Run. แล็บในหน้านี้ไม่มี URL จริง บรรทัดแรกจึงจำลองค่าขึ้นมา ลองเปลี่ยนชื่อแล้วกด Run

After ?> you are back in HTML, and <?= $x ?> prints one value. In a browser the "unsafe" line would show Mya in bold: the visitor's HTML ran. With <script> instead of <b>, that's an attack called cross-site scripting (XSS). หลัง ?> เราจะกลับมาอยู่ใน HTML และ <?= $x ?> ใช้พิมพ์ค่าหนึ่งค่า ในเบราว์เซอร์ บรรทัด "ไม่ปลอดภัย" จะแสดง Mya เป็นตัวหนา แปลว่า HTML ของผู้เข้าชมทำงานแล้ว ถ้าเป็น <script> แทน <b> จะเป็นการโจมตีที่เรียกว่า cross-site scripting (XSS)

Try it with a real serverลองกับเซิร์ฟเวอร์จริง

PHP has a small web server built in. Put this file at public/index.php, start the server in one terminal, and send requests from another (or open the URL in your browser). PHP มีเว็บเซิร์ฟเวอร์ขนาดเล็กมาให้ในตัว วางไฟล์นี้ไว้ที่ public/index.php เปิดเซิร์ฟเวอร์ในเทอร์มินัลหนึ่ง แล้วส่งคำขอจากอีกเทอร์มินัลหนึ่ง (หรือเปิด URL ในเบราว์เซอร์)

Terminal 1 · serverเทอร์มินัล 1 · เซิร์ฟเวอร์PHP 8.3.33 · macOS
$ php -S 127.0.0.1:8000 -t public
[Mon Oct  5 22:22:15 2026] PHP 8.3.33 Development Server (http://127.0.0.1:8000) started
[Mon Oct  5 22:22:16 2026] 127.0.0.1:53491 Accepted
[Mon Oct  5 22:22:16 2026] 127.0.0.1:53491 [200]: GET /
[Mon Oct  5 22:22:16 2026] 127.0.0.1:53491 Closing
[Mon Oct  5 22:22:16 2026] 127.0.0.1:53492 Accepted
[Mon Oct  5 22:22:16 2026] 127.0.0.1:53492 [200]: GET /?name=Mya
[Mon Oct  5 22:22:16 2026] 127.0.0.1:53492 Closing
[Mon Oct  5 22:22:16 2026] 127.0.0.1:53493 Accepted
[Mon Oct  5 22:22:16 2026] 127.0.0.1:53493 [200]: GET /?name=%3Cb%3EMya%3C%2Fb%3E
[Mon Oct  5 22:22:16 2026] 127.0.0.1:53493 Closing
Terminal 2 · requestsเทอร์มินัล 2 · คำขอPHP 8.3.33 · macOS
$ curl "http://127.0.0.1:8000/?name=Mya"
<!doctype html>
<title>Greeter</title>
<form method="get">
  <input name="name" value="Mya">
  <button>Say hi</button>
</form>
  <p>Hello, Mya!</p>

$ curl "http://127.0.0.1:8000/?name=%3Cb%3EMya%3C%2Fb%3E"
<!doctype html>
<title>Greeter</title>
<form method="get">
  <input name="name" value="&lt;b&gt;Mya&lt;/b&gt;">
  <button>Say hi</button>
</form>
  <p>Hello, &lt;b&gt;Mya&lt;/b&gt;!</p>

The second request sends <b>Mya</b>. It comes back as &lt;b&gt;, so the browser shows it as text.คำขอที่สองส่ง <b>Mya</b> ไป และได้กลับมาเป็น &lt;b&gt; เบราว์เซอร์จึงแสดงเป็นข้อความ

Checking a POST formตรวจข้อมูลจากฟอร์มแบบ POST

Never trust form input. Check it on the server, collect the problems, and show them next to the form. This is the same idea Laravel's validation automates. อย่าไว้ใจข้อมูลจากฟอร์ม ให้ตรวจที่ฝั่งเซิร์ฟเวอร์ เก็บรายการปัญหา แล้วแสดงไว้ข้างฟอร์ม เป็นแนวคิดเดียวกับที่ระบบ validation ของ Laravel ทำให้อัตโนมัติ

Lesson 11 · Storing dataบทที่ 11 · การเก็บข้อมูล

Databases with PDOฐานข้อมูลด้วย PDO

PDO is PHP's built-in way to talk to SQLite, MySQL, PostgreSQL and more, with the same methods for each. The examples use SQLite in memory, which needs no server. The important habit: send values separately from the SQL with prepared statements. PDO คือวิธีมาตรฐานของ PHP สำหรับคุยกับ SQLite, MySQL, PostgreSQL และอื่นๆ ด้วย method ชุดเดียวกัน ตัวอย่างใช้ SQLite ในหน่วยความจำซึ่งไม่ต้องมีเซิร์ฟเวอร์ นิสัยสำคัญคือส่งค่าแยกจาก SQL ด้วย prepared statement

Why bother with placeholders? Because the value is never pasted into the SQL text. Watch what happens to a title written to break the query: ทำไมต้องใช้ตัวแทนค่า? เพราะค่าจะไม่ถูกนำไปต่อกับข้อความ SQL ดูว่าจะเกิดอะไรขึ้นกับชื่องานที่ตั้งใจเขียนมาเพื่อทำลายคิวรี

Codeโค้ดDoesทำอะไร
new PDO("sqlite:app.db")connect to a SQLite fileเชื่อมต่อไฟล์ SQLite
new PDO("mysql:host=127.0.0.1;dbname=shop", $user, $pass)connect to MySQLเชื่อมต่อ MySQL
$pdo->prepare($sql)SQL with ? or :name placeholdersSQL ที่มีตัวแทนค่า ? หรือ :name
$stmt->execute([...])run it with the real valuesรันพร้อมค่าจริง
$stmt->fetch(PDO::FETCH_ASSOC)the next row as an arrayแถวถัดไปในรูปอาร์เรย์
$stmt->fetchAll(PDO::FETCH_ASSOC)every rowทุกแถว
Neverห้าม

Never build SQL by joining user input: "... WHERE name = '$name'" lets a visitor rewrite your query. Always use prepare() with placeholders.ห้ามสร้าง SQL ด้วยการต่อข้อมูลจากผู้ใช้ เช่น "... WHERE name = '$name'" เพราะเปิดโอกาสให้ผู้เข้าชมเขียนคิวรีของเราใหม่ได้ ให้ใช้ prepare() กับตัวแทนค่าเสมอ

Lesson 12 · Confidenceบทที่ 12 · ความมั่นใจ

Testing with PHPUnitทดสอบด้วย PHPUnit

A test is code that runs your code and checks the answer, so you don't have to check by hand every time you change something. Here is the whole idea in a few lines. Break addVat on purpose and press Run. เทสต์คือโค้ดที่รันโค้ดของเราแล้วตรวจคำตอบ เราจึงไม่ต้องตรวจเองทุกครั้งที่แก้อะไร นี่คือแนวคิดทั้งหมดในไม่กี่บรรทัด ลองทำให้ addVat ผิดโดยตั้งใจ แล้วกด Run

Real projects use PHPUnit, installed with Composer, PHP's package manager. The rest of this lesson ran in a real terminal. The class under test is a BankAccount like the one in lesson 8, with a rule: you can't withdraw more than you have. โปรเจกต์จริงใช้ PHPUnit ซึ่งติดตั้งด้วย Composer ตัวจัดการแพ็กเกจของ PHP ส่วนที่เหลือของบทนี้รันในเทอร์มินัลจริง คลาสที่ถูกทดสอบคือ BankAccount แบบเดียวกับบทที่ 8 โดยมีกฎว่าห้ามถอนเงินเกินยอดที่มี

1. Install PHPUnit1. ติดตั้ง PHPUnit

Terminalเทอร์มินัลPHP 8.3.33 · macOS
$ composer require --dev phpunit/phpunit
Cannot use phpunit/phpunit's latest version 13.4.1 as it requires php >=8.4.1 which is not satisfied by your platform.
./composer.json has been updated
Running composer update phpunit/phpunit
Loading composer repositories with package information
Updating dependencies
Lock file operations: 25 installs, 0 updates, 0 removals
  - Locking myclabs/deep-copy (1.14.0)
⋯ 50 lines of package installs ⋯
  - Installing myclabs/deep-copy (1.14.0): Extracting archive
  - Installing phpunit/phpunit (12.5.38): Extracting archive
2 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
23 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found.
Using version ^12.5 for phpunit/phpunit

The first line matters: PHPUnit 13 needs PHP 8.4, so on PHP 8.3 Composer picks PHPUnit 12.5 by itself.บรรทัดแรกสำคัญ: PHPUnit 13 ต้องใช้ PHP 8.4 บน PHP 8.3 Composer จึงเลือก PHPUnit 12.5 ให้เอง

2. Write the test2. เขียนเทสต์

  • Every public method whose name starts with test is one test.ทุก public method ที่ชื่อขึ้นต้นด้วย test คือหนึ่งเทสต์
  • Each test has three parts, separated by blank lines: arrange (set up), act (do the thing), assert (check).แต่ละเทสต์มีสามส่วน คั่นด้วยบรรทัดว่าง: arrange (เตรียม) act (ลงมือทำ) assert (ตรวจผล)
  • assertSame compares like ===. expectException says "the next code must throw".assertSame เปรียบเทียบแบบ === ส่วน expectException บอกว่า "โค้ดถัดไปต้องโยน exception"

3. Red: a bug is caught3. แดง: จับบั๊กได้

To show what failure looks like, I changed one character in withdraw(): >= instead of >. Now withdrawing your whole balance is refused, and the second test catches it. เพื่อให้เห็นว่าความล้มเหลวหน้าตาเป็นอย่างไร ผมเปลี่ยนตัวอักษรเดียวใน withdraw() คือใช้ >= แทน > ตอนนี้การถอนเงินทั้งหมดจะถูกปฏิเสธ และเทสต์ที่สองจับได้

Run 1 · with the bugรันครั้งที่ 1 · มีบั๊กPHP 8.3.33 · macOS
$ vendor/bin/phpunit --testdox
PHPUnit 12.5.38 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.3.33
Configuration: ~/php-guide/phpunit.xml

.E..                                                                4 / 4 (100%)

Time: 00:00.001, Memory: 14.00 MB

Bank Account
 ✔ Deposit adds to the balance
 ✘ Can withdraw the whole balance
   ┐
   ├ RuntimeException: Not enough money
   │
   │ ~/php-guide/src/BankAccount.php:23
   │ ~/php-guide/tests/BankAccountTest.php:22
   ┴
 ✔ Cannot withdraw more than the balance
 ✔ Deposit must be more than zero

ERRORS!
Tests: 4, Assertions: 4, Errors: 1.

E means a test crashed with an exception it didn't expect; F would mean an assertion failed. The output points at BankAccount.php:23, where the exception was thrown, and at the test line that called it. Folder paths are shortened to ~/php-guide.E หมายถึงเทสต์พังเพราะ exception ที่ไม่ได้คาดไว้ ส่วน F หมายถึง assertion ไม่ผ่าน ผลลัพธ์ชี้ไปที่ BankAccount.php:23 ซึ่งเป็นจุดที่ exception ถูกโยน และบรรทัดในเทสต์ที่เรียกมัน พาธโฟลเดอร์ถูกย่อเป็น ~/php-guide

4. Green: fix and run again4. เขียว: แก้แล้วรันอีกครั้ง

Run 2 · after changing >= back to >รันครั้งที่ 2 · หลังเปลี่ยน >= กลับเป็น >PHP 8.3.33 · macOS
$ vendor/bin/phpunit --testdox
PHPUnit 12.5.38 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.3.33
Configuration: ~/php-guide/phpunit.xml

....                                                                4 / 4 (100%)

Time: 00:00, Memory: 14.00 MB

Bank Account
 ✔ Deposit adds to the balance
 ✔ Can withdraw the whole balance
 ✔ Cannot withdraw more than the balance
 ✔ Deposit must be more than zero

OK (4 tests, 5 assertions)
Habitนิสัยที่ดี

Red, then green. Watching a test fail once proves it can catch the bug it's written for. Keep your tests and run them before every change you ship.แดงก่อน แล้วค่อยเขียว การเห็นเทสต์ล้มเหลวหนึ่งครั้งพิสูจน์ว่ามันจับบั๊กที่ตั้งใจไว้ได้จริง เก็บเทสต์ไว้ และรันทุกครั้งก่อนปล่อยการเปลี่ยนแปลง

Lesson 13 · Your turnบทที่ 13 · ถึงตาคุณแล้ว

Practiceแบบฝึกหัด

Write the code, press Run, and compare with the solution when you're done. Every solution was run with PHP 8.3.33, and its output is shown under it. เขียนโค้ด กด Run แล้วเทียบกับเฉลยเมื่อเสร็จ ทุกเฉลยถูกรันด้วย PHP 8.3.33 และแสดงผลลัพธ์ไว้ด้านล่าง

1. Total of the even numbers1. ผลรวมของเลขคู่

Add up only the even numbers in the array. Hint: $n % 2 === 0 is true for even numbers.รวมเฉพาะเลขคู่ในอาร์เรย์ คำใบ้: $n % 2 === 0 เป็นจริงเมื่อ $n เป็นเลขคู่

2. A receipt with VAT2. ใบเสร็จพร้อม VAT

Print each item with its price, then the subtotal, 7% VAT and the total. Use number_format($x, 2) for money.พิมพ์สินค้าแต่ละรายการพร้อมราคา แล้วตามด้วยยอดรวมก่อนภาษี VAT 7% และยอดสุทธิ ใช้ number_format($x, 2) กับจำนวนเงิน

3. FizzBuzz3. FizzBuzz

For 1 to 15, print Fizz for multiples of 3, Buzz for multiples of 5, FizzBuzz for both, and the number otherwise. Hint: match (true) works well here.สำหรับเลข 1 ถึง 15 ให้พิมพ์ Fizz เมื่อหารด้วย 3 ลงตัว Buzz เมื่อหารด้วย 5 ลงตัว FizzBuzz เมื่อหารลงตัวทั้งคู่ และพิมพ์ตัวเลขในกรณีอื่น คำใบ้: match (true) ใช้ได้ดีมากที่นี่

4. Grade report4. รายงานเกรด

Write a function grade(int $score): string that returns A (80+), B (60+) or C, then print every student with their grade.เขียนฟังก์ชัน grade(int $score): string ที่คืน A (80 ขึ้นไป) B (60 ขึ้นไป) หรือ C แล้วพิมพ์นักเรียนทุกคนพร้อมเกรด

5. Longest word5. คำที่ยาวที่สุด

Split the sentence into words with explode(" ", $text), print how many words there are, and find the longest one.แยกประโยคเป็นคำด้วย explode(" ", $text) พิมพ์จำนวนคำ แล้วหาคำที่ยาวที่สุด

Lesson 14 · Debuggingบทที่ 14 · การดีบัก

Common mistakesข้อผิดพลาดที่พบบ่อย

Every PHP beginner meets these. The comments show what PHP really prints; each one was checked on PHP 8.3.33. มือใหม่ PHP ทุกคนต้องเจอสิ่งเหล่านี้ คอมเมนต์แสดงสิ่งที่ PHP พิมพ์ออกมาจริง และทุกข้อตรวจกับ PHP 8.3.33 แล้ว

A missing semicolonลืมเซมิโคลอน

PHP reports the error on the line after the missing ;, because that's where it noticed. When a parse error points at a line that looks fine, check the line above.PHP แจ้งข้อผิดพลาดที่บรรทัดถัดจากจุดที่ลืม ; เพราะเป็นจุดที่มันเพิ่งสังเกตเห็น ถ้า parse error ชี้ไปที่บรรทัดที่ดูไม่มีอะไรผิด ให้ดูบรรทัดก่อนหน้า

✗ Wrong✗ ผิด
✓ Right✓ ถูก

One = inside ifใช้ = ตัวเดียวใน if

= stores a value, and a non-empty string counts as true, so this "check" lets everyone in.= คือการเก็บค่า และข้อความที่ไม่ว่างนับเป็นจริง "การตรวจ" นี้จึงปล่อยให้ทุกคนผ่าน

✗ Wrong✗ ผิด
✓ Right✓ ถูก

Variables inside single quotesตัวแปรในเครื่องหมายคำพูดเดี่ยว

Only double quotes fill in variables.มีแต่เครื่องหมายคำพูดคู่เท่านั้นที่แทนค่าตัวแปร

✗ Wrong✗ ผิด
✓ Right✓ ถูก

Expecting sort() to return the sorted arrayคิดว่า sort() คืนอาร์เรย์ที่เรียงแล้ว

sort() changes the array you pass in and returns true.sort() เปลี่ยนอาร์เรย์ที่ส่งเข้าไปโดยตรง และคืนค่า true

✗ Wrong✗ ผิด
✓ Right✓ ถูก

array_filter keeps the old keysarray_filter เก็บคีย์เดิมไว้

After filtering, the first item may not be at key 0. Wrap the result in array_values() to number it from 0 again.หลังกรองแล้ว สมาชิกตัวแรกอาจไม่ได้อยู่ที่คีย์ 0 ให้ครอบผลลัพธ์ด้วย array_values() เพื่อเรียงหมายเลขใหม่ตั้งแต่ 0

✗ Wrong✗ ผิด
✓ Right✓ ถูก

Reading form input that might not be thereอ่านค่าจากฟอร์มที่อาจไม่มีอยู่

On the first visit there is no ?name= in the URL. Give every input a fallback with ??.การเข้าครั้งแรกยังไม่มี ?name= ใน URL ให้ใส่ค่าสำรองให้ทุกค่าที่รับเข้ามาด้วย ??

✗ Wrong✗ ผิด
✓ Right✓ ถูก

Lesson 15 · Referenceบทที่ 15 · อ้างอิง

Glossaryคำศัพท์

The English terms are what you'll see in the PHP manual, error messages and search results, so it pays to know both. คำศัพท์ภาษาอังกฤษคือสิ่งที่จะเจอในคู่มือ PHP ข้อความแจ้งข้อผิดพลาด และผลการค้นหา จึงควรรู้ทั้งสองภาษา

EnglishไทยMeaningความหมาย
variableตัวแปรA named box for a value, written with $กล่องที่มีชื่อสำหรับเก็บค่า เขียนด้วย $
stringสตริง / ข้อความText inside quotesข้อความที่อยู่ในเครื่องหมายคำพูด
interpolationการแทนค่าในข้อความVariables filled into "double quoted" textการแทนค่าตัวแปรในข้อความที่อยู่ใน "เครื่องหมายคำพูดคู่"
arrayอาร์เรย์Many values under one name, by number or text keyหลายค่าในชื่อเดียว อ้างอิงด้วยคีย์ที่เป็นตัวเลขหรือข้อความ
keyคีย์The name or number that finds a value in an arrayชื่อหรือตัวเลขที่ใช้หาค่าในอาร์เรย์
functionฟังก์ชันA named, reusable block of codeบล็อกโค้ดที่มีชื่อและเรียกใช้ซ้ำได้
parameter / argumentพารามิเตอร์ / อาร์กิวเมนต์The input name in a definition / the value passed in a callชื่อข้อมูลขาเข้าในการประกาศ / ค่าที่ส่งเข้าไปตอนเรียกใช้
type declarationการระบุชนิดint, string… written before a parameter or after ):int, string… ที่เขียนหน้าพารามิเตอร์หรือหลัง ):
class / objectคลาส / ออบเจกต์A blueprint / one thing made from it with newแม่แบบ / สิ่งหนึ่งที่สร้างจากแม่แบบด้วย new
property / methodพร็อพเพอร์ตี / เมธอดData inside an object / a function inside a classข้อมูลในออบเจกต์ / ฟังก์ชันในคลาส
exceptionexception / ข้อยกเว้นAn error object you can throw and catchออบเจกต์ข้อผิดพลาดที่ throw และ catch ได้
superglobalตัวแปร superglobalBuilt-in arrays like $_GET, $_POST, $_SERVERอาร์เรย์ในตัว เช่น $_GET, $_POST, $_SERVER
escapingการ escapeTurning special characters into safe ones, e.g. < → &lt;การแปลงอักขระพิเศษให้ปลอดภัย เช่น < → &lt;
prepared statementprepared statementSQL with placeholders, values sent separatelySQL ที่มีตัวแทนค่า โดยส่งค่าแยกต่างหาก
ComposerComposerPHP's package managerตัวจัดการแพ็กเกจของ PHP
assertionการยืนยันผล (assertion)A check inside a test, like assertSameการตรวจผลในเทสต์ เช่น assertSame