Chapterبەش 8 · Lectureوانە 8.3

Form Validationپشتڕاستکردنەوەی فۆرم

Check form data before you use it: client-side vs server-side validation, required fields with isset() and empty(), drop-down lists, radio buttons and checkboxes, format checks for length, digits and e-mail, and three student answers to debug.

زانیاریی پێش بەکارهێنان بپشکنە: و لای ، بە isset() و empty()، ، و ، پشکنینی درێژی، ژمارە و شێوەی و سێ وەڵامی خوێندکاران بۆ دۆزینەوەی باگ.

23 min read21 خولەک خوێندنەوە · 18 stepsهەنگاو

What you will learnچی فێر دەبیت

  • Explain why client-side validation is not secure and server-side validation is always needed.
  • Check required fields with isset(), empty() and trim(), and know their traps.
  • Read and check drop-down lists, radio buttons and checkboxes correctly.
  • Check length, digits and e-mail format with built-in functions.
  • Find and fix typical validation bugs in real student code.
  • ڕوون بکەیتەوە بۆچی سەلامەت نییە و هەمیشە پێویستە.
  • بە isset() و empty() و trim() بپشکنیت و داوەکانیان بناسیت.
  • ، و بە دروستی بخوێنیتەوە و بپشکنیت.
  • درێژی، ژمارە و شێوەی بە بپشکنیت.
  • باوەکانی لە کۆدی ڕاستەقینەی خوێندکاراندا بدۆزیتەوە و چاکیان بکەیتەوە.

Why validate form data?بۆچی زانیاریی فۆرم پشتڕاست دەکەینەوە؟

In the last lecture, PHP received whatever the user sent. But users make mistakes — they forget a field, type a name in the e-mail box, or choose nothing. And some visitors send wrong data on purpose. Before your program uses form data, it must check it. This checking is called .

لە وانەی پێشوودا، PHP هەر شتێکی وەردەگرت کە ناردبووی. بەڵام هەڵە دەکەن — خانەیەک لەبیر دەکەن، ناوێک لە سندووقی دەنووسن، یان هیچ هەڵنابژێرن. هەندێک سەردانکەریش بە ئەنقەست زانیاریی نادروست دەنێرن. پێش ئەوەی زانیاریی بەکاربهێنێت، دەبێت بیپشکنێت. ئەم پشکنینە پێی دەوترێت .

Definitionپێناسە

Checking that is complete and correct before using it, for example that a number is in range or that a required field is not empty. In web forms it must always be done on the server.

پشکنینی ئەوەی تەواو و دروستە پێش بەکارهێنانی، بۆ نموونە ئەوەی ژمارەیەک لە سنووری خۆیدایە یان خانەیەکی پێویست بەتاڵ نییە. لە فۆرمەکانی وێبدا هەمیشە دەبێت لەسەر ڕاژەکار بکرێت.

Typical checks are: is a filled in? Does the e-mail address look like an e-mail address? Is the password long enough? Is the chosen value one of the allowed choices? If a check fails, the page shows a clear message and lets the user try again.

پشکنینە باوەکان ئەمانەن: ئایا پڕ کراوەتەوە؟ ئایا لە دەچێت؟ ئایا بەس درێژە؟ ئایا هەڵبژێردراوەکە یەکێکە لە هەڵبژاردنە ڕێگەپێدراوەکان؟ ئەگەر پشکنینێک سەرنەکەوت، لاپەڕەکە پەیامێکی ڕوون پیشان دەدات و ڕێگە بە دەدات دووبارە هەوڵ بداتەوە.

Client-side or server-side validation?پشتڕاستکردنەوە لای ڕاژەخواز یان لای ڕاژەکار؟

Validation can be done in three ways:

دەتوانرێت بە سێ شێوە ئەنجام بدرێت:

Three ways to validateسێ ڕێگای
Whereلە کوێWhenکەیGoodباشBadخراپ
(in the browser: HTML attributes, JavaScript) (لە : HTML، JavaScript)Before the form is submittedپێش ناردنی A better user experience: instant messages, no waiting for the serverئەزموونێکی باشتر بۆ : پەیامی دەستبەجێ، بێ چاوەڕوانیی Not secure: it can easily be changed or skippedسەلامەت نییە: بە ئاسانی دەگۆڕدرێت یان بازی لێ دەدرێت
(in PHP) (لە PHPـدا)After the form is submittedدوای ناردنی Needed for truly secure validation; it protects the correctness of your data against harmful inputبۆ بەڕاستی سەلامەت پێویستە؛ دروستیی زانیارییەکانت لە نێوخستەی زیانبەخش دەپارێزێتSlower: the page must travel to the server and back; needs more codeهێواشترە: لاپەڕەکە دەبێت بچێت بۆ و بگەڕێتەوە؛ کۆدی زیاتری دەوێت
BothهەردووکیانBefore and afterپێش و دوای ناردنThe best mix of comfort and securityباشترین تێکەڵەی ئاسانکاری و Requires the most effort to programزۆرترین ماندووبوونی دەوێت
Two zones. In the browser, which the user controls, a normal user fills in the form and client-side validation (the required attribute, type="email", JavaScript) gives instant feedback but can be switched off or skipped. An attacker skips the browser checks by switching off JavaScript, editing the HTML with the developer tools, or sending the request directly with no form. Both the normal request and the attacker's request reach the server, which you control, where server-side validation in PHP (isset(), empty(), trim(), filter_var()) checks every request. If the data is not valid, the form is shown again with error messages; if it is valid, the data is used. Best: do both — the browser check is for comfort, the PHP check is for security.دوو بەش. لە تۆڕگەڕدا، کە بەکارهێنەر کۆنترۆڵی دەکات، بەکارهێنەرێکی ئاسایی فۆرمەکە پڕ دەکاتەوە و پشتڕاستکردنەوەی لای ڕاژەخواز (خەسڵەتی required، type="email"، JavaScript) دەستبەجێ وەڵام دەداتەوە، بەڵام دەتوانرێت ناچالاک بکرێت یان بازی لێ بدرێت. هێرشبەرێک پشکنینەکانی تۆڕگەڕ بازدەدات: JavaScript ناچالاک دەکات، HTMLـەکە بە ئامرازەکانی گەشەپێدەر دەگۆڕێت، یان داواکارییەکە ڕاستەوخۆ بەبێ فۆرم دەنێرێت. هەم داواکاریی ئاسایی و هەم داواکاریی هێرشبەرەکە دەگەنە ڕاژەکار، کە تۆ کۆنترۆڵی دەکەیت و لەوێ پشتڕاستکردنەوەی لای ڕاژەکار لە PHPـدا (isset()، empty()، trim()، filter_var()) هەموو داواکارییەک دەپشکنێت. ئەگەر زانیارییەکان دروست نەبوون، فۆرمەکە لەگەڵ هەڵەنامەکان دووبارە پیشان دەدرێتەوە؛ ئەگەر دروست بوون، بەکار دەهێنرێن. باشترین: هەردووکیان — پشکنینی تۆڕگەڕ بۆ ئاسانکارییە، پشکنینی PHP بۆ ئاسایشە.
Browser checks can be skipped; PHP checks cannotپشکنینی بازی لێ دەدرێت؛ پشکنینی PHP ناCêIT
Counting the money at the bazaarژماردنی پارە لە بازاڕ

At the bazaar in Sulaymaniyah, a customer counts his money before he pays. That is helpful — it saves time at the counter. But the shopkeeper still counts the money again himself, because a customer can make a mistake, or try to cheat. Client-side validation is the customer counting; server-side validation is the shopkeeper counting. A shop that trusts the customer's counting alone will soon lose money.

لە بازاڕی سلێمانی، کڕیارێک پێش پارەدان پارەکەی دەژمێرێت. ئەمە بەسوودە — لە لای پارەدان کات دەپارێزێت. بەڵام دووکاندارەکە هەر خۆی دووبارە پارەکە دەژمێرێتەوە، چونکە کڕیار دەتوانێت هەڵە بکات، یان هەوڵی فێڵ بدات. ژماردنی کڕیارەکەیە؛ ژماردنی دووکاندارەکەیە. دووکانێک کە تەنها متمانە بە ژماردنی کڕیار بکات، زوو پارە لەدەست دەدات.

Where the analogy stops workingسنووری ئەم نموونەیە

A shopkeeper can see the customer. A server never sees who sent a request — it only sees the data, so it must check every request.

دووکاندار کڕیارەکە دەبینێت. بەڵام هەرگیز نابینێت کێ ناردووە — تەنها زانیارییەکان دەبینێت، بۆیە دەبێت هەموو بپشکنێت.

Client-side or server-side validation?پشتڕاستکردنەوە لای ڕاژەخواز یان لای ڕاژەکار؟

Why is client-side validation not secure?بۆچی پشتڕاستکردنەوەی لای ڕاژەخواز سەلامەت نییە؟

The slide asks "why not?" and leaves the question open. The answer: client-side checks run on the visitor's own device, so the visitor controls them. A person with bad intentions can manipulate them on their device:

دەپرسێت «بۆچی نا؟» و پرسیارەکە بێ وەڵام بەجێدەهێڵێت. وەڵامەکە: پشکنینەکانی لەسەر ئامێری خودی سەردانکەرەکە کار دەکەن، بۆیە سەردانکەر کۆنترۆڵیان دەکات. کەسێکی خراپ دەتوانێت لەسەر ئامێرەکەی خۆی دەستکارییان بکات:

  • switch off JavaScript in the browser settings;
  • open the developer tools (F12) and delete the required attribute, or change type="email" to type="text";
  • not use your form at all, and send the HTTP request directly with a tool or a short program.
  • JavaScript لە ناچالاک بکات؛
  • ⁦(F12)⁩ بکاتەوە و required بسڕێتەوە، یان type="email" بگۆڕێت بۆ type="text"؛
  • هەر بەکارنەهێنێت و HTTP ڕاستەوخۆ بە ئامرازێک یان کورت بنێرێت.
Client-side checks with HTML5 attributesپشکنینی لای ڕاژەخواز بە خەسڵەتەکانی ⁦HTML5⁩index.htmlHTMLRuns in the browserلە ناو تۆڕگەڕ کار دەکات
<form method="post" action="register.php">
  Name: <input type="text" name="name" required>
  E-mail: <input type="email" name="email" required>
  <input type="submit" value="Register">
</form>
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2-3

required stops the browser from sending an empty field; type="email" makes the browser check the e-mail format. Both are only help for honest users.

required ڕێگە نادات خانەیەکی بەتاڵ بنێرێت؛ type="email" وا دەکات شێوەی بپشکنێت. هەردووکیان تەنها یارمەتین بۆ ڕاستگۆ.

The same request without any browser checkهەمان داواکاری بەبێ هیچ پشکنینێکی تۆڕگەڕBASHType in a terminalلە تێرمیناڵدا بینووسە
curl -d "name=&email=not-an-email" http://localhost/form_handling/register.php
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

curl (a command-line tool on Windows, macOS and Linux) sends a POST request with an empty name and a wrong e-mail. No HTML attribute and no JavaScript can stop it; only your PHP can.

curl (ئامرازێکی هێڵی فەرمانە لە Windows و macOS و Linux) POST بە ناوێکی بەتاڵ و نادروست دەنێرێت. هیچ HTML و هیچ JavaScriptێک ناتوانێت ڕێگری لێ بکات؛ تەنها PHPـەکەت دەتوانێت.

Quick checkپشکنینی خێراWhy is client-side validation not enough?بۆچی بەس نییە؟

6 | The Basics of PHP Form Handling Tutorial | 2023 | Learn PHP Full Course for BeginnersDani Krossing · Englishئینگلیزی · 244K viewsبینین · 4.8K likesلایک · Partبەشی 18:26–23:50 (ofلە 23:50)

Building a form with action, method and name, then reading the sent values in a PHP handler file, and why PHP must check data again.

دروستکردنی بە action، method و name، پاشان خوێندنەوەی لە و بۆچی دەبێت دووبارە بپشکنێتەوە.

From 18:26: why PHP must check data again. exit() belongs after header().

لە ⁦18:26⁩ بەدواوە: بۆچی دەبێت دووبارە بپشکنێتەوە. exit() دەبێت دوای header() بێت.

Checking required fields with isset() and empty()پشکنینی خانە پێویستەکان بە isset() و empty()

The course validates the form from the last lecture (name, e-mail, website, comment, gender). The PHP sits in the same file as the form. It uses two tests:

کۆرسەکە وانەی پێشوو پشتڕاست دەکاتەوە (ناو، ، ماڵپەڕ، تێبینی، ڕەگەز). کۆدی PHPـەکە لە هەمان . دوو پشکنین بەکار دەهێنێت:

  • isset($_POST["submit"]) — was the form sent? The submit button has name="submit", so this key exists only after a click on it. On the first visit the whole block is skipped.
  • empty($_POST["name"]) — is the field missing or blank? empty() is true for a key that does not exist and for an empty string, and it never gives a warning.
  • isset($_POST["submit"]) — ئایا نێردرا؟ name="submit"ـی هەیە، بۆیە ئەم تەنها دوای کرتەکردن لێی هەیە. لە یەکەم سەرداندا هەموو بلۆکەکە بازی لێ دەدرێت.
  • empty($_POST["name"]) — ئایا خانەکە نییە یان بەتاڵە؟ empty() بۆ کە بوونی نییە و بۆ بەتاڵ true دەداتەوە و هەرگیز نادات.

An if … elseif … else chain then checks the fields one by one. Here is the corrected code:

پاشان زنجیرەیەکی if … elseif … else خانەکان یەک لە دوای یەک دەپشکنێت. ئەمە کۆدە ڕاستکراوەکەیە:

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
if (isset($_POST["submit"])) {
    if (empty($_POST["name"])) {
        echo "Name is required<br>";
    } elseif (empty($_POST["email"])) {
        echo "Email is required<br>";
    } elseif (empty($_POST["website"])) {
        echo "Website is required<br>";
    } elseif (empty($_POST["comment"])) {
        echo "Please enter your comment<br>";
    } elseif (empty($_POST["gender"])) {
        echo "Gender is required<br>";
    } else {
        $name    = $_POST["name"];
        $email   = $_POST["email"];
        $website = $_POST["website"];
        $comment = $_POST["comment"];
        $gender  = $_POST["gender"];

        echo "Your inputs are: " . htmlspecialchars("$name, $email, $website, $comment, $gender");
    }
}
?>
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2

Run the checks only after the form was sent.

پشکنینەکان تەنها دوای ناردنی کار دەکەن.

Lineدێڕی 3-12

The chain stops at the first empty field and shows only that message.

زنجیرەکە لە یەکەم خانەی بەتاڵدا دەوەستێت و تەنها ئەو پەیامە پیشان دەدات.

Lineدێڕی 13-20

Only when every field is filled are the values copied into variables and printed.

تەنها کاتێک هەموو خانەکان پڕکرابنەوە، دەخرێنە ناو و چاپ دەکرێن.

Lineدێڕی 20

htmlspecialchars() makes the printed text safe (see security).

htmlspecialchars() دەقە چاپکراوەکە سەلامەت دەکات (بڕوانە ئاسایش).

Name filled, e-mail empty: only the first error is shownناو پڕکراوەتەوە، ئیمەیڵ بەتاڵە: تەنها یەکەم هەڵە پیشان دەدرێت
Email is required
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Email is required<br>
Quick checkپشکنینی خێراWith the corrected if … elseif chain, the user leaves both the name and the e-mail empty and clicks Submit. What does the page show?بە زنجیرە ڕاستکراوەکەی if … elseif، هەم ناو و هەم بەتاڵ بەجێدەهێڵێت و کرتە لە Submit دەکات. لاپەڕەکە چی پیشان دەدات؟

Checking required fields with isset() and empty()پشکنینی خانە پێویستەکان بە isset() و empty()

Two traps of empty()دوو داوی empty()

empty() is quick, but it treats some real answers wrongly:

empty() خێرایە، بەڵام هەندێک وەڵامی ڕاستەقینە بە هەڵە هەڵدەسەنگێنێت:

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
echo "<pre>";
var_dump(empty(""));          // nothing typed
var_dump(empty("0"));         // the user typed 0
var_dump(empty("   "));       // the user typed only spaces
var_dump(trim("   ") === ""); // trim first, then compare
var_dump(trim("0") === "");   // "0" is a real answer
  • "0" counts as empty. A user who types 0 (for example "number of children: 0") is told the field is required.
  • Spaces are not empty. A name made only of spaces passes the check.
  • "0" بە بەتاڵ دادەنرێت. کە 0 دەنووسێت (بۆ نموونە «ژمارەی منداڵ: 0») پێی دەوترێت خانەکە پێویستە.
  • بەتاڵ نییە. ناوێک کە تەنها لە پێکهاتبێت لە پشکنینەکە دەردەچێت.

The reliable test: remove the outer spaces with trim(), then compare with an empty string: trim($_POST["name"] ?? "") === "".

پشکنینی متمانەپێکراو: بە trim() دەرەوە لاببە، پاشان لەگەڵ بەتاڵ بەراوردی بکە: trim($_POST["name"] ?? "") === "".

Quick checkپشکنینی خێراWhat does empty("0") return?empty("0") چی دەگەڕێنێتەوە؟

Checking required fields with isset() and empty()پشکنینی خانە پێویستەکان بە isset() و empty()

Showing all errors at onceپیشاندانی هەموو هەڵەکان پێکەوە

With an elseif chain the user sees one error, fixes it, sends again, and only then sees the next one. It is friendlier to check every field with separate ifs and collect the messages in an array:

بە زنجیرەی elseif یەک هەڵە دەبینێت، چاکی دەکات، دووبارە دەینێرێت و تەنها ئەو کاتە هەڵەی دواتر دەبینێت. باشترە هەموو خانەیەک بە ifـی جیاواز بپشکنیت و پەیامەکان لە کۆ بکەیتەوە:

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
$errors = [];

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $name    = trim($_POST["name"] ?? "");
    $email   = trim($_POST["email"] ?? "");
    $comment = trim($_POST["comment"] ?? "");
    $gender  = $_POST["gender"] ?? "";

    if ($name === "") {
        $errors[] = "Name is required.";
    }
    if ($email === "") {
        $errors[] = "Email is required.";
    }
    if ($comment === "") {
        $errors[] = "Please enter your comment.";
    }
    if ($gender === "") {
        $errors[] = "Gender is required.";
    }

    if (count($errors) > 0) {
        echo "<ul>";
        foreach ($errors as $error) {
            echo "<li>$error</li>";
        }
        echo "</ul>";
    } else {
        echo "Thank you, " . htmlspecialchars($name) . "!";
    }
}
?>
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 4

$_SERVER["REQUEST_METHOD"] === "POST" is another way to ask "was the form sent?" — it does not need a named button.

$_SERVER["REQUEST_METHOD"] === "POST" ڕێگایەکی ترە بۆ پرسینی «ئایا نێردرا؟» — پێویستی بە دوگمەیەکی ناودار نییە.

Lineدێڕی 5-8

Read each value once, with a default, and trim it.

هەر یەک جار بخوێنەوە، لەگەڵ و trim()ـی بکە.

Lineدێڕی 10-21

Separate ifs: every empty field adds its own message.

ifـی جیاواز: هەر خانەیەکی بەتاڵ پەیامی خۆی زیاد دەکات.

Lineدێڕی 23

count($errors) > 0 — at least one problem was found.

count($errors) > 0 — لانیکەم یەک کێشە دۆزرایەوە.

Every field filled (the name was sent as " Dilan ")هەموو خانەکان پڕکراونەتەوە (ناوەکە وەک « Dilan » نێردرا)
Thank you, Dilan!

Drop-down lists, radio buttons and checkboxesلیستی هەڵبژاردن، دوگمەی ڕادیۆ و چێک‌بۆکس

Fields that offer choices need their own checks, because of how browsers send them.

ئەو خانانەی هەڵبژاردن پێشکەش دەکەن پشکنینی تایبەت بە خۆیان پێویستە، بەهۆی ئەو شێوەیەی دەیاننێرن.

Drop-down lists, radio buttons and checkboxesلیستی هەڵبژاردن، دوگمەی ڕادیۆ و چێک‌بۆکس

Checking a radio buttonپشکنینی دوگمەی ڕادیۆ

Radio buttons in a group share one name, so only one can be chosen. If the user chooses none, the browser sends nothing at all for that name — the key does not exist in $_POST. That is why the course tests the group with empty(), which works for a missing key:

لە کۆمەڵەیەکدا یەک nameیان هەیە، بۆیە تەنها یەکێکیان هەڵدەبژێردرێت. ئەگەر هیچیان هەڵنەبژێرێت، هیچ شتێک بۆ ئەو ناوە نانێرێت — لە $_POSTدا بوونی نییە. هەر بۆیە کۆرسەکە کۆمەڵەکە بە empty() دەپشکنێت، کە بۆ نەبوو کار دەکات:

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
$gender = "";
$genderErr = "";

if (isset($_POST["submit"])) {
    if (empty($_POST["gender"])) {
        $genderErr = "Gender is required";
    } else {
        $gender = $_POST["gender"];
    }
}
?>
<form method="post" action="">
  Gender:
  <input type="radio" name="gender" value="female">Female
  <input type="radio" name="gender" value="male">Male
  <span class="error">* <?php echo $genderErr; ?></span>
  <br><br>
  <input type="submit" name="submit" value="Submit">
</form>
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2-3

Give both variables a starting value. The HTML below prints $genderErr; without this line PHP 8 warns Undefined variable $genderErr on the first visit.

هەردوو سەرەتایی پێ بدە. HTMLـی خوارەوە $genderErr چاپ دەکات؛ بەبێ ئەم دێڕە ⁦PHP 8⁩ لە یەکەم سەرداندا Undefined variable $genderErr دەدات.

Lineدێڕی 6-10

The check from the slide: empty → error message; otherwise keep the value.

پشکنینەکەی : بەتاڵ ← ؛ ئەگینا هەڵبگرە.

Lineدێڕی 17

A red * marks the field as required; the message appears after it.

*ێکی سوور خانەکە وەک پێویست نیشان دەکات؛ پەیامەکە لە دوایەوە دەردەکەوێت.

Quick checkپشکنینی خێراA radio group gender was sent with nothing chosen. What is in $_POST?کۆمەڵە gender بێ هەڵبژاردن نێردرا. چی لە $_POSTدایە؟

Drop-down lists, radio buttons and checkboxesلیستی هەڵبژاردن، دوگمەی ڕادیۆ و چێک‌بۆکس

Getting the value of a checkboxوەرگرتنی نرخی چێک‌بۆکس

A works like a single on/off switch. If it is ticked, the browser sends its value; if it is not ticked, it is not sent at all. So isset() is the real test:

وەک کارەبا کار دەکات: هەڵکراو یان کوژاوە. ئەگەر نیشانە کرابێت، valueـەکەی دەنێرێت؛ ئەگەر نیشانە نەکرابێت، هەر نانێردرێت. بۆیە isset() پشکنینە ڕاستەقینەکەیە:

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<form method="post" action="">
  <input type="checkbox" name="formWheelchair" value="Yes"> I need wheelchair access
  <input type="submit" name="formSubmit" value="Submit">
</form>

<?php
if (isset($_POST["formSubmit"])) {
    if (isset($_POST["formWheelchair"]) && $_POST["formWheelchair"] == "Yes") {
        echo "Need wheelchair access.";
    } else {
        echo "Do not need wheelchair access.";
    }
}
?>
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2

name="formWheelchair" and value="Yes": when ticked, $_POST["formWheelchair"] is "Yes".

name="formWheelchair" و value="Yes": کاتێک نیشانە کرابێت، $_POST["formWheelchair"] دەبێتە "Yes".

Lineدێڕی 7

Answer only after the form was sent.

تەنها دوای ناردنی وەڵام بدەرەوە.

Lineدێڕی 8

isset() first, so an unticked box gives no warning; then compare the value.

سەرەتا isset()، بۆیە نیشانە نەکراو نادات؛ پاشان بەراورد بکە.

Sent with the box not tickedبە چێک‌بۆکسی نیشانە نەکراوەوە نێردرا
[ ] I need wheelchair access [Submit]

Do not need wheelchair access.
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post" action="">
  <input type="checkbox" name="formWheelchair" value="Yes"> I need wheelchair access
  <input type="submit" name="formSubmit" value="Submit">
</form>

Do not need wheelchair access.
Quick checkپشکنینی خێراA form has <input type="checkbox" name="news" value="yes">. The user sends the form without ticking it. What is isset($_POST["news"])? <input type="checkbox" name="news" value="yes">ـی هەیە. دەنێرێت بێ ئەوەی نیشانە بکات. isset($_POST["news"]) چییە؟

Checking length, digits and e-mail formatپشکنینی درێژی، ژمارە و شێوەی ئیمەیڵ

"Not empty" is only the first check. The course homework (below) also asks for checks on the content. PHP has built-in functions for each job:

«بەتاڵ نییە» تەنها یەکەم پشکنینە. ڕاهێنانی ماڵەوەی کۆرسەکە (لە خوارەوە) پشکنینی ناوەڕۆکیش دەخوازێت. PHP بۆ هەر کارێک هەیە:

Useful checking functions بەسوودەکانی پشکنین
QuestionپرسیارFunctionResultئەنجام
How many characters?چەند ؟mb_strlen($text)A number. Use it for Kurdish/Arabic text; strlen() counts bytes, not letters.ژمارەیەک. بۆ دەقی کوردی/عەرەبی بەکاری بهێنە؛ strlen() دەژمێرێت، نەک پیتەکان.
Does it contain a piece of text?ئایا پارچە دەقێکی تێدایە؟str_contains($text, "@")true or false (PHP 8).true یان false ⁦(PHP 8)⁩.
Does it contain any digit?ئایا هیچ ژمارەیەکی تێدایە؟preg_match('/[0-9]/', $text)1 if a digit was found, 0 if not.1 ئەگەر ژمارەیەک دۆزرایەوە، 0 ئەگەر نا.
Is it a valid e-mail address?ئایا دروستە؟filter_var($email, FILTER_VALIDATE_EMAIL)The address, or false.خودی ناونیشانەکە، یان false.
Is it one of the allowed values?ئایا یەکێکە لە ڕێگەپێدراوەکان؟in_array($value, $allowed, true)true or false.true یان false.
index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
echo "<pre>";
$username = "Hana";
$kurdish  = "هانا";
$email    = "hana@example.com";

var_dump(strlen($username));      // 4 letters, 4 bytes
var_dump(strlen($kurdish));       // 4 letters, but 8 bytes!
var_dump(mb_strlen($kurdish));    // 4 characters

var_dump(str_contains($email, "@"));                // true
var_dump(preg_match('/[0-9]/', "rezan7"));          // 1 = a digit was found
var_dump(preg_match('/[0-9]/', "rezan"));           // 0 = no digit
var_dump(filter_var("hana@example.com", FILTER_VALIDATE_EMAIL));
var_dump(filter_var("a.@", FILTER_VALIDATE_EMAIL));
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 7-9

Each Kurdish letter takes 2 bytes in UTF-8, so strlen("هانا") is 8. mb_strlen() counts the 4 letters.

هەر پیتێکی کوردی لە ⁦UTF-8⁩دا ٢ دەگرێت، بۆیە strlen("هانا") دەبێتە 8. mb_strlen() چوار پیتەکە دەژمێرێت.

Lineدێڕی 12-13

'/[0-9]/' is a regular-expression pattern that means "any one digit from 0 to 9".

'/[0-9]/' نەخشەیەکی گەڕانە ⁦(regular expression)⁩ بە واتای «هەر ژمارەیەک لە 0 تا 9».

Lineدێڕی 15

a.@ contains @ and ., but it is not an e-mail address: filter_var() rejects it.

a.@ ـ@ و .ـی تێدایە، بەڵام نییە: filter_var() ڕەتی دەکاتەوە.

Quick checkپشکنینی خێراWhich check really tells you whether $email is a valid e-mail address?کام پشکنین بەڕاستی پێت دەڵێت ئایا $email دروستە؟

PHP Tutorial (& MySQL) #20 - Filters & More ValidationNet Ninja · Englishئینگلیزی · 88K viewsبینین · 1.6K likesلایک · Partبەشی 1:53–10:03 (ofلە 13:05)

Checking the format of form data: filter_var() with FILTER_VALIDATE_EMAIL for e-mail addresses, and preg_match() to allow only letters and spaces.

پشکنینی شێوەی : filter_var() لەگەڵ FILTER_VALIDATE_EMAIL بۆ و preg_match() بۆ ئەوەی تەنها پیت و بۆشایی ڕێگەپێدراو بن.

Watch 1:53–10:03: e-mail check and regex check

لە ⁦1:53⁩ تا ⁦10:03⁩ سەیر بکە: پشکنینی و پشکنین بە regex.

Homework: validate a registration formڕاهێنانی ماڵەوە: پشتڕاستکردنەوەی فۆرمی خۆتۆمارکردن

Homework: validate a registration formڕاهێنانی ماڵەوە: پشتڕاستکردنەوەی فۆرمی خۆتۆمارکردن

Three student answers: find the bugsسێ وەڵامی خوێندکاران: باگەکان بدۆزەوە

Three students sent answers to this homework. Each one works in part but has bugs — a perfect exercise in . Read each answer, find the bugs yourself, then open the answer.

سێ خوێندکار وەڵامیان بۆ ئەم ڕاهێنانە نارد. هەریەکەیان بەشێکی کار دەکات بەڵام تێدایە — ڕاهێنانێکی تەواو بۆ . هەر وەڵامێک بخوێنەوە، خۆت بدۆزەوە، پاشان وەڵامەکە بکەرەوە.

ExerciseڕاهێنانFind the bugs: answer Aباگەکان بدۆزەوە: وەڵامی A

This answer collects all messages in $errors and uses a function checkNum() to look for digits in the username. Test it in your head with the username rezan0 and the password abcdefgh (8 letters). What goes wrong? Find at least five problems.

ئەم وەڵامە هەموو پەیامەکان لە $errorsدا کۆ دەکاتەوە و checkNum() بەکار دەهێنێت بۆ گەڕان بەدوای ژمارە لە . لە مێشکی خۆتدا بە rezan0 و abcdefgh (⁦8⁩ پیت) تاقی بکەرەوە. چی هەڵە دەڕوات؟ لانیکەم پێنج کێشە بدۆزەوە.

Answer A (PHP part, at the top of the page)وەڵامی A (بەشی PHP، لە سەرەوەی لاپەڕەکە)index.phpPHP
<?php
$containsNum = false;
$errors = null;

function checkNum($field) {
    global $containsNum;
    for ($i = 0; $i <= 9; $i++) {
        if (strstr($field, $i)) {
            $containsNum = true;
        }
    }
}

if (isset($_POST['subbtn'])) {

    $name = $_POST['username'];
    $email = $_POST['email'];
    $gender = $_POST['gender'];

    if (empty($name)) {
        $errors .= "Name field is empty. <br />";
    }

    if (empty($email)) {
        $errors .= "Email field is empty. <br />";
    }

    if (empty($gender)) {
        $errors .= "Gender must be chosen. <br />";
    }

    checkNum($_POST['username']);
    if ($containsNum) {
        $errors .= "The username field must not conrain a number."."<br />";
    }

    if (!strstr($_POST['email'], '@') || !strstr($_POST['email'], '.')) {
        $errors .= "Email must contain at least one @ and dot."."<br />";
    }

    if (strlen($_POST['pass']) <= 8 || strlen($_POST['pass']) >= 20) {
        $errors .= "Password should be between 8 and 20 characters.<br />";
    }
}

echo $errors;
?>
Answer A (HTML part, under the PHP)وەڵامی A (بەشی HTML، لە ژێر PHPـەکەوە)index.phpPHP
<form method="post">
    Username: <input type="text" name="username" value="<?php if (isset($name)) echo $name; ?>"><br>
    Email: <input type="text" name="email" value="<?php if (isset($email)) echo $email; ?>"><br>
    Gender:
    <input type="radio" name="gender" value="Female" <?php if (isset($gender) && $gender == "Female") echo "checked"; ?>> Female
    &nbsp;
    <input type="radio" name="gender" value="Male" <?php if (isset($gender) && $gender == "Male") echo "checked"; ?>> Male <br />
    Password: <input type="password" name="pass"><br>
    <input type="submit" name="subbtn" value="Login">
</form>
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2-3

Sticky text boxes: the typed values are printed back (without htmlspecialchars()).

لکاو: نووسراوەکان دووبارە چاپ دەکرێنەوە (بەبێ htmlspecialchars()).

Lineدێڕی 5, 7

The chosen radio button gets checked.

هەڵبژێردراو checked وەردەگرێت.

Hintئاماژە

What does strstr("rezan0", 0) return, and is that value true or false?

strstr("rezan0", 0) چی دەگەڕێنێتەوە و ئەو ڕاستە یان هەڵە؟

Show answerوەڵامەکە پیشان بدە

The PHP part prints this for the username rezan0, a valid e-mail, gender Male and the password abcdefgh: the digit is not found, and a valid 8-character password is rejected:

بەشی PHPـەکە بۆ rezan0، دروست، ڕەگەزی Male و abcdefgh ئەمە چاپ دەکات: ژمارەکە نادۆزرێتەوە و دروستی 8 ڕەت دەکرێتەوە:

Sent: rezan0 / rezan@example.com / Male / abcdefghنێردرا: ⁦rezan0 / rezan@example.com / Male / abcdefgh⁩
Password should be between 8 and 20 characters.
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Password should be between 8 and 20 characters.<br />
  • The digit 0 is never found. strstr() returns the rest of the text from the match. For rezan0 that is "0", and in an if the string "0" counts as false. So a username ending in 0 passes. (A digit 7 is found, because strstr("reb7in", 7) returns "7in".)
  • 8 and 20 are rejected. <= 8 || >= 20 refuses passwords of exactly 8 or exactly 20 characters, although the message says "between 8 and 20". Use < 8 || > 20.
  • No gender chosen → a warning. $_POST['gender'] is read without isset(); when no radio button is chosen PHP 8 warns Undefined array key "gender".
  • The e-mail check is too weak. It only asks for an @ and a . somewhere, so a.@ is accepted. Add filter_var(..., FILTER_VALIDATE_EMAIL).
  • "Mixed" is not checked at all.
  • PHP 7 would not even find 7. Passing the integer $i as the search text works only since PHP 8.0. In PHP 7 an integer needle was read as a character code (7 meant an invisible control character), so no digit was ever found. Convert it, (string) $i, or use the functions below.
  • The password is read without a check. $_POST['pass'] is used without isset() or ??, and an empty password only gets the length message.
  • Style: checkNum() changes a global flag instead of returning true/false; $errors = null works with .= but "" is clearer; the typo "conrain"; the button says "Login" on a registration form; the sticky values are printed without htmlspecialchars().
  • ژمارەی 0 هەرگیز نادۆزرێتەوە. strstr() پاشماوەی دەقەکە لە شوێنی دۆزینەوەکەوە دەگەڕێنێتەوە. بۆ rezan0 ئەمە "0"ـە و لەناو ifدا "0" بە false دادەنرێت. بۆیە ناوێک کە بە 0 کۆتایی بێت دەردەچێت. (ژمارەی 7 دەدۆزرێتەوە، چونکە strstr("reb7in", 7) ـ"7in" دەگەڕێنێتەوە.)
  • 8 و ⁦20⁩ ڕەت دەکرێنەوە. <= 8 || >= 20 ئەو تێپەڕەوشانە ڕەت دەکاتەوە کە ڕێک 8 یان ڕێک ⁦20⁩ ، هەرچەندە پەیامەکە دەڵێت «لە نێوان 8 و ⁦20⁩دا». < 8 || > 20 بەکاربهێنە.
  • هیچ ڕەگەزێک هەڵنەبژێردرا ← . $_POST['gender'] بەبێ isset() دەخوێنرێتەوە؛ کاتێک هیچ هەڵنەبژێردرابێت، ⁦PHP 8⁩ Undefined array key "gender" دەدات.
  • پشکنینی زۆر لاوازە. تەنها @ و .ێک لە هەر شوێنێک دەخوازێت، بۆیە a.@ وەردەگیرێت. filter_var(..., FILTER_VALIDATE_EMAIL) زیاد بکە.
  • «تێکەڵ» هەر نەپشکنراوە.
  • ⁦PHP 7⁩ تەنانەت 7ـیش نەدەدۆزییەوە. ناردنی $i () وەک دەقی گەڕان تەنها لە ⁦PHP 8.0⁩ـەوە کار دەکات. لە ⁦PHP 7⁩دا وەک کۆدی دەخوێنرایەوە (7 واتای کۆنترۆڵی نادیار بوو)، بۆیە هیچ ژمارەیەک نەدەدۆزرایەوە. بیگۆڕە بۆ دەق، (string) $i، یان خوارەوە بەکاربهێنە.
  • بێ پشکنین دەخوێنرێتەوە. $_POST['pass'] بەبێ isset() یان ?? بەکار دێت و بەتاڵ تەنها پەیامی درێژی وەردەگرێت.
  • شێواز: checkNum() ئاڵایەکی global دەگۆڕێت لە جیاتی گەڕاندنەوەی true/false؛ $errors = null لەگەڵ .= کار دەکات بەڵام "" ڕوونترە؛ هەڵەی نووسینی «conrain»؛ دوگمەکە لەسەر دەڵێت «Login»؛ لکاوەکان بەبێ htmlspecialchars() چاپ دەکرێن.
No gender chosen (rezan / rezan@example.com / abcdefghi)هیچ ڕەگەزێک هەڵنەبژێردرا ⁦(rezan / rezan@example.com / abcdefghi)⁩
Warning: Undefined array key "gender" in C:\xampp\htdocs\forms\index.php on line 18
Gender must be chosen.
reb7in / rezan@example.com / Male / abcdefghi: this digit is found⁦reb7in / rezan@example.com / Male / abcdefghi⁩: ئەم ژمارەیە دەدۆزرێتەوە
The username field must not conrain a number.
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
The username field must not conrain a number.<br />

Why "0" is false — and the reliable way:

بۆچی "0" بە false دادەنرێت — و ڕێگا متمانەپێکراوەکە:

test.phpPHP
<?php
echo "<pre>";
var_dump(strstr("rezan0", "0"));         // the rest of the string from "0"
var_dump((bool) strstr("rezan0", "0"));  // ...which counts as false!
var_dump((bool) strstr("reb0in", "0"));  // here the rest is "0in": true
var_dump(str_contains("rezan0", "0"));   // the reliable way (PHP 8)

A fixed digit check that keeps the student's idea (a loop over 0–9) but returns a boolean:

پشکنینێکی چاککراوی ژمارە کە بیرۆکەی خوێندکارەکە دەپارێزێت ( بەسەر ⁦0–9⁩دا) بەڵام دەگەڕێنێتەوە:

test.phpPHP
<?php
echo "<pre>";
function containsDigit($text) {
    for ($i = 0; $i <= 9; $i++) {
        if (str_contains($text, (string) $i)) {
            return true;
        }
    }
    return false;
}

var_dump(containsDigit("rezan0"));   // the digit 0 is found now
var_dump(containsDigit("reb9in"));   // and the digit 9
var_dump(containsDigit("rezan"));    // no digit
ExerciseڕاهێنانFind the bugs: answer Bباگەکان بدۆزەوە: وەڵامی B

This answer prints a message for each problem straight away. It has at least four real bugs. Find them. (The bottom of the original screenshot was cut off; the last } was added so that the code runs.)

ئەم وەڵامە بۆ هەر کێشەیەک دەستبەجێ پەیامێک چاپ دەکات. لانیکەم چوار ڕاستەقینەی تێدایە. بیاندۆزەوە. (خوارەوەی سەرەکییەکە بڕابوو؛ دوایین } زیاد کراوە تاکو کۆدەکە کار بکات.)

Answer Bوەڵامی Bindex.phpPHP
<?php
if(isset($_POST['btn'])){

    $Username = $_POST['username'];
    $email = $_POST ['email'];
    $password = $_POST["password"];
    if (isset($gender['gender']))
    $gender = $_POST['gender'];

    for ($i = 0 ; $i<9 ; $i++){
        if (strstr($_POST['username'],$i)){
            echo "Only text <br>";}
        }
        if (!strstr($_POST['email'],"@")|| !strstr($_POST['email'],"@")){
            echo " must contain @ and . <br>";
        }
        if (strlen($_POST['password']< 8) ||strlen($_POST['password']> 20) ){
            echo "Between 8 to 20 <br>";

    }
}
?>
Hintئاماژە

Look closely at the parentheses in the strlen line, and at which variable isset() tests.

بە وردی سەیری کەوانەکانی دێڕی strlen بکە و ئەو isset() دەیپشکنێت.

Show answerوەڵامەکە پیشان بدە
  • isset($gender['gender']) tests the wrong variable. $gender does not exist yet, so the condition is always false and the gender is never read. It should be isset($_POST['gender']).
  • $i<9 skips the digit 9, and 0 is missed because of the strstr() "0" problem. The message is also printed once for every digit found.
  • The e-mail is tested for "@" twice and never for ".", so rezan@examplecom passes.
  • A misplaced parenthesis: strlen($_POST['password']< 8) measures the length of the comparison result (true/false), not of the password. Almost every real password is rejected, and a password like "10" is accepted. Correct: strlen($_POST['password']) < 8 || strlen($_POST['password']) > 20.
  • Smaller points: the indentation hides that the for loop ends after its first }; $Username uses a capital letter unlike the other variables; "mixed" is not checked. ($_POST ['email'] with a space before [ is unusual but valid PHP.)
  • isset($gender['gender']) نادروست دەپشکنێت. $gender هێشتا بوونی نییە، بۆیە هەمیشە false ـە و ڕەگەز هەرگیز ناخوێنرێتەوە. دەبێت isset($_POST['gender']) بێت.
  • $i<9 ژمارەی 9 بازدەدات و 0یش بەهۆی کێشەی «0»ـی strstr()ـەوە نادۆزرێتەوە. پەیامەکەش بۆ هەر ژمارەیەکی دۆزراوە یەک جار چاپ دەکرێت.
  • دوو جار بۆ "@" دەپشکنرێت و هەرگیز بۆ "." نا، بۆیە rezan@examplecom دەردەچێت.
  • کەوانەیەکی لە شوێنی خۆی نەبوو: strlen($_POST['password']< 8) درێژیی ئەنجامی بەراوردکردنەکە (true/false) دەپێوێت، نەک هی . نزیکەی هەموو ڕاستەقینە ڕەت دەکرێتەوە و وەک "10" وەردەگیرێت. دروستەکەی: strlen($_POST['password']) < 8 || strlen($_POST['password']) > 20.
  • خاڵی بچووکتر: ڕیزبەندیی دێڕەکان ئەوە دەشارێتەوە کە for دوای یەکەم } کۆتایی دێت؛ $Username بە پیتی گەورە دەست پێدەکات، بە پێچەوانەی تر؛ «تێکەڵ» نەپشکنراوە. ($_POST ['email'] بە پێش [ نائاساییە، بەڵام PHPـی دروستە.)
Sent: rezan9 / rezan@examplecom / abcdefghijنێردرا: ⁦rezan9 / rezan@examplecom / abcdefghij⁩
Between 8 to 20
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Between 8 to 20 <br>

Only the (wrong) length message appears: the digit 9 and the missing dot were not noticed, and a good 10-letter password was rejected. With the password 10 there is no message at all:

تەنها پەیامی (نادروستی) درێژی دەردەکەوێت: ژمارە 9 و خاڵە ونبووەکە هەست پێ نەکران و باشی ⁦10⁩ پیتی ڕەت کرایەوە. بە 10 هیچ پەیامێک نییە:

Sent: rezan / rezan@example.com / password 10نێردرا: ⁦rezan / rezan@example.com⁩ / تێپەڕەوشە ⁦10⁩
(no output)

An empty page: no message at all.

لاپەڕەیەکی بەتاڵ: هیچ پەیامێک نییە.

ExerciseڕاهێنانFind the bugs: answer Cباگەکان بدۆزەوە: وەڵامی C

This answer keeps one error variable per field and prints the data only when all three are still null. Its length check is correct. What happens when the user leaves the e-mail and the password empty? (Again the bottom of the screenshot was cut; the last } was added.)

ئەم وەڵامە بۆ هەر خانەیەک هەڵەی جیا هەڵدەگرێت و تەنها کاتێک زانیارییەکان چاپ دەکات کە هەر سێکیان هێشتا null بن. پشکنینی درێژییەکەی دروستە. چی ڕوودەدات کاتێک و بەتاڵ بەجێدەهێڵێت؟ (دیسان خوارەوەی وێنەکە بڕابوو؛ دوایین } زیاد کراوە.)

Answer Cوەڵامی Cindex.phpPHP
<?php
$UsernameError = null;
$EmailError = null;
$PasswordError = null;


if (isset($_POST['sub'])){
    if(empty($_POST['username'])){
        $UsernameError = "Enter your username";
    }
    for ($i = 0 ; $i<=10; $i++ ){
     if (strstr($_POST['username'],$i)){
        $UsernameError = " your username only must text";

    }

    }
    if (empty($_POST['email'])){
        $EmailError = "enter your email";
    }
    if(!strstr($_POST['email'],"@") || !strstr($_POST['email'],".")){
        $EmailError = " email contain @ and .";
    }
    if (empty($_POST['password'])){
        $PasswordError = "enter your password";
    }
    if (strlen($_POST['password'])>20 || strlen($_POST['password'])<8){
        $PasswordError = " Password must be between 8 - 20";
    }
    if(!isset($UsernameError)&& !isset($EmailError)&& !isset($PasswordError)){

        $username = (($_POST['username']));
        $Email = (($_POST['email']));
        $password = (($_POST['password']));

        echo $username."<br>";
        echo $Email."<br>";
        echo $password."<br>";

    }
}
?>
Show answerوەڵامەکە پیشان بدە

To see the three error variables we print them after the code. Input: username hana0, e-mail and password empty:

بۆ بینینی سێ هەڵە، دوای کۆدەکە چاپیان دەکەین. نێوخستە: hana0، و بەتاڵ:

What the browser showsئەوەی تۆڕگەڕ پیشانی دەدات
Username:
Email:  email contain @ and .
Password:  Password must be between 8 - 20
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Username: <br>Email:  email contain @ and .<br>Password:  Password must be between 8 - 20
  • Later checks overwrite earlier messages. An empty e-mail first gets "enter your email", but the next if replaces it with " email contain @ and .". The same happens to the password. Use elseif, so the second test runs only if the first one passed.
  • hana0 is not flagged (the same strstr() "0" problem). The loop to 10 is unnecessary: there are only ten digits, 0–9.
  • It prints the password back to the page — never show a password.
  • Good ideas to keep: one error variable per field, null + isset() as "no error", and a correct > 20 || < 8 length test. Small points: the double parentheses (($_POST['username'])) are unnecessary; the messages need better English ("your username only must text"); "mixed" is not checked.
  • پشکنینەکانی دواتر پەیامەکانی پێشوو دەسڕنەوە. بەتاڵ سەرەتا «⁦enter your email⁩» وەردەگرێت، بەڵام ifـی دواتر « ⁦email contain @ and⁩ .»ـی لە جێگەی دادەنێت. هەمان شت بۆ ڕوودەدات. elseif بەکاربهێنە، تاکو پشکنینی دووەم تەنها کاتێک کار بکات کە یەکەم سەرکەوتوو بووبێت.
  • hana0 نیشانە ناکرێت (هەمان کێشەی «0»ـی strstr()). تا ⁦10⁩ پێویست نییە: تەنها دە ژمارە هەیە، ⁦0–9⁩.
  • دووبارە لەسەر لاپەڕەکە چاپ دەکاتەوە — هەرگیز پیشان مەدە.
  • بیرۆکەی باش بۆ پاراستن: هەڵە بۆ هەر خانەیەک، null + isset() بە واتای «هەڵە نییە» و پشکنینێکی دروستی درێژی بە > 20 || < 8. خاڵی بچووک: کەوانەی دووبارەی (($_POST['username'])) پێویست نییە؛ ئینگلیزیی پەیامەکان باشتر دەبێت («⁦your username only must text⁩»)؛ «تێکەڵ» نەپشکنراوە.
Quick checkپشکنینی خێراWhich condition rejects passwords shorter than 8 or longer than 20 characters (8 and 20 allowed)?کام ئەو تێپەڕەوشانە ڕەت دەکاتەوە کە لە 8 کورتتر یان لە ⁦20⁩ درێژترن (⁦8⁩ و ⁦20⁩ ڕێگەپێدراون)؟

Homework: validate a registration formڕاهێنانی ماڵەوە: پشتڕاستکردنەوەی فۆرمی خۆتۆمارکردن

A complete solutionچارەسەرێکی تەواو

This solution fixes every bug above. It reads and trims each field once, checks every rule, keeps one message per field next to the field, and keeps the typed username and e-mail in the form (a sticky form, explained in the next lecture). The password box is never refilled.

ئەم چارەسەرە هەموو سەرەوە چاک دەکاتەوە. هەر خانەیەک یەک جار دەخوێنێتەوە و trim()ـی دەکات، هەموو دەپشکنێت، بۆ هەر خانەیەک پەیامێک لە تەنیشتیەوە دادەنێت و و نووسراوەکە لەناو دەهێڵێتەوە (، کە لە وانەی داهاتوودا ڕوون کراوەتەوە). هەرگیز دووبارە پڕ ناکرێتەوە.

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
$username = "";
$email = "";
$errors = ["username" => "", "email" => "", "password" => ""];
$success = "";

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $username = trim($_POST["username"] ?? "");
    $email    = trim($_POST["email"] ?? "");
    $password = $_POST["password"] ?? "";

    // 1. Username: required, and no digits at all
    if ($username === "") {
        $errors["username"] = "Username is required.";
    } elseif (preg_match('/[0-9]/', $username)) {
        $errors["username"] = "Username must not contain numbers.";
    }

    // 2. Email: required, must contain @ and a dot, and must be a valid address
    if ($email === "") {
        $errors["email"] = "Email is required.";
    } elseif (!str_contains($email, "@") || !str_contains($email, ".")) {
        $errors["email"] = "Email must contain @ and a dot.";
    } elseif (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
        $errors["email"] = "Email is not a valid address.";
    }

    // 3. Password: 8-20 characters, and mixed (letters AND digits)
    $length = mb_strlen($password);
    if ($length < 8 || $length > 20) {
        $errors["password"] = "Password must be 8 to 20 characters.";
    } elseif (!preg_match('/[a-zA-Z]/', $password) || !preg_match('/[0-9]/', $password)) {
        $errors["password"] = "Password must mix letters and numbers.";
    }

    if ($errors["username"] === "" && $errors["email"] === "" && $errors["password"] === "") {
        $success = "Registration data is valid. Welcome, " . htmlspecialchars($username) . "!";
    }
}
?>
<form method="post" action="">
  Username: <input type="text" name="username" value="<?php echo htmlspecialchars($username); ?>">
  <span class="error"><?php echo $errors["username"]; ?></span><br>
  Email: <input type="text" name="email" value="<?php echo htmlspecialchars($email); ?>">
  <span class="error"><?php echo $errors["email"]; ?></span><br>
  Password: <input type="password" name="password">
  <span class="error"><?php echo $errors["password"]; ?></span><br>
  <input type="submit" value="Register">
</form>
<p><?php echo $success; ?></p>
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2-5

Start with empty values so the form also works on the first visit.

بە بەتاڵ دەست پێبکە تاکو لە یەکەم سەردانیشدا کار بکات.

Lineدێڕی 13-17

Rule 1: required, then "no digit at all" with preg_match('/[0-9]/', …) — this also finds 0.

١: پێویستە، پاشان «هیچ ژمارەیەکی تێدا نەبێت» بە preg_match('/[0-9]/', …) — ئەمە 0ـیش دەدۆزێتەوە.

Lineدێڕی 20-26

Rule 2: the course's "@ and ." test with str_contains(), then a real format test with filter_var().

٢: پشکنینی «@ و .»ـی کۆرسەکە بە str_contains()، پاشان پشکنینێکی ڕاستەقینەی شێوە بە filter_var().

Lineدێڕی 29-34

Rule 3: 8 to 20 characters (8 and 20 allowed), and mixed = at least one letter and one digit.

٣: 8 بۆ ⁦20⁩ (⁦8⁩ و ⁦20⁩ ڕێگەپێدراون) و تێکەڵ = لانیکەم یەک پیت و یەک ژمارە.

Lineدێڕی 42, 44

Typed values are printed back with htmlspecialchars().

نووسراوەکان بە htmlspecialchars() دووبارە چاپ دەکرێنەوە.

Sent: (empty) / a.@ / short1نێردرا: (بەتاڵ) / ⁦a.@ / short1⁩
Username: [ ] Username is required.
Email: [a.@] Email is not a valid address.
Password: [ ] Password must be 8 to 20 characters.
[Register]
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post" action="">
  Username: <input type="text" name="username" value="">
  <span class="error">Username is required.</span><br>
  Email: <input type="text" name="email" value="a.@">
  <span class="error">Email is not a valid address.</span><br>
  Password: <input type="password" name="password">
  <span class="error">Password must be 8 to 20 characters.</span><br>
  <input type="submit" value="Register">
</form>
<p></p>
Sent: Rezan / rezan@example.com / kurdistan2026نێردرا: ⁦Rezan / rezan@example.com / kurdistan2026⁩
Username: [Rezan]
Email: [rezan@example.com]
Password: [ ]
[Register]

Registration data is valid. Welcome, Rezan!
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post" action="">
  Username: <input type="text" name="username" value="Rezan">
  <span class="error"></span><br>
  Email: <input type="text" name="email" value="rezan@example.com">
  <span class="error"></span><br>
  Password: <input type="password" name="password">
  <span class="error"></span><br>
  <input type="submit" value="Register">
</form>
<p>Registration data is valid. Welcome, Rezan!</p>

Common mistakesهەڵە باوەکان

  • Validating only in the browser. HTML required and JavaScript can be skipped; always check again in PHP.
  • Reading radio buttons and checkboxes without isset()/empty(). When nothing is chosen they are not sent, and PHP 8 warns.
  • Running the checks on the first visit. Without isset($_POST["submit"]) (or a REQUEST_METHOD test) the page shows errors before the user did anything.
  • Trusting empty() blindly. "0" is "empty", and " " is not. Use trim() and === "".
  • Using strstr() as a yes/no test. It returns text, and "0" is false. Use str_contains().
  • Off-by-one in ranges. "Between 8 and 20" means >= 8 && <= 20; the error test is < 8 || > 20.
  • Misplaced parentheses such as strlen($x < 8).
  • Overwriting messages with a second if instead of elseif.
  • Copy-and-paste messages ("email is required" under the website field).
  • Trusting drop-down values. Check them with in_array().
  • Counting Kurdish letters with strlen(). Use mb_strlen().
  • تەنها لە . requiredـی HTML و JavaScript بازیان لێ دەدرێت؛ هەمیشە لە PHPـدا دووبارە بپشکنە.
  • خوێندنەوەی و بەبێ isset()/empty(). کاتێک هیچ هەڵنەبژێردرابێت نانێردرێن و ⁦PHP 8⁩ ئاگادار دەکاتەوە.
  • کارپێکردنی پشکنینەکان لە یەکەم سەرداندا. بەبێ isset($_POST["submit"]) (یان پشکنینی REQUEST_METHOD) لاپەڕەکە پێش ئەوەی هیچ بکات هەڵە پیشان دەدات.
  • متمانەی کوێرانە بە empty(). "0" «بەتاڵ»ـە و " " بەتاڵ نییە. trim() و === "" بەکاربهێنە.
  • بەکارهێنانی strstr() وەک پشکنینی بەڵێ/نەخێر. دەق دەگەڕێنێتەوە و "0" false ـە. str_contains() بەکاربهێنە.
  • لە مەودادا. «لە نێوان 8 و ⁦20⁩دا» واتە >= 8 && <= 20؛ پشکنینی هەڵەکە < 8 || > 20ـە.
  • کەوانەی لە شوێنی خۆی نەبوو وەک strlen($x < 8).
  • سڕینەوەی پەیامەکان بە ifـێکی دووەم لە جیاتی elseif.
  • پەیامی کۆپی‌کراو («⁦email is required⁩» لە ژێر خانەی ماڵپەڕدا).
  • متمانە بە . بە in_array() بیانپشکنە.
  • ژماردنی پیتە کوردییەکان بە strlen(). mb_strlen() بەکاربهێنە.

Practiceڕاهێنان

Quick checkپشکنینی خێراWhich of these checks cannot be skipped by a visitor?کام لەم پشکنینانە سەردانکەر ناتوانێت بازی لێ بدات؟

Quick checkپشکنینی خێراYou want the user to see every problem in the form at once. What do you write?دەتەوێت هەموو کێشەکانی پێکەوە ببینێت. چی دەنووسیت؟

ExerciseڕاهێنانAn age fieldخانەی تەمەن

Add a required field age to a form. Accept only whole numbers from 1 to 120. Show the message "Please enter your age" when it is empty and "Age must be a number from 1 to 120" when it is wrong. Make sure that a value of 0 gives the second message, not the first.

خانەیەکی پێویستی age بۆ زیاد بکە. تەنها لە 1 تا ⁦120⁩ وەربگرە. کاتێک بەتاڵە پەیامی «⁦Please enter your age⁩» و کاتێک نادروستە «⁦Age must be a number from 1 to 120⁩» پیشان بدە. دڵنیا ببەوە کە 0 پەیامی دووەم دەدات، نەک یەکەم.

Hintئاماژە

Do not use empty() here. filter_var($age, FILTER_VALIDATE_INT, ["options" => ["min_range" => 1, "max_range" => 120]]) returns the number or false.

لێرەدا empty() بەکارمەهێنە. filter_var($age, FILTER_VALIDATE_INT, ["options" => ["min_range" => 1, "max_range" => 120]]) ژمارەکە یان false دەگەڕێنێتەوە.

Show answerوەڵامەکە پیشان بدە
index.phpPHP
<?php
function checkAge($age) {
    if (trim($age) === "") {
        return "Please enter your age";
    }
    $options = ["options" => ["min_range" => 1, "max_range" => 120]];
    if (filter_var($age, FILTER_VALIDATE_INT, $options) === false) {
        return "Age must be a number from 1 to 120";
    }
    return "OK";
}

// In the page you would write:  $message = checkAge($_POST["age"] ?? "");
foreach (["", "0", "abc", "25", "121"] as $test) {
    echo '"' . $test . '" -> ' . checkAge($test) . "<br>";
}
Review questionsپرسیارەکانی پێداچوونەوە
What is the difference between client-side and server-side validation?جیاوازیی نێوان پشتڕاستکردنەوەی لای ڕاژەخواز و لای ڕاژەکار چییە؟

Client-side validation runs in the browser before the form is sent: fast and friendly, but not secure. Server-side validation runs in PHP after the form arrives: slower, but it cannot be skipped. Use both, and never rely on the client side alone.

پێش ناردنی لە کار دەکات: خێرا و دۆستانەیە، بەڵام سەلامەت نییە. دوای گەیشتنی لە PHPـدا کار دەکات: هێواشترە، بەڵام بازی لێ نادرێت. هەردووکیان بەکاربهێنە و هەرگیز تەنها پشت بە مەبەستە.

What do isset($_POST["submit"]) and empty($_POST["name"]) check?isset($_POST["submit"]) و empty($_POST["name"]) چی دەپشکنن؟

The first checks that the form was sent (the named submit button exists in $_POST). The second is true when the name field is missing or blank.

یەکەمیان دەپشکنێت کە نێردراوە ( ناودار لە $_POSTدا هەیە). دووەمیان کاتێک ڕاستە کە خانەی ناو نەبێت یان بەتاڵ بێت.

Why does an if … elseif chain show only one error?بۆچی زنجیرەی if … elseif تەنها یەک هەڵە پیشان دەدات؟

Because the chain stops at the first true condition. To show all errors, use separate ifs and collect the messages.

چونکە زنجیرەکە لە یەکەم ڕاستدا دەوەستێت. بۆ پیشاندانی هەموو هەڵەکان، ifـی جیاواز بەکاربهێنە و پەیامەکان کۆ بکەرەوە.

How do you read the value of a checkbox safely?چۆن بە سەلامەتی نرخی چێک‌بۆکسێک دەخوێنیتەوە؟

With isset($_POST["box"]) first, because an unticked checkbox is not sent; then compare the value.

سەرەتا بە isset($_POST["box"])، چونکە نیشانە نەکراو نانێردرێت؛ پاشان بەراورد بکە.

Why can strstr($name, $i) miss the digit 0?بۆچی strstr($name, $i) دەتوانێت ژمارەی 0 ون بکات؟

It returns the rest of the string from the match; for a name ending in 0 that is "0", which PHP treats as false. Use str_contains() or preg_match('/[0-9]/', …).

پاشماوەی لە شوێنی دۆزینەوەکەوە دەگەڕێنێتەوە؛ بۆ ناوێک کە بە 0 کۆتایی بێت ئەمە "0"ـە، کە PHP بە false دایدەنێت. str_contains() یان preg_match('/[0-9]/', …) بەکاربهێنە.

Which function checks an e-mail address properly?کام کردار بە دروستی ناونیشانی ئیمەیڵ دەپشکنێت؟

filter_var($email, FILTER_VALIDATE_EMAIL) — it returns the address or false. Checking only for @ and . accepts nonsense like a.@.

filter_var($email, FILTER_VALIDATE_EMAIL) — ناونیشانەکە یان false دەگەڕێنێتەوە. پشکنینی تەنها @ و . شتی بێواتای وەک a.@ وەردەگرێت.

Summaryپوختە

  • Validation checks user input before it is used: required fields, formats, lengths and allowed values.
  • Client-side validation is for comfort; server-side validation in PHP is for security and must always be done.
  • isset($_POST["submit"]) asks "was the form sent?"; empty() asks "is it missing or blank?" — but remember "0" and spaces.
  • Unchosen radio buttons and unticked checkboxes are not sent; drop-down values must be checked against the allowed list.
  • Use mb_strlen(), str_contains(), preg_match(), filter_var() and in_array() for content checks.
  • Show clear messages next to the fields, and show all of them at once when you can.
  • پێش بەکارهێنان دەپشکنێت: ، شێوە، درێژی و ڕێگەپێدراوەکان.
  • بۆ ئاسانکارییە؛ لە PHPـدا بۆ و دەبێت هەمیشە بکرێت.
  • isset($_POST["submit"]) دەپرسێت «ئایا نێردرا؟»؛ empty() دەپرسێت «ئایا نییە یان بەتاڵە؟» — بەڵام "0" و لەبیر مەکە.
  • هەڵنەبژێردراو و نیشانە نەکراو نانێردرێن؛ دەبێت لەگەڵ لیستی ڕێگەپێدراودا بپشکنرێن.
  • بۆ پشکنینی ناوەڕۆک mb_strlen()، str_contains()، preg_match()، filter_var() و in_array() بەکاربهێنە.
  • پەیامی ڕوون لە تەنیشت خانەکانەوە پیشان بدە و ئەگەر توانیت هەموویان پێکەوە پیشان بدە.

Videoڤیدیۆ

Watch a videoسەیری ڤیدیۆیەک بکە

A video that viewers liked a lot and praised in their comments, chosen for this lesson.ڤیدیۆیەک کە بینەران زۆریان پێ خۆش بووە و لە کۆمێنتەکانیاندا ستایشیان کردووە، بۆ ئەم وانەیە هەڵبژێردراوە.

PHP Full Course for free 🐘Bro Code · Englishئینگلیزی · 3M viewsبینین · 65K likesلایک · Partبەشی 2:01:09–2:27:40 (ofلە 4:00:00)

How to create a function, send values in with arguments, and get a result back with return, with a short practice example.

چۆن دروست بکەیت، بە بنێریتە ناوی و بە return ئەنجامێک لێی وەربگریتەوە، لەگەڵ ڕاهێنانێکی کورت.

Watch 2:01:09–2:27:40: isset(), empty(), radio buttons and checkboxes

لە ⁦2:01:09⁩ تا ⁦2:27:40⁩ سەیر بکە: isset()، empty()، و .

Lesson complete!وانەکە تەواو بوو!

Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.

Key termsزاراوە سەرەکییەکان

Next lessonوانەی داهاتوو

Form Security and Sticky Formsئاسایشی فۆرم و فۆرمە لکاوەکان

References and further readingسەرچاوەکان و خوێندنەوەی زیاتر

This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.