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()ـی کۆرسەکە هەڵبسەنگێنە و دروست بکە کە دوای هەڵەیەک دەپارێزێت.

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

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() and stripslashes() do, and why stripslashes() 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 (سکریپتی نێوان تۆڕگەکان)

Definitionپێناسە

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:

ئەمە لاپەڕەیەکی بەخێرهاتنە کە ناوەکە ڕێک وەک نێردراوە چاپ دەکات:

welcome.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
$name = $_POST["name"] ?? "";
echo "<p>Welcome " . $name . "</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 بنێرێت:

The user typed <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() تەنها نیشاندانێکە. سکریپتی هێرشبەرێکی ڕاستەقینە دەتوانێت سەردانکەر بخوێنێتەوە (و لە ڕێگەیانەوە )، لاپەڕەکە بگۆڕێت، یان سەردانکەر بنێرێت بۆ لاپەڕەیەکی ساختەی . ئەگەر دەقەکە هەڵبگیرێت — بۆ نموونە لە تێبینییەکدا کە هەموو سەردانکەرێک دەیبینێت — هێرشەکە هەموو سەردانکەرێک دەگرێتەوە.

Quick checkپشکنینی خێراA page prints $_GET["q"] without escaping. A visitor opens it with q=<script>alert(1)</script>. What happens?لاپەڕەیەک $_GET["q"] بێ گۆڕینی هێماکان چاپ دەکات. سەردانکەرێک بە q=<script>alert(1)</script> دەیکاتەوە. چی ڕوودەدات؟

Cracking Websites with Cross Site Scripting - ComputerphileComputerphile · Englishئینگلیزی · 1.6M viewsبینین · 40K likesلایک

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چارەسەر: گۆڕینی هێماکانی دەرخستە

Two rows. Without escaping: the user types <script>alert('Hacked!')</script>, PHP prints it with echo "Welcome " . $name;, the HTML that is sent contains real script tags, and the browser runs the script and shows an alert box saying Hacked!. With htmlspecialchars(): the same input is printed with echo "Welcome " . htmlspecialchars($name);, the HTML that is sent contains &lt;script&gt;alert(&#039;Hacked!&#039;)&lt;/script&gt;, and the browser shows the text <script>alert('Hacked!')</script> on the page instead of running it.دوو ڕیز. بەبێ گۆڕینی هێماکان: بەکارهێنەر <script>alert('Hacked!')</script> دەنووسێت، PHP بە echo "Welcome " . $name; چاپی دەکات، ئەو HTMLـەی دەنێردرێت تاگە ڕاستەقینەکانی scriptـی تێدایە و تۆڕگەڕ سکریپتەکە کارا دەکات و پەنجەرەیەکی گفتوگۆ بە نووسینی Hacked! پیشان دەدات. بە htmlspecialchars(): هەمان نووسین بە echo "Welcome " . htmlspecialchars($name); چاپ دەکرێت، ئەو HTMLـەی دەنێردرێت &lt;script&gt;alert(&#039;Hacked!&#039;)&lt;/script&gt;ـی تێدایە و تۆڕگەڕ لە جیاتی کاراکردن، دەقی <script>alert('Hacked!')</script> لەسەر لاپەڕەکە پیشان دەدات.
Escaping turns the attacker's code into harmless textگۆڕینی هێماکان کۆدی هێرشبەر دەکاتە دەقێکی بێزیانCêIT

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ـدا واتایان هەیە، دەگۆڕێت بۆ . ئەو کاتە وەک دەق پیشانیان دەدات:

welcome.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
$name = $_POST["name"] ?? "";
echo "<p>Welcome " . htmlspecialchars($name) . "</p>";
The red-bold attempt, escaped: the tags are shown as textهەوڵی سوور و تۆخکردن، دوای گۆڕین: تاگەکان وەک دەق پیشان دەدرێن
Welcome <b style="color:red">Aram</b>
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<p>Welcome &lt;b style=&quot;color:red&quot;&gt;Aram&lt;/b&gt;</p>
Quick checkپشکنینی خێراWhat does htmlspecialchars("<b>") return?htmlspecialchars("<b>") چی دەگەڕێنێتەوە؟

PHP Tutorial (& MySQL) #18 - XSS AttacksNet Ninja · Englishئینگلیزی · 89K viewsبینین · 1.5K likesلایک

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ـی ستوونی) — لە سەرەتا و کۆتایی . دەست لە ناوەوەی دەقەکە نادات.

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
echo "<pre>";
$input = "  \t Hana  Karim \n ";
$clean = trim($input);

var_dump($input);
var_dump($clean);   // only the start and the end are cleaned
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" مامەڵەی لەگەڵ بکرێت و خانەیەک کە تەنها تێدا بێت دەبێت بە بەتاڵ دابنرێت.

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

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 و دوو \\ دەبێتە یەک.

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?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 backslash
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 &lt; and &gt;. This prevents attackers from injecting HTML or JavaScript code through forms.

htmlspecialchars() تایبەتەکان دەگۆڕێت بۆ . ئەو نووسانەی لە HTMLـدا واتایان هەیە، وەک < و >، بە کۆدی وەک &lt; و &gt; دەگۆڕێتەوە. ئەمە ڕێگە لە هێرشبەران دەگرێت کە لە ڕێگەی کۆدی HTML یان JavaScript تێبخزێنن.

What htmlspecialchars() changeshtmlspecialchars() چی دەگۆڕێت
CharacterBecomesدەبێتەWhyبۆچی
&&amp;Starts every entity, so it must be escaped first.هەموو بەم هێمایە دەست پێدەکات، بۆیە دەبێت سەرەتا بگۆڕدرێت.
<&lt;Would open a tag. دەکاتەوە.
>&gt;Would close a tag. دادەخات.
"&quot;Would end an attribute value like value="…". وەک value="…" کۆتایی پێدەهێنێت.
'&#039;Would end an attribute value like value='…' (escaped by default since PHP 8.1). وەک value='…' کۆتایی پێدەهێنێت (لە ⁦PHP 8.1⁩ـەوە بە شێوەی بنەڕەتی دەگۆڕدرێت).
index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
$input = "<script>alert('Hi') & \"bye\"</script>";
echo htmlspecialchars($input);

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.phpPHP
function 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.phpPHP
function 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:

با لەسەر چوار نێوخستە تاقی بکەینەوە:

test.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?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 ");
Explain 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\aram lost its backslashes: stripslashes() damaged real data.

C:\Users\aram هێڵە لارەکانی لەدەستدا: stripslashes() زانیاریی ڕاستەقینەی تێکدا.

Lineدێڕی 12

Function names are not case-sensitive, so TEST_INPUT() calls test_input() (the lab text calls it TEST_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() بانگ بکە.

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?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 } ?>
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.

: ڕێک لەو شوێنەی دەقەکە چاپ دەکرێت هێماکانی بگۆڕە — لەناو و لەناو لاپەڕەکەدا.

Quick checkپشکنینی خێراWhen should you call htmlspecialchars()?کەی دەبێت htmlspecialchars() بانگ بکەیت؟

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()دا تێدەپەڕێت. ڕاستکراوە و تەواو:

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?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";
    }
}
?>
Explain 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 &lt;b&gt;, so the browser shows the text <b> instead of making the rest of the page bold.

سەیری بکە: پێش «Karwan» نەماون و <b> وەک &lt;b&gt; گەیشت، بۆیە دەقی <b> پیشان دەدات لە جیاتی ئەوەی باقیی لاپەڕەکە تۆخ بکات.

Sticky formsفۆرمە لکاوەکان

Definitionپێناسە

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ـە کە لەبیری دەمێنێت چۆن پڕت کردەوە، تەنانەت کاتێک لە ناردنەکەدا هەڵە هەبووە. ئەمە بەتایبەتی بۆ خۆشە کاتێک دەبێت دوای پڕکردنەوەی نادروستی یەکەمجار دووبارە بنێرنەوە: تەنها هەڵەکە چاک دەکەنەوە، لە جیاتی ئەوەی هەموو شتێک دووبارە بنووسنەوە.

The clerk who keeps your formئەو فەرمانبەرەی فۆرمەکەت دەپارێزێت

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 لە نێوان هیچ لەبیر ناکات: لاپەڕەکە لە سەرەتاوە دووبارە دروست دەکرێتەوە، بۆیە کۆدەکەت دەبێت هەموو کۆن دووبارە بخاتەوە ناو .

Three states of a sticky form. 1, first visit: the variables start as empty strings, so every field is empty. 2, sent with mistakes: Name still shows Hana and E-mail still shows hana@example, with the messages "* Invalid email format" and "* Gender is required"; the typed values came back and only the mistakes need fixing. 3, everything is valid: the fields show Hana and hana@example.com, Female is selected, and "Your input:" lists the data. Below, how PHP refills each kind of control: a text box inside the value attribute, a textarea between its opening and closing tags, a radio button or checkbox by printing the word checked, and a drop-down list by printing the word selected.سێ دۆخی فۆرمێکی لکاو. ١، یەکەم سەردان: گۆڕاوەکان بە زنجیرەنووسەیەکی بەتاڵ دەست پێدەکەن، بۆیە هەموو خانەکان بەتاڵن. ٢، بە هەڵەوە نێردرا: Name هێشتا Hana و E-mail هێشتا hana@example پیشان دەدەن، لەگەڵ پەیامەکانی «* Invalid email format» و «* Gender is required»؛ نرخە نووسراوەکان گەڕانەوە و تەنها هەڵەکان پێویستیان بە چاککردنە. ٣، هەمووی دروستە: خانەکان Hana و hana@example.com پیشان دەدەن، Female هەڵبژێردراوە و «Your input:» زانیارییەکان ڕیز دەکات. لە خوارەوە، PHP چۆن هەر جۆرە توخمێکی فۆرم پڕ دەکاتەوە: خانەی دەق لەناو خەسڵەتی value، ناوچەی دەق لە نێوان تاگی کردنەوە و داخستندا، دوگمەی ڕادیۆ و چێک‌بۆکس بە چاپکردنی وشەی checked و لیستی هەڵبژاردن بە چاپکردنی وشەی selected.
A sticky form keeps the user's work between attempts کاری لە نێوان هەوڵەکاندا دەپارێزێتCêIT

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ـدا دەنووسین.» ئەمە بۆ ڕاستە، بەڵام هەر جۆرە بە شێوەیەکی جیاواز پڕ دەکرێتەوە:

Refilling each kind of controlدووبارە پڕکردنەوەی هەر جۆرە
ControlHow 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 fieldNever refill it. Let the user type the password again.هەرگیز دووبارە پڕی مەکەرەوە. با دووبارە بنووسێتەوە.
Quick checkپشکنینی خێراHow do you keep a radio button chosen after the form comes back?چۆن دوای گەڕانەوەی هەڵبژێردراو دەهێڵیتەوە؟

PHP Tutorial (& MySQL) #21 - Showing ErrorsNet Ninja · Englishئینگلیزی · 85K viewsبینین · 1.5K likesلایک · Partبەشی 5:02–10:44 (ofلە 10:44)

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 بوونیان نییە. ئەمە کرۆکەکەیەتی:

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<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>

Sticky formsفۆرمە لکاوەکان

The lab's sticky form: two more bugsفۆرمی لکاوی تاقیگەکە: دوو باگی تر

The lab (Exercise 5) writes each text field like this:

تاقیگەکە (ڕاهێنانی ٥) هەر بەم شێوەیە دەنووسێت:

As printed in the lab (with curly quotes)وەک لە تاقیگەکەدا چاپ کراوە (بە نیشانەی گوتەی چەماوە)index.phpTEXT
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 بوونی نییە:

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?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;?>">

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() لە ).

index.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?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;
}
?>
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 checked in 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() دێڕە نوێیەکانی تێبینییەکە دەپارێزێت.

Corrected and sent again: everything is validچاککرا و دووبارە نێردرا: هەمووی دروستە
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>female

Find 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.

دوو خوێندکار تاقیگەکەیان بە دوو بۆ شارەزایی فراوان کرد. کۆدەکەیان تاقیکردنەوەیەکی باشە بۆ هەموو ئەوەی لەم وانەیەدایە.

ExerciseڕاهێنانStudent answer 1وەڵامی خوێندکاری ١

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"> وەک ناو بنووسێت؟ لە یەکەم سەرداندا چی لەناو ؟

Student answer 1وەڵامی خوێندکاری ١stickyForm.phpPHP
<?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وەڵامەکە پیشان بدە
Sent with the name 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. Use htmlspecialchars($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 out action is fine: the form posts to the same page.)
  • بێ گۆڕینی هێماکان ⁦(XSS)⁩. ناوەکە بە خاوی لەناو value="…"دا چاپ دەکرێت. ئەو ">ـەی نووسیویەتی و دادەخات و باقییەکەی لەسەر لاپەڕەکە دەردەکەوێت. htmlspecialchars($name) بەکاربهێنە.
  • زیادە لە . لەناو <textarea>دا لە پێش و دوای <?php … ?> هەیە. ئەو دەبنە بەشێک لە دەقەکە، بۆیە تەنانەت لە یەکەم سەردانیشدا دوو تێدایە و هەر ناردنێک زیاتر لە دەوری تێبینییەکە زیاد دەکات. PHPـەکە ڕاستەوخۆ بە بلکێنە.
  • تەنها Java دەپشکنرێت و پەیامەکە لە سەرەوەی چاپ دەکرێت لە جیاتی تەنیشت خانەکە. Swift هەرگیز باس ناکرێت. باشتر: «⁦Choose at least one skill⁩» کاتێک هیچ کامیان نیشانە نەکرابن.
  • trim() نییە: ناوێک کە تەنها بێت وەردەگیرێت. (نەنووسینی action دروستە: بۆ هەمان لاپەڕە دەنێردرێت.)
First visit: the textarea already contains two spacesیەکەم سەردان: ناوچەی دەقەکە پێشتر دوو بۆشایی تێدایە
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>
ExerciseڕاهێنانStudent answer 2وەڵامی خوێندکاری ٢

The second student's form is the same, but the last check is different. What does the user see when no skill is ticked?

خوێندکاری دووەم هەمان شتە، بەڵام دوایین پشکنین جیاوازە. کاتێک هیچ شارەزاییەک نیشانە نەکراوە چی دەبینێت؟

The only different linesتاکە دێڕە جیاوازەکانindex.phpPHP
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ـەکە بەتاڵە، بۆیە هیچ پەیامێک پیشان نادرێت. هەموو کێشەکانی وەڵامی ١ (بێ گۆڕینی هێماکان، لە ) لێرەشدا هەن.

Sent with no skill ticked: no messageبێ نیشانەکردنی هیچ شارەزاییەک نێردرا: هیچ پەیامێک نییە
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

وەشانێکی ڕاستکراوە

stickyForm.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?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>
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: ?? and isset() handle that without warnings.

هەڵنەبژێردراو و نیشانە نەکراو نانێردرێن: ?? و isset() بەبێ مامەڵەی لەگەڵ دەکەن.

Lineدێڕی 16-18

"At least one skill" — the rule the second student wanted.

«لانیکەم یەک شارەزایی» — ئەو یاسایەی خوێندکاری دووەم دەیویست.

Sent with the name Soran and Swift ticked: everything staysبە ناوی Soran و Swiftـی نیشانەکراو نێردرا: هەموو شتێک دەمێنێتەوە
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, in value="…" or in a textarea.
  • Escaping twice: test_input() on input and htmlspecialchars() on output shows &amp;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 variable warnings 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() لە &amp;lt; بە پیشان دەدات. یەک جار، لە ، بیگۆڕە.
  • بەکارهێنانی stripslashes() لە PHPـی نوێدا — هێڵە لارە ڕاستەقینەکان دەسڕێتەوە.
  • باوەڕکردن بەوەی htmlspecialchars() دەپارێزێت. SQL پێویستی بە هەیە.
  • لکاوەکان کە هێشتا بوونیان نییە ← Undefined variable لەناو خانەکاندا. سەرەتاییان پێ بدە.
  • پڕکردنەوەی لکاوەکان تەنها کاتێک هەموو شتێک دروستە — ئەو کاتە ڕێک لەو کاتەدا نین کە پێویستن.
  • لە دەوری <?php … ?> لەناو <textarea>.
  • دووبارە پڕکردنەوەی . هەرگیز دووبارە چاپ مەکەرەوە.
  • چەماوە (“name”) کە لە بەڵگەنامەیەکەوە کۆپی کراون: .
  • هەڵەی نووسین لە ناوی (text_input، Striplashed): یان کە بوونی نییە.

Practiceڕاهێنان

Quick checkپشکنینی خێراWhy should you not use stripslashes() on form data today?بۆچی ئەمڕۆ نابێت stripslashes() لەسەر زانیاریی بەکاربهێنیت؟

Quick checkپشکنینی خێراA sticky text box is written value="<?php echo $name; ?>". The user typed Ali"><b>. What goes wrong? لکاو بەم شێوەیە نووسراوە: value="<?php echo $name; ?>". Ali"><b>ـی نووسیوە. چی تێکدەچێت؟

ExerciseڕاهێنانExercise 3 (lab): the validation formڕاهێنانی ٣ (تاقیگە): فۆرمی پشتڕاستکردنەوە

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دا دابنێ ( لە مامەڵەکردن لەگەڵ فۆرم و زنجیرەکە لە پشتڕاستکردنەوەی فۆرمدا ڕوون کراونەتەوە). وەشانی ڕاستکراوە:

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 {
        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>
ExerciseڕاهێنانExercise 4 (lab): secure the inputs with a functionڕاهێنانی ٤ (تاقیگە): نێوخستەکان بە کردارێک سەلامەت بکە

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() لاببە.

ExerciseڕاهێنانExercise 5 (lab): make the form stickyڕاهێنانی ٥ (تاقیگە): فۆرمەکە لکاو بکە

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.

وەڵامە تەواوەکە فۆرمە لکاوەکە لەگەڵ پشتڕاستکردنەوەـی سەرەوەیە.

ExerciseڕاهێنانAdd a sticky drop-down listلیستێکی هەڵبژاردنی لکاو زیاد بکە

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وەڵامەکە پیشان بدە
index.phpPHP
<?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>
Someone sent city=Parisکەسێک ⁦city=Paris⁩ ـی نارد
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>
Review questionsپرسیارەکانی پێداچوونەوە
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زاراوە سەرەکییەکان

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

Including Files: include and requireهاوردەکردنی فایل: include و require

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

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