Chapterبەش 8 · Lectureوانە 8.4
Form Security and Sticky Formsئاسایشی فۆرم و فۆرمە لکاوەکان
Protect your pages from cross-site scripting (XSS) with htmlspecialchars(), understand what trim() and stripslashes() really do, review the course's test_input() function, and build sticky forms that keep the user's input after an error.
لاپەڕەکانت بە htmlspecialchars() لە XSS بپارێزە، تێبگە trim() و stripslashes() بەڕاستی چی دەکەن، test_input()ـی کۆرسەکە هەڵبسەنگێنە و دروست بکە کە دوای هەڵەیەک دەپارێزێت.
What you will learnچی فێر دەبیت
- Explain what XSS is and show how unescaped output makes it possible.
- Use
htmlspecialchars()at output, and know which characters it changes. - Describe what
trim()andstripslashes()do, and whystripslashes()is outdated. - Write and judge a cleaning function such as
test_input(). - Build a sticky form with text boxes, a textarea, radio buttons, checkboxes and a drop-down list.
- Avoid undefined-variable warnings and double escaping in sticky forms.
- ڕوون بکەیتەوە XSS چییە و پیشانی بدەیت چۆن نەگۆڕدراو ڕێگەی بۆ خۆش دەکات.
htmlspecialchars()لە بەکاربهێنیت و بزانیت کام نووسانە دەگۆڕێت.- باسی ئەوە بکەیت
trim()وstripslashes()چی دەکەن و بۆچیstripslashes()کۆنە. - وەک
test_input()بنووسیت و هەڵیبسەنگێنیت. - دروست بکەیت بە ، ، ، و .
- لە لە پێناسەنەکراو و گۆڕینی دووجارەی هێماکان دوور بکەویتەوە.
Forms are an open doorفۆرم دەرگایەکی کراوەیە
A form is a door into your website: anyone in the world can type anything into it. Most visitors type a name or an e-mail address. A few type code, hoping your page will run it. This lecture teaches two things that every form needs: making user input safe before you print it, and sticky forms, which keep what the user typed when the form comes back with errors.
دەرگایەکە بۆ ناو : هەر کەسێک لە جیهاندا دەتوانێت هەر شتێک تێیدا بنووسێت. زۆربەی سەردانکەران ناوێک یان دەنووسن. هەندێکیان کۆد دەنووسن، بە هیوای ئەوەی لاپەڕەکەت کاری پێ بکات. ئەم وانەیە دوو شت فێر دەکات کە هەموو پێویستی پێیانە: سەلامەتکردنی پێش چاپکردنی و ، کە کاتێک بە هەڵەوە دەگەڕێتەوە ئەوەی نووسیویەتی دەیپارێزن.
The course says: "There are some built-in functions that we can use to prevent form hacking." They are trim(), stripslashes() and htmlspecialchars(). You will see what each one really does — and why one of them should not be used any more.
کۆرسەکە دەڵێت: «هەندێک هەن کە دەتوانین بۆ ڕێگرتن لە هاککردنی بەکاریان بهێنین.» ئەوانیش trim() و stripslashes() و htmlspecialchars()ـن. دەبینیت هەریەکەیان بەڕاستی چی دەکات — و بۆچی یەکێکیان ئیتر نابێت بەکاربهێنرێت.
Cross-site scripting (XSS)XSS (سکریپتی نێوان تۆڕگەکان)
An attack in which someone sends as , and a page shows it without escaping it, so the script runs in other visitors' browsers. Escape output with htmlspecialchars() to stop it.
هێرشێکە کە تێیدا کەسێک کۆدی وەک دەنێرێت و لاپەڕەکە بەبێ گۆڕینی هێما تایبەتەکان پیشانی دەدات، بۆیە کۆدەکە لە تۆڕگەڕی سەردانیکەرانی تردا کارا دەبێت. بۆ ڕێگرتن لێی، دەرخستە بە htmlspecialchars() بگۆڕە.
Cross-site scripting (XSS) is a type of web security weakness that can happen in PHP and in other web technologies. It happens when an attacker can inject harmful code into the code of your web page. The usual way in is a form: the page prints what the user typed, and the browser cannot tell the difference between your HTML and HTML that the user typed. The Cybersecurity course puts XSS among the injection attacks: Cross-site scripting (XSS), briefly.
جۆرێکە لە لاوازیی وێب کە دەتوانێت لە PHP و تەکنەلۆژیاکانی تری وێبیشدا ڕووبدات. کاتێک ڕوودەدات کە هێرشبەرێک بتوانێت کۆدی زیانبەخش بخاتە ناو کۆدی لاپەڕەکەتەوە. ڕێگای باوی چوونە ژوورەوە : لاپەڕەکە ئەوە چاپ دەکات کە نووسیویەتی و ناتوانێت جیاوازی بکات لە نێوان HTMLـی تۆ و ئەو HTMLـەی نووسیویەتی. کۆرسی لەگەڵ ڕوون دەکاتەوە: XSS، بە کورتی.
Here is a welcome page that prints the name exactly as it was sent:
ئەمە لاپەڕەیەکی بەخێرهاتنە کە ناوەکە ڕێک وەک نێردراوە چاپ دەکات:
<?php
$name = $_POST["name"] ?? "";
echo "<p>Welcome " . $name . "</p>";<b style="color:red">Aram</b>بەکارهێنەر نووسیی <b style="color:red">Aram</b>Welcome Aram (Aram is shown in red bold letters)
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<p>Welcome <b style="color:red">Aram</b></p>The browser obeyed the user's tags and made the name red and bold. That looks harmless, but the same hole lets an attacker send JavaScript:
گوێڕایەڵی بوو و ناوەکەی سوور و تۆخ کرد. بێزیان دیارە، بەڵام هەمان کون ڕێگە بە هێرشبەر دەدات JavaScript بنێرێت:
<script>alert('Hacked!')</script>بەکارهێنەر نووسیی <script>alert('Hacked!')</script>Welcome (the browser runs the script and shows a box: "Hacked!")
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<p>Welcome <script>alert('Hacked!')</script></p>An alert() box is only a demonstration. A real attacker's script can read the visitor's cookies (and with them the login session), change the page, or send the visitor to a fake login page. If the text is saved — for example in a comment that every visitor sees — the attack hits every visitor.
alert() تەنها نیشاندانێکە. سکریپتی هێرشبەرێکی ڕاستەقینە دەتوانێت سەردانکەر بخوێنێتەوە (و لە ڕێگەیانەوە )، لاپەڕەکە بگۆڕێت، یان سەردانکەر بنێرێت بۆ لاپەڕەیەکی ساختەی . ئەگەر دەقەکە هەڵبگیرێت — بۆ نموونە لە تێبینییەکدا کە هەموو سەردانکەرێک دەیبینێت — هێرشەکە هەموو سەردانکەرێک دەگرێتەوە.
Tom Scott shows how text with a script tag can attack a website, and why websites must make special characters safe before showing them.
تۆم سکۆت پیشان دەدات چۆن دەقێک کە <script> تێدایە دەتوانێت هێرش بکاتە سەر و بۆچی دەبێت پێش پیشاندان نیشانە تایبەتەکان بێمەترسی بکەن.
Cross-site scripting (XSS)XSS (سکریپتی نێوان تۆڕگەکان)
The fix: escape the outputچارەسەر: گۆڕینی هێماکانی دەرخستە
The fix is one function. htmlspecialchars() converts the characters that have a meaning in HTML into . The browser then shows them as text:
چارەسەرەکە یەک . htmlspecialchars() وەک < و >، کە لە HTMLـدا واتایان هەیە، دەگۆڕێت بۆ . ئەو کاتە وەک دەق پیشانیان دەدات:
<?php
$name = $_POST["name"] ?? "";
echo "<p>Welcome " . htmlspecialchars($name) . "</p>";Welcome <script>alert('Hacked!')</script>HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<p>Welcome <script>alert('Hacked!')</script></p>Welcome <b style="color:red">Aram</b>
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<p>Welcome <b style="color:red">Aram</b></p>A four-minute demo: a script typed into a PHP form runs in the page, then htmlspecialchars() makes the browser show it as plain text.
نمایشێکی چوار خولەکی: کە لە دەنووسرێت لەناو لاپەڕەکەدا کار دەکات، پاشان htmlspecialchars() وا دەکات وەک دەقی ئاسایی پیشانی بدات.
trim(), stripslashes() and htmlspecialchars()trim() و stripslashes() و htmlspecialchars()
The course lists three functions for cleaning form input. Here is what each one does, tested in PHP 8.5.
کۆرسەکە سێ بۆ نێوخستەی ڕیز دەکات. ئەمە ئەوەیە کە هەریەکەیان دەیکات، لە PHP 8.5دا تاقیکراوەتەوە.
trim(), stripslashes() and htmlspecialchars()trim() و stripslashes() و htmlspecialchars()
trim(): remove outer spacestrim(): لابردنی بۆشاییەکانی دەرەوە
trim() removes — spaces, tabs, newlines (and the invisible NUL and vertical-tab characters) — from the start and the end of a string. It does not touch the spaces inside the text.
trim() لادەبات — واتە Space و Tab و دێڕی نوێ (هەروەها نادیارەکانی NUL و Tabـی ستوونی) — لە سەرەتا و کۆتایی . دەست لە ناوەوەی دەقەکە نادات.
<?php
echo "<pre>";
$input = " \t Hana Karim \n ";
$clean = trim($input);
var_dump($input);
var_dump($clean); // only the start and the end are cleanedstring(18) " Hana Karim " string(11) "Hana Karim"
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3
Two spaces, a tab and a space before; a space, a newline and a space after; two spaces in the middle.
دوو ، تابێک و لە پێشەوە؛ ، دێڕێکی نوێ و لە دواوە؛ دوو لە ناوەڕاستدا.
- Lineدێڕی 7
18 characters became 11: only the outer whitespace is gone.
18 بوو بە 11: تەنها دەرەکییەکان لابران.
trim() is useful: a user who types " Dilan " by mistake should be treated as "Dilan", and a field that contains only spaces should count as empty.
trim() بەسوودە: کە بە هەڵە " Dilan " دەنووسێت دەبێت وەک "Dilan" مامەڵەی لەگەڵ بکرێت و خانەیەک کە تەنها تێدا بێت دەبێت بە بەتاڵ دابنرێت.
trim(), stripslashes() and htmlspecialchars()trim() و stripslashes() و htmlspecialchars()
stripslashes(): a leftover from old PHPstripslashes(): پاشماوەیەک لە PHPـی کۆن
stripslashes() removes backslashes (\) that were added in front of quotes: O\'Reilly becomes O'Reilly, and a double backslash \\ becomes one.
stripslashes() (\) لادەبات کە لە پێش زیاد کراون: O\'Reilly دەبێتە O'Reilly و دوو \\ دەبێتە یەک.
<?php
echo stripslashes("O\\'Reilly") . "<br>"; // what old "magic quotes" added
echo stripslashes("C:\\Users\\hana\\notes") . "<br>"; // a real Windows path
echo stripslashes("2 \\ 3 = ?"); // a real backslashO'Reilly C:Usershananotes 2 3 = ?
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
O'Reilly<br>C:Usershananotes<br>2 3 = ?Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
Removes the backslash that old PHP added before a quote — the only job it was made for.
لادەبات کە PHPـی کۆن لە پێش گوتەیەکەوە زیادی دەکرد — تاکە کارێک کە بۆی دروست کرابوو.
- Lineدێڕی 3-4
But it also destroys backslashes the user really typed: a Windows path and a maths text are damaged.
بەڵام لەناو دەبات کە بەڕاستی نووسیونی: Windows و دەقێکی بیرکاری تێکدەچن.
trim(), stripslashes() and htmlspecialchars()trim() و stripslashes() و htmlspecialchars()
htmlspecialchars(): make text safe for HTMLhtmlspecialchars(): دەق بۆ HTML سەلامەت بکە
htmlspecialchars() converts special characters to HTML entities. It replaces characters that mean something in HTML, such as < and >, with codes such as < and >. This prevents attackers from injecting HTML or JavaScript code through forms.
htmlspecialchars() تایبەتەکان دەگۆڕێت بۆ . ئەو نووسانەی لە HTMLـدا واتایان هەیە، وەک < و >، بە کۆدی وەک < و > دەگۆڕێتەوە. ئەمە ڕێگە لە هێرشبەران دەگرێت کە لە ڕێگەی کۆدی HTML یان JavaScript تێبخزێنن.
| Character | Becomesدەبێتە | Whyبۆچی |
|---|---|---|
& | & | Starts every entity, so it must be escaped first.هەموو بەم هێمایە دەست پێدەکات، بۆیە دەبێت سەرەتا بگۆڕدرێت. |
< | < | Would open a tag. دەکاتەوە. |
> | > | Would close a tag. دادەخات. |
" | " | Would end an attribute value like value="…". وەک value="…" کۆتایی پێدەهێنێت. |
' | ' | Would end an attribute value like value='…' (escaped by default since PHP 8.1). وەک value='…' کۆتایی پێدەهێنێت (لە PHP 8.1ـەوە بە شێوەی بنەڕەتی دەگۆڕدرێت). |
<?php
$input = "<script>alert('Hi') & \"bye\"</script>";
echo htmlspecialchars($input);<script>alert('Hi') & "bye"</script>HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<script>alert('Hi') & "bye"</script>The course's test_input() functionکرداری test_input()ـی کۆرسەکە
To use these functions on every field, the course creates one and passes each value from the form through it. The function takes one — the user's input — and gives back the cleaned text with return:
بۆ بەکارهێنانی ئەم لەسەر هەموو خانەیەک، کۆرسەکە دروست دەکات و هەر بەناویدا تێدەپەڕێنێت. یەک وەردەگرێت — — و دەقە پاککراوەکە بە return دەگەڕێنێتەوە:
test_input() as in the lecturetest_input() وەک لە وانەکەداindex.phpPHPfunction test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
Remove spaces, tabs and newlines at both ends.
، تاب و دێڕی نوێ لە هەردوو سەرەوە لاببە.
- Lineدێڕی 3
Remove backslashes (outdated, see above).
لاببە (کۆنە، بڕوانە سەرەوە).
- Lineدێڕی 4
Turn
< > & " 'into HTML entities.< > & " 'بگۆڕە بۆ .- Lineدێڕی 5
Give the result back to the caller.
ئەنجامەکە بگەڕێنەوە بۆ ئەو شوێنەی بانگی کردووە.
The lab writes the same function with a comment on each line:
تاقیگەکە هەمان بە لەسەر هەر دێڕێک دەنووسێت:
test_input() as in the labtest_input() وەک لە تاقیگەکەداindex.phpPHPfunction test_input($data) {
//it removes white space
$data = trim($data);
// deals with backlashes
$data = stripslashes($data);
//convert html tage to special characters
$data = htmlspecialchars($data);
//finally return the data
return $data;
}
?>Let us run the function on four inputs:
با لەسەر چوار نێوخستە تاقی بکەینەوە:
<?php
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
echo test_input(" <b>Aram</b> ") . "<br>";
echo test_input("Tom & \"Jerry\" 'x'") . "<br>";
echo test_input("C:\\Users\\aram") . "<br>";
echo TEST_INPUT(" works in capitals too ");<b>Aram</b> Tom & "Jerry" 'x' C:Usersaram works in capitals too
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<b>Aram</b><br>Tom & "Jerry" 'x'<br>C:Usersaram<br>works in capitals tooExplain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 9
The tags are escaped and the outer spaces are gone.
گۆڕدراون و دەرەکییەکان نەماون.
- Lineدێڕی 10
Quotes and
&become entities.و
&دەبنە .- Lineدێڕی 11
The path
C:\Users\aramlost its backslashes:stripslashes()damaged real data.C:\Users\aramهێڵە لارەکانی لەدەستدا:stripslashes()زانیاریی ڕاستەقینەی تێکدا.- Lineدێڕی 12
Function names are not case-sensitive, so
TEST_INPUT()callstest_input()(the lab text calls itTEST_INPUT()). Write one spelling.ناوی هەستیار نین بە قەبارەی پیت، بۆیە
TEST_INPUT()بانگیtest_input()دەکات (دەقی تاقیگەکە ناوی دەنێتTEST_INPUT()). یەک ڕێنووس بنووسە.
The course's test_input() functionکرداری test_input()ـی کۆرسەکە
The modern way: clean on input, escape on outputڕێگا نوێیەکە: لە نێوخستەدا پاک بکەرەوە، لە دەرخستەدا هێماکان بگۆڕە
Today's rule is simple: when the data comes in, trim() it and validate it; keep the real text in your variables. When the data goes out into HTML, call htmlspecialchars() at that moment.
یاسای ئەمڕۆ سادەیە: کاتێک زانیارییەکان دێنە ژوورەوە، trim()یان بکە و پشتڕاستیان بکەرەوە؛ دەقە ڕاستەقینەکە لەناو بهێڵەوە. کاتێک زانیارییەکان دەچنە دەرەوە بۆ ناو HTML، لەو ساتەدا htmlspecialchars() بانگ بکە.
<?php
$name = "";
$nameErr = "";
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$name = trim($_POST["name"] ?? ""); // 1. clean: remove outer spaces
if ($name === "") { // 2. validate the real value
$nameErr = "Name is required";
}
}
?>
<form method="post" action="">
Name: <input type="text" name="name" value="<?php echo htmlspecialchars($name); ?>">
<span class="error"><?php echo $nameErr; ?></span>
<input type="submit" value="Send">
</form>
<?php if ($name !== "" && $nameErr === "") { ?>
<p>Hello, <?php echo htmlspecialchars($name); ?>!</p>
<?php } ?> Aram "Ari" <b> (with spaces around it)بەکارهێنەر Aram "Ari" <b> ـی نارد (لەگەڵ بۆشایی لە دەوری)Name: [Aram "Ari" <b>] [Send] Hello, Aram "Ari" <b>!
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post" action="">
Name: <input type="text" name="name" value="Aram "Ari" <b>">
<span class="error"></span>
<input type="submit" value="Send">
</form>
<p>Hello, Aram "Ari" <b>!</p>Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 6
Input: clean (trim) and keep the real text.
نێوخستە: پاکی بکەرەوە (trim) و دەقە ڕاستەقینەکە بپارێزە.
- Lineدێڕی 8
Validate the real value.
ڕاستەقینەکە پشتڕاست بکەرەوە.
- Lineدێڕی 14, 19
Output: escape exactly where the text is printed — in the attribute and in the page.
: ڕێک لەو شوێنەی دەقەکە چاپ دەکرێت هێماکانی بگۆڕە — لەناو و لەناو لاپەڕەکەدا.
Exercise 4: validation using test_input()ڕاهێنانی ٤: پشتڕاستکردنەوە بە test_input()
Lecture 5 and Lab 5 (Exercise 4) put the pieces together: the if … elseif chain from the validation lecture checks the fields, and in the final else every value goes through test_input() before it is printed. Corrected and complete:
وانەی ٥ و تاقیگەی ٥ (ڕاهێنانی ٤) پارچەکان پێکەوە دەلکێنن: زنجیرەی if … elseif لە وانەی پشتڕاستکردنەوە خانەکان دەپشکنێت و لە elseـی کۆتاییدا هەموو پێش چاپکردن بە test_input()دا تێدەپەڕێت. ڕاستکراوە و تەواو:
<?php
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
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 = test_input($_POST["name"]);
$email = test_input($_POST["email"]);
$website = test_input($_POST["website"]);
$comment = test_input($_POST["comment"]);
$gender = test_input($_POST["gender"]);
echo "Your inputs are: $name $email $gender $website $comment";
}
}
?> Karwan <b>ناو نێردرا وەک Karwan <b>Your inputs are: Karwan <b> karwan@example.com male example.com I like PHP
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Your inputs are: Karwan <b> karwan@example.com male example.com I like PHPExplain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2-7
The function must be defined in the same file (any place works, because PHP registers functions before running the script). Here
stripslashes()is kept only to match the course.دەبێت لە هەمان پێناسە کرابێت (هەر شوێنێک کار دەکات، چونکە PHP پێش کارپێکردنی تۆمار دەکات). لێرەدا
stripslashes()تەنها بۆ گونجان لەگەڵ کۆرسەکە هێڵراوەتەوە.- Lineدێڕی 21-25
Every value is cleaned and escaped before it is printed.
هەموو پێش چاپکردن پاک دەکرێتەوە و هێماکانی دەگۆڕدرێن.
Look at the output: the spaces before "Karwan" are gone and <b> arrived as <b>, so the browser shows the text <b> instead of making the rest of the page bold.
سەیری بکە: پێش «Karwan» نەماون و <b> وەک <b> گەیشت، بۆیە دەقی <b> پیشان دەدات لە جیاتی ئەوەی باقیی لاپەڕەکە تۆخ بکات.
Sticky formsفۆرمە لکاوەکان
A form that keeps the values the user typed when it comes back with errors, so the user does not have to type everything again. In PHP you print the old value back into each field.
فۆرمێکە کە کاتێک بە هەڵەوە دەگەڕێتەوە، ئەو نرخانەی بەکارهێنەر نووسیبوونی دەپارێزێت، تاکو پێویست نەکات هەموو شتێک دووبارە بنووسێتەوە. لە PHPـدا نرخە کۆنەکە دەخەیتەوە ناو هەر خانەیەک.
A sticky form is simply a standard HTML form that remembers how you filled it out, even when there were errors in the submission. This is especially nice for users when they must send the form again after filling it out incorrectly the first time: they only fix the mistake, instead of typing everything again.
بە سادەیی ئاسایی HTMLـە کە لەبیری دەمێنێت چۆن پڕت کردەوە، تەنانەت کاتێک لە ناردنەکەدا هەڵە هەبووە. ئەمە بەتایبەتی بۆ خۆشە کاتێک دەبێت دوای پڕکردنەوەی نادروستی یەکەمجار دووبارە بنێرنەوە: تەنها هەڵەکە چاک دەکەنەوە، لە جیاتی ئەوەی هەموو شتێک دووبارە بنووسنەوە.
You hand a long application form to a clerk at the passport office. One box is wrong. A bad clerk tears up the whole form and gives you an empty one. A good clerk gives your form back, circles the wrong box and says "only fix this". A sticky form is the good clerk.
داواکاریی درێژ دەدەیتە فەرمانبەرێک لە فەرمانگەی پاسپۆرت. یەک خانە هەڵەیە. فەرمانبەرێکی خراپ هەموو دەدڕێنێت و بەتاڵت دەداتێ. فەرمانبەرێکی باش دەداتەوە، بازنەیەک بە دەوری خانە هەڵەکەدا دەکێشێت و دەڵێت «تەنها ئەمە چاک بکەرەوە». فەرمانبەرە باشەکەیە.
Where the analogy stops workingسنووری ئەم نموونەیە
The clerk remembers your form by himself. PHP remembers nothing between requests: the page is built again from scratch, so your code must print every old value back into the form.
فەرمانبەرەکە خۆی لەبیر دەمێنێت. بەڵام PHP لە نێوان هیچ لەبیر ناکات: لاپەڕەکە لە سەرەتاوە دووبارە دروست دەکرێتەوە، بۆیە کۆدەکەت دەبێت هەموو کۆن دووبارە بخاتەوە ناو .
The lab says: "To create a sticky form we write one line of PHP code inside the value attribute of every HTML form input." That is true for text boxes, but each kind of control is refilled differently:
تاقیگەکە دەڵێت: «بۆ دروستکردنی ، یەک دێڕ کۆدی PHP لەناو valueـی هەموو نێوخستەیەکی HTMLـدا دەنووسین.» ئەمە بۆ ڕاستە، بەڵام هەر جۆرە بە شێوەیەکی جیاواز پڕ دەکرێتەوە:
| Control | How PHP refills itPHP چۆن پڕی دەکاتەوە |
|---|---|
| Text, e-mail, password-less inputs و (نەک ) | value="<?php echo htmlspecialchars($name); ?>" |
<textarea …><?php echo htmlspecialchars($comment); ?></textarea> | |
<?php if ($gender === "female") echo "checked"; ?> | |
<?php if ($java) echo "checked"; ?> | |
| optionبژاردەیەک لە | <option … <?php if ($color === "Red") echo "selected"; ?>> |
| Password field | Never refill it. Let the user type the password again.هەرگیز دووبارە پڕی مەکەرەوە. با دووبارە بنووسێتەوە. |
Making a sticky form: the fields keep what the user typed after an error, with empty starting variables and htmlspecialchars() on output.
دروستکردنی : دوای ئەوەی نووسیویەتی دەپارێزن؛ لە سەرەتادا بەتاڵ دادەنێیت و لە htmlspecialchars() بەکاردەهێنیت.
From 5:02: keeping typed values in the form after an error
لە 5:02 بەدواوە: هێشتنەوەی لە دوای .
Sticky formsفۆرمە لکاوەکان
The course's sticky form, and why it warnsفۆرمی لکاوی کۆرسەکە و بۆچی ئاگادار دەکاتەوە
The course example ("just HTML form code") prints a variable into every field: value="<?php echo $name;?>" for the text boxes, $comment between the textarea tags, and checked for the matching radio button. The trouble starts on the first visit: nothing was sent yet, so $name and $comment do not exist. Here is the core of it:
نموونەکەی کۆرسەکە («تەنها کۆدی HTML») لەناو هەموو خانەیەکدا چاپ دەکات: value="<?php echo $name;?>" بۆ ، $comment لە نێوان <textarea>دا و checked بۆ دوگمە ڕادیۆ گونجاوەکە. کێشەکە لە یەکەم سەرداندا دەست پێدەکات: هێشتا هیچ نەنێردراوە، بۆیە $name و $comment بوونیان نییە. ئەمە کرۆکەکەیەتی:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Name: <input type="text" name="name" value="<?php echo $name;?>">
<br><br>
Comment: <textarea name="comment" rows="5" cols="40"><?php echo $comment;?></textarea>
</form>HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post" action="/form_handling/index.php">
Name: <input type="text" name="name" value="<br />
<b>Warning</b>: Undefined variable $name in <b>C:\xampp\htdocs\form_handling\index.php</b> on line <b>2</b><br />
">
<br><br>
Comment: <textarea name="comment" rows="5" cols="40"><br />
<b>Warning</b>: Undefined variable $comment in <b>C:\xampp\htdocs\form_handling\index.php</b> on line <b>4</b><br />
</textarea>
</form>With display_errors on (as in XAMPP), PHP prints the warning as HTML — and here that HTML lands inside the value attribute and inside the textarea.
کاتێک display_errors چالاکە (وەک لە XAMPP)، PHP وەک HTML چاپ دەکات — و لێرەدا ئەو HTMLـە دەکەوێتە ناو value و ناو .
Sticky formsفۆرمە لکاوەکان
The lab's sticky form: two more bugsفۆرمی لکاوی تاقیگەکە: دوو باگی تر
The lab (Exercise 5) writes each text field like this:
تاقیگەکە (ڕاهێنانی ٥) هەر بەم شێوەیە دەنووسێت:
Name: <input type="text" name="name" value="<?php
if(isset($_POST[“name”])) echo $name;?>">With straight quotes it runs, but there is a logic bug. The test asks "was name sent?", but then prints $name — a variable that the lab's validation code creates only in its final else, when every field was valid. When the user made a mistake (exactly when the sticky form is needed), $name does not exist:
بە ڕاست کار دەکات، بەڵام لۆجیکی هەیە. پشکنینەکە دەپرسێت «ئایا name نێردرا؟»، بەڵام پاشان $name چاپ دەکات — کە کۆدی تاقیگەکە تەنها لە elseـی کۆتاییدا دروستی دەکات، کاتێک هەموو خانەکان دروست بوون. کاتێک هەڵەیەکی کردووە (ڕێک ئەو کاتەی پێویستە)، $name بوونی نییە:
<?php
// The validation stopped early (email was empty), so $name was never set.
?>
Name: <input type="text" name="name" value="<?php if(isset($_POST["name"])) echo $name;?>">HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Name: <input type="text" name="name" value="<br />
<b>Warning</b>: Undefined variable $name in <b>C:\xampp\htdocs\forms\index.php</b> on line <b>4</b><br />
">The fix used in the complete program below: give every variable a starting value at the top, fill it from $_POST before validating, and print it with htmlspecialchars(). Then the value is there whether the checks pass or fail. (A short alternative for one field: value="<?php echo htmlspecialchars($_POST["name"] ?? ""); ?>".) The PHP that sets these variables must also come before the form in the file: PHP runs from top to bottom, so a variable printed in the form must already exist.
ئەو چارەسەرەی لە تەواوەکەی خوارەوەدا بەکارهاتووە: لە سەرەوە سەرەتایی بدە بە هەموو ، پێش لە $_POSTـەوە پڕی بکەرەوە و بە htmlspecialchars() چاپی بکە. ئەو کاتە هەیە، جا پشکنینەکان سەرکەوتوو بن یان نا. (جێگرەوەیەکی کورت بۆ یەک خانە: value="<?php echo htmlspecialchars($_POST["name"] ?? ""); ?>".) هەروەها ئەو PHPـەی ئەم دادەنێت دەبێت لە پێش بێت: PHP لە سەرەوە بۆ خوارەوە کار دەکات، بۆیە ئەو لەناو چاپ دەکرێت دەبێت پێشتر هەبێت.
Sticky formsفۆرمە لکاوەکان
A complete sticky form with validationفۆرمێکی لکاوی تەواو لەگەڵ پشتڕاستکردنەوە
This program joins everything from Lecture 5 and Lab 5: the form (Example 3), validation with a message next to each field, cleaning, and stickiness (Exercise 5) — written the modern way (trim on input, htmlspecialchars() on output).
ئەم هەموو شتێکی وانەی ٥ و تاقیگەی ٥ پێکەوە دەلکێنێت: (نموونەی ٣)، لەگەڵ پەیامێک لە تەنیشت هەر خانەیەکەوە، و لکاوبوون (ڕاهێنانی ٥) — بە ڕێگا نوێیەکە نووسراوە (trim لە نێوخستەدا، htmlspecialchars() لە ).
<?php
// 1. Start with empty values, so the form works on the first visit
$name = $email = $website = $comment = $gender = "";
$nameErr = $emailErr = $genderErr = "";
// 2. When the form was sent, read, clean and check every field
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$name = trim($_POST["name"] ?? "");
$email = trim($_POST["email"] ?? "");
$website = trim($_POST["website"] ?? "");
$comment = trim($_POST["comment"] ?? "");
$gender = $_POST["gender"] ?? "";
if ($name === "") {
$nameErr = "Name is required";
}
if ($email === "") {
$emailErr = "Email is required";
} elseif (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$emailErr = "Invalid email format";
}
if ($gender !== "female" && $gender !== "male") {
$gender = "";
$genderErr = "Gender is required";
}
}
?>
<form method="post" action="">
Name: <input type="text" name="name" value="<?php echo htmlspecialchars($name); ?>">
<span class="error">* <?php echo $nameErr; ?></span>
<br><br>
E-mail: <input type="text" name="email" value="<?php echo htmlspecialchars($email); ?>">
<span class="error">* <?php echo $emailErr; ?></span>
<br><br>
Website: <input type="text" name="website" value="<?php echo htmlspecialchars($website); ?>">
<br><br>
Comment: <textarea name="comment" rows="5" cols="40"><?php echo htmlspecialchars($comment); ?></textarea>
<br><br>
Gender:
<input type="radio" name="gender" value="female" <?php if ($gender === "female") echo "checked"; ?>>Female
<input type="radio" name="gender" value="male" <?php if ($gender === "male") echo "checked"; ?>>Male
<span class="error">* <?php echo $genderErr; ?></span>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>
<?php
// 3. Show the result only when there are no errors
if ($_SERVER["REQUEST_METHOD"] === "POST" && $nameErr === "" && $emailErr === "" && $genderErr === "") {
echo "<h3>Your input:</h3>";
echo htmlspecialchars($name) . "<br>";
echo htmlspecialchars($email) . "<br>";
echo htmlspecialchars($website) . "<br>";
echo nl2br(htmlspecialchars($comment)) . "<br>";
echo $gender;
}
?>Name: [Hana] * E-mail: [hana@example] * Invalid email format Website: [ ] Comment: [I like this "course"] Gender: ( ) Female ( ) Male * Gender is required [Submit]
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post" action="">
Name: <input type="text" name="name" value="Hana">
<span class="error">* </span>
<br><br>
E-mail: <input type="text" name="email" value="hana@example">
<span class="error">* Invalid email format</span>
<br><br>
Website: <input type="text" name="website" value="">
<br><br>
Comment: <textarea name="comment" rows="5" cols="40">I like this "course"</textarea>
<br><br>
Gender:
<input type="radio" name="gender" value="female" >Female
<input type="radio" name="gender" value="male" >Male
<span class="error">* Gender is required</span>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3-4
Starting values: no "undefined variable" warnings on the first visit.
سەرەتایی: لە یەکەم سەرداندا هیچ « پێناسەنەکراو» نییە.
- Lineدێڕی 8-12
Read and trim every field before validating, so the values exist even when there are errors.
هەموو خانەیەک پێش بخوێنەوە و trimـی بکە، تاکو هەبن تەنانەت کاتێک هەڵە هەیە.
- Lineدێڕی 19
filter_var()checks the e-mail format.filter_var()شێوەی دەپشکنێت.- Lineدێڕی 22-25
Accept only the two real values; anything else (or nothing) is an error.
تەنها دوو ڕاستەقینەکە وەربگرە؛ هەر شتێکی تر (یان هیچ) هەڵەیە.
- Lineدێڕی 29, 32, 35
Text boxes: the old value goes into
value="…", escaped.: کۆنەکە دەچێتە ناو
value="…"، دوای گۆڕینی هێماکان.- Lineدێڕی 37
Textarea: the old text goes between the tags, escaped.
: دەقە کۆنەکە دەچێتە نێوان ، دوای گۆڕینی هێماکان.
- Lineدێڕی 40-41
Radio buttons: print
checkedin the one that matches.: لەو دوگمەیەی دەگونجێت
checkedچاپ بکە.- Lineدێڕی 48-55
Show the result only when there is no error.
nl2br()keeps the line breaks of the comment.ئەنجامەکە تەنها کاتێک پیشان بدە کە هیچ هەڵەیەک نەبێت.
nl2br()دێڕە نوێیەکانی تێبینییەکە دەپارێزێت.
Name: [Hana] * E-mail: [hana@example.com] * Website: [hana.example.com] Comment: [Thanks! / See you.] Gender: (•) Female ( ) Male * [Submit] Your input: Hana hana@example.com hana.example.com Thanks! See you. female
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post" action="">
Name: <input type="text" name="name" value="Hana">
<span class="error">* </span>
<br><br>
E-mail: <input type="text" name="email" value="hana@example.com">
<span class="error">* </span>
<br><br>
Website: <input type="text" name="website" value="hana.example.com">
<br><br>
Comment: <textarea name="comment" rows="5" cols="40">Thanks!
See you.</textarea>
<br><br>
Gender:
<input type="radio" name="gender" value="female" checked>Female
<input type="radio" name="gender" value="male" >Male
<span class="error">* </span>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>
<h3>Your input:</h3>Hana<br>hana@example.com<br>hana.example.com<br>Thanks!<br />
See you.<br>femaleFind the bugs: a sticky form with checkboxesباگەکان بدۆزەوە: فۆرمێکی لکاو بە چێکبۆکسەوە
Two students extended the lab's sticky form with two checkboxes for programming skills. Their code is a good test of everything in this lecture.
دوو خوێندکار تاقیگەکەیان بە دوو بۆ شارەزایی فراوان کرد. کۆدەکەیان تاقیکردنەوەیەکی باشە بۆ هەموو ئەوەی لەم وانەیەدایە.
This page reads the fields, avoids warnings for the radio button and the checkboxes with !empty(), shows "Please enter your name" next to an empty name, and echoes "Java is not checked." Find four problems. Hint: what happens if the user types Soran"> as the name? What is inside the textarea on the very first visit?
ئەم لاپەڕەیە خانەکان دەخوێنێتەوە، بە !empty() لە و دوور دەکەوێتەوە، لە تەنیشت ناوێکی بەتاڵەوە «Please enter your name» پیشان دەدات و «Java is not checked.» چاپ دەکات. چوار کێشە بدۆزەوە. یارمەتی: چی ڕوودەدات ئەگەر Soran"> وەک ناو بنووسێت؟ لە یەکەم سەرداندا چی لەناو ؟
<?php
if (isset($_POST['submit'])) {
$name = $_POST["name"];
$comment = $_POST['comment'];
//AVOIDING WARNING
if (!empty($_POST['gender'])) {
$gender = $_POST['gender'];
}
if (!empty($_POST['java'])) {
$java = $_POST['java'];
}
if (!empty($_POST['swift'])) {
$swift = $_POST['swift'];
}
//VALIDATION
if (empty($name)) {
$name_error = "Please enter your name";
}
if (empty($java)) {
echo "Java is not checked.";
}
}
?>
<form method="post">
Name: <input type="text" id="name" name="name" value="<?php if (isset($name)) echo $name; ?>">
<?php if (isset($name_error)) echo $name_error; ?><br /><br />
Comment: <textarea name="comment" rows="5" cols="40"> <?php if (isset($comment)) echo $comment; ?> </textarea>
<br /><br />
Gender:
<input type="radio" name="gender" <?php if (isset($gender) && $gender == "female") echo "checked"; ?> value="female"> Female
<input type="radio" name="gender" <?php if (isset($gender) && $gender == "male") echo "checked"; ?> value="male"> Male
<br /><br />
Programming Skills: <br>
Java: <input type="checkbox" name="java" <?php if (isset($java)) echo "checked"; ?> value="java"><br>
Swift: <input type="checkbox" name="swift" <?php if (isset($swift)) echo "checked"; ?> value="swift"><br>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>Show answerوەڵامەکە پیشان بدە
Soran">, Male and only Swift tickedبە ناوی Soran">، Male و تەنها Swiftـی نیشانەکراو نێردراHTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Java is not checked.
<form method="post">
Name: <input type="text" id="name" name="name" value="Soran">">
<br /><br />
Comment: <textarea name="comment" rows="5" cols="40"> Hi </textarea>
<br /><br />
Gender:
<input type="radio" name="gender" value="female"> Female
<input type="radio" name="gender" checked value="male"> Male
<br /><br />
Programming Skills: <br>
Java: <input type="checkbox" name="java" value="java"><br>
Swift: <input type="checkbox" name="swift" checked value="swift"><br>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>- No escaping (XSS). The name is printed raw into
value="…". The">typed by the user closes the attribute and the tag, and the rest appears on the page. Usehtmlspecialchars($name). - Extra spaces in the textarea. There is a space before and after
<?php … ?>inside<textarea>. Those spaces become part of the text, so even on the first visit the box contains two spaces, and every submit adds more around the comment. Put the PHP directly against the tags. - Only Java is checked, and the message is printed above the form instead of next to the field. Swift is never mentioned. Better: "Choose at least one skill" when neither is ticked.
- No
trim(): a name of only spaces is accepted. (Leaving outactionis fine: the form posts to the same page.)
- بێ گۆڕینی هێماکان (XSS). ناوەکە بە خاوی لەناو
value="…"دا چاپ دەکرێت. ئەو">ـەی نووسیویەتی و دادەخات و باقییەکەی لەسەر لاپەڕەکە دەردەکەوێت.htmlspecialchars($name)بەکاربهێنە. - زیادە لە . لەناو
<textarea>دا لە پێش و دوای<?php … ?>هەیە. ئەو دەبنە بەشێک لە دەقەکە، بۆیە تەنانەت لە یەکەم سەردانیشدا دوو تێدایە و هەر ناردنێک زیاتر لە دەوری تێبینییەکە زیاد دەکات. PHPـەکە ڕاستەوخۆ بە بلکێنە. - تەنها Java دەپشکنرێت و پەیامەکە لە سەرەوەی چاپ دەکرێت لە جیاتی تەنیشت خانەکە. Swift هەرگیز باس ناکرێت. باشتر: «Choose at least one skill» کاتێک هیچ کامیان نیشانە نەکرابن.
trim()نییە: ناوێک کە تەنها بێت وەردەگیرێت. (نەنووسینیactionدروستە: بۆ هەمان لاپەڕە دەنێردرێت.)
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post">
Name: <input type="text" id="name" name="name" value="">
<br /><br />
Comment: <textarea name="comment" rows="5" cols="40"> </textarea>
<br /><br />
Gender:
<input type="radio" name="gender" value="female"> Female
<input type="radio" name="gender" value="male"> Male
<br /><br />
Programming Skills: <br>
Java: <input type="checkbox" name="java" value="java"><br>
Swift: <input type="checkbox" name="swift" value="swift"><br>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>The second student's form is the same, but the last check is different. What does the user see when no skill is ticked?
خوێندکاری دووەم هەمان شتە، بەڵام دوایین پشکنین جیاوازە. کاتێک هیچ شارەزاییەک نیشانە نەکراوە چی دەبینێت؟
if (empty($java) && empty($swift)) {
}Show answerوەڵامەکە پیشان بدە
Nothing at all. The idea ("at least one skill must be ticked") is right, but the if block is empty, so no message is shown. All the problems of answer 1 (no escaping, spaces in the textarea) are here too.
هیچ شتێک. بیرۆکەکە («لانیکەم یەک شارەزایی دەبێت نیشانە بکرێت») دروستە، بەڵام بلۆکی ifـەکە بەتاڵە، بۆیە هیچ پەیامێک پیشان نادرێت. هەموو کێشەکانی وەڵامی ١ (بێ گۆڕینی هێماکان، لە ) لێرەشدا هەن.
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post">
Name: <input type="text" id="name" name="name" value="Soran">
<br /><br />
Comment: <textarea name="comment" rows="5" cols="40"> Hi </textarea>
<br /><br />
Gender:
<input type="radio" name="gender" value="female"> Female
<input type="radio" name="gender" checked value="male"> Male
<br /><br />
Programming Skills: <br>
Java: <input type="checkbox" name="java" value="java"><br>
Swift: <input type="checkbox" name="swift" value="swift"><br>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>A corrected version
وەشانێکی ڕاستکراوە
<?php
$name = $comment = $gender = "";
$java = $swift = false;
$nameErr = $skillsErr = "";
if (isset($_POST["submit"])) {
$name = trim($_POST["name"] ?? "");
$comment = trim($_POST["comment"] ?? "");
$gender = $_POST["gender"] ?? ""; // not sent if no radio is chosen
$java = isset($_POST["java"]); // not sent if not ticked
$swift = isset($_POST["swift"]);
if ($name === "") {
$nameErr = "Please enter your name";
}
if (!$java && !$swift) {
$skillsErr = "Choose at least one skill";
}
}
?>
<form method="post" action="">
Name: <input type="text" name="name" value="<?php echo htmlspecialchars($name); ?>">
<span class="error"><?php echo $nameErr; ?></span><br><br>
Comment: <textarea name="comment" rows="5" cols="40"><?php echo htmlspecialchars($comment); ?></textarea>
<br><br>
Gender:
<input type="radio" name="gender" value="female" <?php if ($gender === "female") echo "checked"; ?>> Female
<input type="radio" name="gender" value="male" <?php if ($gender === "male") echo "checked"; ?>> Male
<br><br>
Programming skills:<br>
Java: <input type="checkbox" name="java" value="java" <?php if ($java) echo "checked"; ?>><br>
Swift: <input type="checkbox" name="swift" value="swift" <?php if ($swift) echo "checked"; ?>><br>
<span class="error"><?php echo $skillsErr; ?></span>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>Name: [ ] Please enter your name Comment: [Hi] Gender: ( ) Female (•) Male Programming skills: Java: [ ] Swift: [ ] Choose at least one skill [Submit]
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post" action="">
Name: <input type="text" name="name" value="">
<span class="error">Please enter your name</span><br><br>
Comment: <textarea name="comment" rows="5" cols="40">Hi</textarea>
<br><br>
Gender:
<input type="radio" name="gender" value="female" > Female
<input type="radio" name="gender" value="male" checked> Male
<br><br>
Programming skills:<br>
Java: <input type="checkbox" name="java" value="java" ><br>
Swift: <input type="checkbox" name="swift" value="swift" ><br>
<span class="error">Choose at least one skill</span>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2-4
Starting values; the checkboxes are booleans.
سەرەتایی؛ .
- Lineدێڕی 9-11
An unchosen radio button and unticked checkboxes are not sent:
??andisset()handle that without warnings.هەڵنەبژێردراو و نیشانە نەکراو نانێردرێن:
??وisset()بەبێ مامەڵەی لەگەڵ دەکەن.- Lineدێڕی 16-18
"At least one skill" — the rule the second student wanted.
«لانیکەم یەک شارەزایی» — ئەو یاسایەی خوێندکاری دووەم دەیویست.
Name: [Soran] Comment: [Hi] Gender: ( ) Female (•) Male Programming skills: Java: [ ] Swift: [x] [Submit]
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post" action="">
Name: <input type="text" name="name" value="Soran">
<span class="error"></span><br><br>
Comment: <textarea name="comment" rows="5" cols="40">Hi</textarea>
<br><br>
Gender:
<input type="radio" name="gender" value="female" > Female
<input type="radio" name="gender" value="male" checked> Male
<br><br>
Programming skills:<br>
Java: <input type="checkbox" name="java" value="java" ><br>
Swift: <input type="checkbox" name="swift" value="swift" checked><br>
<span class="error"></span>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>Common mistakesهەڵە باوەکان
- Printing user input without
htmlspecialchars()— in the page, invalue="…"or in a textarea. - Escaping twice:
test_input()on input andhtmlspecialchars()on output shows&lt;to the user. Escape once, at output. - Using
stripslashes()on modern PHP — it deletes real backslashes. - Believing
htmlspecialchars()protects the database. SQL needs prepared statements. - Sticky variables that do not exist yet →
Undefined variablewarnings inside the fields. Initialise them. - Filling sticky variables only when everything is valid — then they are missing exactly when they are needed.
- Spaces around
<?php … ?>inside<textarea>. - Refilling the password field. Never print a password back.
- Curly quotes (
“name”) copied from a document: fatal error. - Typos in function names (
text_input,Striplashed): fatal error or a function that does not exist.
- چاپکردنی بەبێ
htmlspecialchars()— لەناو لاپەڕەکە، لەناوvalue="…"یان لەناو . - دوو جار گۆڕینی هێماکان:
test_input()لە نێوخستەدا وhtmlspecialchars()لە&lt;بە پیشان دەدات. یەک جار، لە ، بیگۆڕە. - بەکارهێنانی
stripslashes()لە PHPـی نوێدا — هێڵە لارە ڕاستەقینەکان دەسڕێتەوە. - باوەڕکردن بەوەی
htmlspecialchars()دەپارێزێت. SQL پێویستی بە هەیە. - لکاوەکان کە هێشتا بوونیان نییە ←
Undefined variableلەناو خانەکاندا. سەرەتاییان پێ بدە. - پڕکردنەوەی لکاوەکان تەنها کاتێک هەموو شتێک دروستە — ئەو کاتە ڕێک لەو کاتەدا نین کە پێویستن.
- لە دەوری
<?php … ?>لەناو<textarea>. - دووبارە پڕکردنەوەی . هەرگیز دووبارە چاپ مەکەرەوە.
- چەماوە (
“name”) کە لە بەڵگەنامەیەکەوە کۆپی کراون: . - هەڵەی نووسین لە ناوی (
text_input،Striplashed): یان کە بوونی نییە.
Practiceڕاهێنان
Write the form with name, e-mail, website, comment (textarea, 5 rows, 40 columns), gender (two radio buttons) and a submit button. It must post to the same page using htmlspecialchars($_SERVER["PHP_SELF"]). Then write the PHP that validates it with isset(), empty() and an if … elseif chain.
بنووسە بە ناو، ، ماڵپەڕ، تێبینی (، 5 دێڕ، 40 ستوون)، ڕەگەز (دوو ) و . دەبێت بە بەکارهێنانی htmlspecialchars($_SERVER["PHP_SELF"]) بۆ هەمان لاپەڕە بنێردرێت. پاشان PHPـەکە بنووسە کە بە isset()، empty() و زنجیرەیەکی if … elseif پشتڕاستی بکاتەوە.
Show answerوەڵامەکە پیشان بدە
Put the PHP block above the form in one index.php (the form is explained in form handling, the chain in form validation). Corrected version:
بلۆکی PHPـەکە لە سەرەوەی لە یەک index.phpدا دابنێ ( لە مامەڵەکردن لەگەڵ فۆرم و زنجیرەکە لە پشتڕاستکردنەوەی فۆرمدا ڕوون کراونەتەوە). وەشانی ڕاستکراوە:
<?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 {
echo "Your inputs are: " . htmlspecialchars($_POST["name"] . ", " . $_POST["email"] . ", "
. $_POST["website"] . ", " . $_POST["comment"] . ", " . $_POST["gender"]);
}
}
?>
<h2>PHP Form Validation Example</h2>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
Name: <input type="text" name="name">
<br><br>
E-mail: <input type="text" name="email">
<br><br>
Website: <input type="text" name="website">
<br><br>
Comment: <textarea name="comment" rows="5" cols="40"></textarea>
<br><br>
Gender:
<input type="radio" name="gender" value="female">Female
<input type="radio" name="gender" value="male">Male
<br><br>
<input type="submit" name="submit" value="Submit">
</form>HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Email is required<br><h2>PHP Form Validation Example</h2>
<form method="post" action="/form_handling/index.php">
Name: <input type="text" name="name">
<br><br>
E-mail: <input type="text" name="email">
<br><br>
Website: <input type="text" name="website">
<br><br>
Comment: <textarea name="comment" rows="5" cols="40"></textarea>
<br><br>
Gender:
<input type="radio" name="gender" value="female">Female
<input type="radio" name="gender" value="male">Male
<br><br>
<input type="submit" name="submit" value="Submit">
</form>Create a user-defined function test_input() that takes one parameter (the user's input), trims it, (in the course: strips slashes) and converts HTML characters, then returns it. Use it for every field in the final else of your validation code.
test_input() دروست بکە کە یەک وەربگرێت ()، trimـی بکات، (لە کۆرسەکەدا: stripslashes) و HTML بگۆڕێت، پاشان بیگەڕێنێتەوە. لە elseـی کۆتایی کۆدی بۆ هەموو خانەیەک بەکاری بهێنە.
Show answerوەڵامەکە پیشان بدە
See Exercise 4: validation using test_input() for the complete, corrected program and its output. Remember the improvement: escape when printing, and drop stripslashes().
بۆ تەواو و ڕاستکراوەکە و ، بڕوانە ڕاهێنانی ٤: پشتڕاستکردنەوە بە test_input(). چاککردنەوەکە لەبیر مەکە: لە کاتی چاپکردندا هێماکان بگۆڕە و stripslashes() لاببە.
Rewrite the form so that every field keeps its value after the user clicks Submit: the text boxes, the textarea and the radio buttons.
دووبارە بنووسەوە تاکو هەموو خانەیەک دوای کرتەکردنی لە Submit بپارێزێت: ، و .
Show answerوەڵامەکە پیشان بدە
The complete answer is the sticky form with validation above.
وەڵامە تەواوەکە فۆرمە لکاوەکە لەگەڵ پشتڕاستکردنەوەـی سەرەوەیە.
Add a required drop-down list "City" (Erbil, Sulaymaniyah, Duhok, Halabja) to the complete sticky form. It must keep the chosen city, show "City is required" when nothing is chosen, and reject any value that is not in the list.
پێویستی «City» (Erbil، Sulaymaniyah، Duhok، Halabja) زیاد بکە بۆ تەواوی سەرەوە. دەبێت شارە هەڵبژێردراوەکە بپارێزێت، کاتێک هیچ هەڵنەبژێردراوە «City is required» پیشان بدات و هەر کە لە لیستەکەدا نەبێت ڕەت بکاتەوە.
Hintئاماژە
Start the list with <option value="">Choose…</option>. Use in_array($city, $cities, true) and print selected in a loop.
لیستەکە بە <option value="">Choose…</option> دەست پێبکە. in_array($city, $cities, true) بەکاربهێنە و لەناو selected چاپ بکە.
Show answerوەڵامەکە پیشان بدە
<?php
$cities = ["Erbil", "Sulaymaniyah", "Duhok", "Halabja"];
$city = "";
$cityErr = "";
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$city = $_POST["city"] ?? "";
if (!in_array($city, $cities, true)) {
$city = "";
$cityErr = "City is required";
}
}
?>
<form method="post" action="">
City:
<select name="city">
<option value="">Choose…</option>
<?php foreach ($cities as $c) { ?>
<option value="<?php echo $c; ?>" <?php if ($city === $c) echo "selected"; ?>><?php echo $c; ?></option>
<?php } ?>
</select>
<span class="error"><?php if ($cityErr !== "") echo "* " . $cityErr; ?></span>
<br>
<input type="submit" value="Submit">
</form>City: [Duhok ▾] [Submit]
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post" action="">
City:
<select name="city">
<option value="">Choose…</option>
<option value="Erbil" >Erbil</option>
<option value="Sulaymaniyah" >Sulaymaniyah</option>
<option value="Duhok" selected>Duhok</option>
<option value="Halabja" >Halabja</option>
</select>
<span class="error"></span>
<br>
<input type="submit" value="Submit">
</form>City: [Choose… ▾] * City is required [Submit]
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form method="post" action="">
City:
<select name="city">
<option value="">Choose…</option>
<option value="Erbil" >Erbil</option>
<option value="Sulaymaniyah" >Sulaymaniyah</option>
<option value="Duhok" >Duhok</option>
<option value="Halabja" >Halabja</option>
</select>
<span class="error">* City is required</span>
<br>
<input type="submit" value="Submit">
</form>What is XSS?XSS چییە؟
Cross-site scripting: an attacker sends HTML or JavaScript as input, and a page prints it without escaping, so the browser runs it for the visitor.
سکریپتی نێوان : هێرشبەرێک HTML یان JavaScript وەک نێوخستە دەنێرێت و لاپەڕەیەک بەبێ گۆڕینی هێماکان چاپی دەکات، بۆیە بۆ سەردانکەرەکە کاری پێدەکات.
What do trim(), stripslashes() and htmlspecialchars() do?trim() و stripslashes() و htmlspecialchars() چی دەکەن؟
trim() removes whitespace at both ends; stripslashes() removes backslashes (outdated, it damages real data); htmlspecialchars() turns & < > " ' into HTML entities so they are shown as text.
trim() لە هەردوو سەرەوە لادەبات؛ stripslashes() لادەبات (کۆنە، زانیاریی ڕاستەقینە تێکدەدات)؛ htmlspecialchars() ـ& < > " ' دەکاتە تاکو وەک دەق پیشان بدرێن.
Why is test_input() not the best approach today?بۆچی test_input() ئەمڕۆ باشترین ڕێگا نییە؟
It escapes on input instead of output (so stored data contains HTML codes), it uses the outdated stripslashes(), and its name suggests validation although it rejects nothing.
لە نێوخستەدا هێماکان دەگۆڕێت لە جیاتی (بۆیە زانیارییە هەڵگیراوەکان کۆدی HTMLـیان تێدایە)، stripslashes()ـی کۆن بەکار دەهێنێت و ناوەکەی دەگەیەنێت هەرچەندە هیچ شتێک ڕەت ناکاتەوە.
What is a sticky form, and why is it useful?فۆرمی لکاو چییە و بۆچی بەسوودە؟
A form that remembers what the user typed when it comes back with errors, so the user only fixes the mistakes instead of typing everything again.
کە کاتێک بە هەڵەوە دەگەڕێتەوە ئەوەی نووسیویەتی لەبیری دەمێنێت، بۆیە تەنها هەڵەکان چاک دەکاتەوە لە جیاتی ئەوەی هەموو شتێک دووبارە بنووسێتەوە.
How is each kind of control made sticky?هەر جۆرە توخمێک چۆن لکاو دەکرێت؟
Text input: escaped value in value="…"; textarea: escaped text between the tags; radio button and checkbox: print checked; <option>: print selected; password: never refill.
: گۆڕدراو لەناو value="…"؛ : دەقی گۆڕدراو لە نێوان ؛ و : checked چاپ بکە؛ <option>: selected چاپ بکە؛ : هەرگیز دووبارە پڕی مەکەرەوە.
Why do sticky variables give "Undefined variable" warnings, and how do you prevent it?بۆچی گۆڕاوە لکاوەکان هۆشداریی «Undefined variable» دەدەن و چۆن ڕێگری لێ دەکەیت؟
On the first visit (or when validation stopped early) the variables were never created. Give them starting values ($name = "";) at the top and fill them from $_POST before validating.
لە یەکەم سەرداندا (یان کاتێک زوو وەستا) هەرگیز دروست نەکران. لە سەرەوە سەرەتاییان پێ بدە ($name = "";) و پێش لە $_POSTـەوە پڕیان بکەرەوە.
Summaryپوختە
- XSS happens when user input is printed as HTML. Escape every value with
htmlspecialchars()at the moment you print it. trim()is useful for input;stripslashes()is a magic-quotes leftover — do not use it on form data.htmlspecialchars()escapes& < > " '; it does not protect SQL and does not replace validation.- The course's
test_input()works, but the modern rule is: trim and validate on input, escape on output. - A sticky form refills each control:
value, textarea content,checked,selected— never the password. - Initialise every sticky variable and fill it before validating, so the form works on the first visit and after errors.
- XSS ڕوودەدات کاتێک وەک HTML چاپ دەکرێت. هەموو لەو ساتەی چاپی دەکەیت بە
htmlspecialchars()بگۆڕە. trim()بۆ نێوخستە بەسوودە؛stripslashes()پاشماوەی magic quotesـە — لەسەر زانیاریی بەکاری مەهێنە.htmlspecialchars()ـ& < > " 'دەگۆڕێت؛ SQL ناپارێزێت و جێگەی ناگرێتەوە.test_input()ـی کۆرسەکە کار دەکات، بەڵام یاسا نوێیەکە ئەمەیە: لە نێوخستەدا trim و پشتڕاستی بکەرەوە، لە هێماکان بگۆڕە.- هەموو دووبارە پڕ دەکاتەوە:
value، ناوەڕۆکی ،checked،selected— هەرگیز نا. - سەرەتایی بدە بە هەموو لکاو و پێش پڕی بکەرەوە، تاکو لە یەکەم سەردان و دوای هەڵەکانیش کار بکات.
Lesson complete!وانەکە تەواو بوو!
Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.
Key termsزاراوە سەرەکییەکان
Including Files: include and requireهاوردەکردنی فایل: include و require
Related lecturesوانە پەیوەندیدارەکان
- Form Handling with GET and POSTمامەڵەکردن لەگەڵ فۆرم بە GET و POST
- PHP Superglobalsسووپەرگلۆباڵەکانی PHP
- Securing Data in PHP and MySQLپاراستنی دراوە لە PHP و MySQL
- Strings and string functionsزنجیرەنووسەکان و کردارەکانی زنجیرەنووسە
- A Login System with Sessionsسیستەمی چوونەژوورەوە بە سێشن
- Injection Attacks: SQL Injection and Cross-Site Scriptingهێرشەکانی تێخزاندن: تێخزاندنی SQL و XSS
References and further readingسەرچاوەکان و خوێندنەوەی زیاتر
This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.