📘 Chapter 9: PHP Working with Form

Lesson Plan — Objectives → Explain → Demo → Practice → Quiz → Mini Project

1

ជំហានទី 1: Form Review

💡 Concept

Form គឺជាផ្នែកខាងមុខ (frontend) ដែលអ្នកប្រើប្រាស់បញ្ចូលទិន្នន័យ។

  • Form ប្រមូលទិន្នន័យ (input) រួចផ្ញើទៅ Server ដើម្បី PHP ដំណើរការ
  • <form action="result.php" method="post"> — កំណត់ទិសដៅ និង method
  • action = ផ្ញើទៅ PHP file មួយណា | method = GET / POST

📝 Code

<form action="result.php" method="post">
    <input type="text" name="fname">
    <input type="submit" value="Send">
</form>

🖥 Output

result.php:

<?php
echo "Name: " . htmlspecialchars($_POST['fname']);
?>

➡ User types "Sophal" → Output: Name: Sophal

🏋 Practice

Create a simple form with fname and lname fields. Submit to result.php and display "Hello, [fname] [lname]!"

2

ជំហានទី 2: Form Element

💡 Concept

Input Types

  • type="text" — បញ្ចូលអក្សរ
  • type="email" — បញ្ចូល email
  • type="password" — លាក់អក្សរ
  • type="file" — upload ឯកសារ
  • type="checkbox" — ជ្រើសច្រើន
  • type="radio" — ជ្រើសមួយ
  • type="submit" — ប៊ូតុងផ្ញើ

Other Elements

  • <textarea> — text ច្រើនជួរ
  • <select> + <option> — dropdown
  • name="" — សម្រាប់ PHP ទទួល
  • value="" — តម្លៃដែលផ្ញើទៅ

📝 Code — Group Related Form Element (fieldset + legend)

ប្រើ

ដើម្បី group Form elements និង ដើម្បីដាក់ចំណង់ជើងក្រុម។ ឧទាហរណ៍ Group Step1/Step2/Step3

<form action="result.php" method="post">
  <fieldset>
    <legend>Step1: Personal Information</legend>
    <input type="text" name="fname" size="30">
    <input type="text" name="lname" size="30">
    <input type="text" name="mail"  size="30">
  </fieldset>

  <fieldset>
    <legend>Step2: Your Favorite</legend>
    <input type="radio" name="like" value="Coke"> Coke
    <input type="radio" name="like" value="Pepsi"> Pepsi
    <input type="checkbox" name="skills[]" value="HTML"> HTML
    <input type="checkbox" name="skills[]" value="CSS"> CSS
    <select name="how">
      <option value="Google">Google</option>
      <option value="Friend">Friend</option>
    </select>
  </fieldset>

  <fieldset>
    <legend>Step3: Submit</legend>
    <textarea name="comments" rows="4" cols="40"></textarea>
    <input type="submit" value="Send">
  </fieldset>
</form>

🏋 Practice

Create a form with 3 fieldsets: Personal Info (name, email), Preferences (radio + checkbox + select), and Submit (textarea + button).

3

ជំហានទី 3: Form Method (GET vs POST)

💡 Concept

Feature GET POST
ទិន្នន័យបង្ហាញក្នុង URLលាក់ក្នុង HTTP body
ទំហំមានកំណត់ (~2048 chars)គ្មានកំណត់
សុវត្ថិភាពទាប (ឃើញក្នុង URL)ខ្ពស់ជាង
PHP Variable$_GET['key']$_POST['key']
ប្រើសម្រាប់Search, FilterLogin, Form Submit

⚠️ ណែនាំ: ប្រើ $_POST ឬ $_GET ឲ្យជាក់លាក់។ ជៀសវាង $_REQUEST!

📝 Code

GET Method:

<!-- form_get.php -->
<form action="result.php" method="get">
  Name: <input type="text" name="name">
  <input type="submit">
</form>

<!-- result.php -->
<?php
// URL: result.php?name=Sophal
echo $_GET['name'];
?>

POST Method:

<!-- form_post.php -->
<form action="result.php" method="post">
  Name: <input type="text" name="name">
  <input type="submit">
</form>

<!-- result.php -->
<?php
// data hidden in body
echo $_POST['name'];
?>

🏋 Practice

Create 2 forms: one using GET (search box) and one using POST (login form). Observe the URL difference after submit.

4

ជំហានទី 4: Using Array as Form Value

💡 Concept

ប្រើ name="skills[]" ដើម្បីផ្ញើតម្លៃច្រើនជា array។ PHP ទទួលជា $_POST['skills'] ជា indexed array រួច loop ដោយ foreach។

📝 Code

HTML (form.php):

<label>Select your skills:</label>
<input type="checkbox"
  name="skills[]" value="HTML"> HTML
<input type="checkbox"
  name="skills[]" value="CSS"> CSS
<input type="checkbox"
  name="skills[]" value="JavaScript"> JS
<input type="checkbox"
  name="skills[]" value="PHP"> PHP
<input type="checkbox"
  name="skills[]" value="MySQL"> MySQL

PHP (result.php):

<?php
$skills = $_POST['skills'] ?? [];

if (!empty($skills)) {
    echo "Your skills:<ul>";
    foreach ($skills as $skill) {
        $safe = htmlspecialchars($skill);
        echo "<li>$safe</li>";
    }
    echo "</ul>";
} else {
    echo "No skills selected.";
}
?>

🖥 Output

User checks: HTML, PHP, MySQL →

Your skills:
  • HTML
  • PHP
  • MySQL

🏋 Practice

Create a form with hobbies[] checkboxes (5 options). Display selected hobbies using foreach. Count total selected with count().

5

ជំហានទី 5: Validating Form With PHP (check_input)

💡 Concept

Sanitize = Clean up user input before display/storage to prevent XSS attacks.

  • trim() — កាត់ space ដើម/ចុង
  • stripslashes() — ដក backslash
  • htmlspecialchars() — ការពារ XSS

📝 Code

// Sanitization function
function check_input(string $data): string {
    $data = trim($data);            // Remove whitespace
    $data = stripslashes($data);    // Remove backslashes
    $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
    return $data;                   // Prevent XSS
}

// Usage:
$name    = check_input($_POST['fname']    ?? '');
$email   = check_input($_POST['email']    ?? '');
$comment = check_input($_POST['comments'] ?? '');

echo "Name: $name <br>";
echo "Email: $email <br>";
echo "Comment: $comment";

🖥 Output

User inputs: <script>alert('xss')</script>

➡ After check_input(): &lt;script&gt;alert('xss')&lt;/script&gt;

✅ XSS prevented! Script displayed as text, not executed.

🏋 Practice

Create check_input() function. Test by entering <b>Hello</b> and <script>alert(1)</script>. Verify output is safe text.

6

ជំហានទី 6: Required/Optional + Validate Email & URL

💡 Concept

Required Fields

Required: Check with empty(). If empty, show error.

ប្រើ filter_var($email, FILTER_VALIDATE_EMAIL)

Optional Fields

Optional: Validate only if user fills the field.

ប្រើ filter_var($url, FILTER_VALIDATE_URL)

📝 Code

$errors = [];

// === Required: Full Name ===
if (empty($fullname)) {
    $errors[] = "Full Name is required.";
}

// === Required: Email (must be valid) ===
if (empty($email)) {
    $errors[] = "Email is required.";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $errors[] = "Invalid email format.";
}

// === Optional: Website (validate only if filled) ===
if (!empty($website)) {
    if (!filter_var($website, FILTER_VALIDATE_URL)) {
        $errors[] = "Invalid URL format.";
    }
}

// === Required: Comments (min 10 chars) ===
if (empty($comments)) {
    $errors[] = "Comments is required.";
} elseif (mb_strlen($comments) < 10) {
    $errors[] = "Comments must be at least 10 characters.";
}

// Show errors
if (!empty($errors)) {
    foreach ($errors as $e) {
        echo "<p style='color:red'>$e</p>";
    }
}

🏋 Practice

Create a form with: Name (required), Email (required + validate), Phone (optional), Website (optional + validate URL). Display error messages in red for invalid inputs.

7

ជំហានទី 7: PHP Upload Files

💡 Concept

  • ត្រូវប្រើ enctype="multipart/form-data"
  • ប្រើ $_FILES ដើម្បីទទួលឯកសារ
  • ពិនិត្យ MIME type + extension + size
  • ប្ដូរអះមំ (timestamp + random) ដើម្បីសុវត្ថិភាព
  • ប្រើ move_uploaded_file() ដើម្បីផ្លាស់ប្តូរឯកសារ

$_FILES['file'] array keys:

  • ['name'] — Original filename
  • ['type'] — MIME type (browser-reported)
  • ['tmp_name'] — Temporary path on server
  • ['error'] — Error code (0 = OK)
  • ['size'] — File size in bytes

📝 Code

<!-- HTML: enctype is REQUIRED for upload -->
<form method="post" enctype="multipart/form-data">
  <input type="file" name="attachment">
  <input type="submit" value="Upload">
</form>

<?php
if ($_FILES['attachment']['error'] === UPLOAD_ERR_OK) {

    // 1) Check MIME type (server-side, not browser)
    $allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];
    $fileType = mime_content_type($_FILES['attachment']['tmp_name']);

    // 2) Check extension
    $allowedExts = ['jpg', 'jpeg', 'png', 'pdf'];
    $ext = strtolower(pathinfo($_FILES['attachment']['name'], PATHINFO_EXTENSION));

    // 3) Check size (max 2MB)
    $maxSize = 2 * 1024 * 1024;

    if (in_array($fileType, $allowedTypes)
        && in_array($ext, $allowedExts)
        && $_FILES['attachment']['size'] <= $maxSize) {

        // 4) Rename file for security
        $newName = time() . '_' . mt_rand(1000, 9999) . '.' . $ext;

        // 5) Move to uploads folder
        move_uploaded_file(
            $_FILES['attachment']['tmp_name'],
            'uploads/' . $newName
        );
        echo "Uploaded: $newName";
    } else {
        echo "Invalid file type or too large!";
    }
}
?>

🏋 Practice

Create a file upload form. Allow only .jpg and .png (max 1MB). Display the uploaded image using <img> tag after upload.

8

ជំហានទី 8: Redirecting with header()

💡 Concept

ប្រើ header("Location: thanks.htm") ដើម្បី redirect។ ត្រូវ exit() ជានិច្ចបន្ទាប់ពី header()!

⚠️ សំខាន់: កុំ output (echo/HTML) មុនពេលហៅ header() អះភាស ដ org org org org orgវាមិនដំណើរការ!

📝 Code

<?php
// Process form data first...
// Then redirect:

header("Location: thanks.htm");
exit();  // IMPORTANT: always exit() after header()!

// ❌ WRONG - output before header:
// echo "Processing...";    // <-- This causes error
// header("Location: ...");  // <-- Headers already sent!
?>

🖥 Output

form.php process.php thanks.htm

User submits form → PHP validates → redirects to thank-you page

🏋 Practice

Create login.phpcheck.phpwelcome.htm. If username = "admin" and password = "1234", redirect to welcome.htm. Otherwise, redirect back to login.php.

🚀 Case Study: Contact Form Mini Project

Contact Form + Validation + Upload + Redirect

form.php process.php thanks.htm

🖥 Output

❌ បើមាន Error

  • Error messages ពណ៌ក្រហម
  • រក្សា values ចាស់ (sticky form)
  • File field reset

✅ បើជោគជ័យ

  • File uploaded ជោគជ័យ
  • Redirect ទៅ thanks.htm
  • បង្ហាញសារអរគុណ

📁 Upload

  • រក្សាទុកក្នុង /uploads/
  • អះមំថ្មី: timestamp + random
  • ប្រភេទ: jpg, png, pdf

🏋 Practice — បំពេញ Form ខាងក្រោម → Submit → សង្កេត Error / Success

  • សាកល្បង submit ដោយគ្មានបំពេញ Full Name → មើល error
  • បញ្ចូល email មិនត្រឹមត្រូវ → មើល validation error
  • បញ្ចូល Website URL មិនត្រឹមត្រូវ → មើល error
  • ជ្រើស Skills checkbox ច្រើន → មើល output ជា list
  • Upload file .txt (មិនអនុញ្ញាត) → មើល error
  • បំពេញត្រឹមត្រូវគ្រប់វាល → Redirect ទៅ thanks.htm

📬 Contact Form

👤 Step1: Personal Information
✉️ Step2: Message Details
🛠️ Step3: Skills (optional — skills[])
📎 Step4: Attachment (optional)

* វាលដែលចាំបាច់