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

Redirects: Sending the Browser Somewhere Elseئاڕاستەکردنەوە: ناردنی تۆڕگەڕ بۆ شوێنێکی تر

How header("Location: ...") and exit send a visitor to another page: the 302 response behind it, why it must come before any output, a complete form that redirects safely, redirecting after a form, and HTML meta refresh.

چۆن ⁦header("Location: ...")⁩ و exit سەردانکەر دەنێرن بۆ لاپەڕەیەکی تر: ⁦302⁩ لە پشتیەوە، بۆچی دەبێت پێش هەر بێت، تەواو کە بە سەلامەتی ئاڕاستە دەکاتەوە، دوای و ⁦meta refresh⁩ ـی HTML.

18 min read18 خولەک خوێندنەوە · 16 stepsهەنگاو

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

  • Explain what a redirect is and what the server sends (status 302 and a Location header).
  • Redirect with header("Location: ...") followed by exit.
  • Explain why header() must be called before any output, and find hidden output.
  • Build a form that redirects only to addresses on an allow-list.
  • Choose between 301, 302 and 303, and between a PHP redirect and an HTML meta refresh.
  • ڕوونی بکەیتەوە چییە و چی دەنێرێت ( ⁦302⁩ و Location).
  • بە ⁦header("Location: ...")⁩ و پاشان exit ئاڕاستە بکەیتەوە.
  • ڕوونی بکەیتەوە بۆچی دەبێت ⁦header()⁩ پێش هەر بانگ بکرێت و شاراوە بدۆزیتەوە.
  • دروست بکەیت کە تەنها بۆ ئەو ناونیشانانە ئاڕاستە دەکاتەوە کە لە .
  • لە نێوان ⁦301⁩ و ⁦302⁩ و ⁦303⁩دا و لە نێوان PHP و ⁦meta refresh⁩ ـی HTMLـدا هەڵبژێریت.

What is a redirect?ئاڕاستەکردنەوە چییە؟

A sends the visitor's from one address to another. The visitor asks for one page, and the server answers: "not here, go to this other address". The browser then opens the new address by itself.

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

Websites need redirects all the time:

هەمیشە پێویستیان بە هەیە:

  • A page has moved to a new address, or the whole site moved to a new domain or from HTTP to HTTPS.
  • A form was saved, and the visitor should now see a "thank you" page.
  • A visitor who has not logged in tries to open a private page, and must be sent to the login page.
  • The visitor picks a destination from a list, and the site sends them there.
  • لاپەڕەیەک گوازراوەتەوە بۆ ناونیشانێکی نوێ، یان هەموو گوازراوەتەوە بۆ دۆمەینێکی نوێ یان لە HTTPـەوە بۆ HTTPS.
  • پاشەکەوت کرا و ئێستا سەردانکەر دەبێت لاپەڕەی «سوپاس» ببینێت.
  • سەردانکەرێک کە نەچووەتە ژوورەوە هەوڵ دەدات لاپەڕەیەکی تایبەت بکاتەوە و دەبێت بنێردرێت بۆ لاپەڕەی .
  • سەردانکەر شوێنێک لە لیستێک هەڵدەبژێرێت و دەیانێرێت بۆ ئەوێ.
The shop that movedئەو دوکانەی گوازرایەوە

You walk through the bazaar to your favourite bookshop, but the shop is empty. On the door there is a note: "We have moved to Mawlawi Street, shop 12." You read it and walk to the new place yourself. A redirect is that note on the door: the old address does not give you the books, it only tells you where to go.

بە بازاڕدا دەڕۆیت بۆ کتێبفرۆشییە دڵخوازەکەت، بەڵام دوکانەکە بەتاڵە. لەسەر دەرگاکە پەڕەیەک هەڵواسراوە: «گوازراینەوە بۆ شەقامی مەولەوی، دوکانی ١٢.» دەیخوێنیتەوە و خۆت بەرەو شوێنە نوێیەکە دەڕۆیت. ئەو پەڕەیەیە کە لەسەر دەرگاکەیە: ناونیشانە کۆنەکە کتێبت پێ نادات، تەنها پێت دەڵێت بۆ کوێ بڕۆیت.

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

A person may decide not to go. A browser follows a redirect at once, without asking the visitor. And a PHP page can put up this "note" only before it starts sending the page itself, as you will see below.

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

Definitionپێناسە

Sending the browser to a different URL. In PHP: header("Location: page.php"); exit;. Call it before any output, and use exit so that the rest of the script does not run.

بریتییە لە ناردنی بۆ ناونیشانێکی تر. لە PHPـدا: header("Location: page.php"); exit;. پێش هەر بانگی بکە و exit بەکاربهێنە تاکو باقی دەسنووسەکە جێبەجێ نەبێت.

Quick checkپشکنینی خێراIn a redirect, who opens the new address?لە ، کێ ناونیشانە نوێیەکە دەکاتەوە؟

How a redirect works: status 302 and the Location headerئاڕاستەکردنەوە چۆن کار دەکات: کۆدی دۆخی ⁦302⁩ و سەردێڕی HTTPـی Location

Every from a web server starts with a and a few (lines of information written as Name: value). For a redirect, the server sends the status code 302 Found and an HTTP header called Location that holds the new address. The body of the response is usually empty.

هەموو لە بە و چەند دەست پێدەکات (دێڕی زانیاری کە بە شێوەی Name: value دەنووسرێن). بۆ ، 302 Found و بە ناوی Location دەنێرێت کە ناونیشانە نوێیەکەی تێدایە. جەستەی زۆرجار بەتاڵە.

A sequence diagram between the browser and the web server. 1: the browser sends POST /order.php. The server runs header("Location: thanks.php"); exit;. 2: the server answers HTTP/1.1 302 Found with Location: thanks.php and no page. 3: the browser sends GET /thanks.php by itself. 4: the server answers 200 OK with the page <p>Thank you!</p>. The browser shows localhost/thanks.php with "Thank you!"; the visitor sees only the last page.وێنەیەکی زنجیرەیی لە نێوان تۆڕگەڕ و ڕاژەکاری وێبدا. ١: تۆڕگەڕ POST /order.php دەنێرێت. ڕاژەکار header("Location: thanks.php"); exit; جێبەجێ دەکات. ٢: ڕاژەکار بە HTTP/1.1 302 Found و Location: thanks.php و بەبێ لاپەڕە وەڵام دەداتەوە. ٣: تۆڕگەڕ خۆی GET /thanks.php دەنێرێت. ٤: ڕاژەکار بە 200 OK و لاپەڕەی <p>Thank you!</p> وەڵام دەداتەوە. تۆڕگەڕ localhost/thanks.php لەگەڵ «Thank you!» پیشان دەدات؛ سەردانکەر تەنها کۆتا لاپەڕە دەبینێت.
A redirect takes two requests: the first answer contains only the new address. دوو دەخایەنێت: یەکەم تەنها ناونیشانە نوێیەکەی تێدایە.CêIT
The four steps of a redirectچوار هەنگاوەکەی ئاڕاستەکردنەوە
  1. The browser asks for a page, for example by sending a form to order.php.

    داوای لاپەڕەیەک دەکات، بۆ نموونە بە ناردنی بۆ order.php.

  2. PHP calls header("Location: thanks.php"). The server answers 302 Found with Location: thanks.php, and no page.

    PHP header("Location: thanks.php") بانگ دەکات. بە 302 Found و Location: thanks.php وەڵام دەداتەوە، بەبێ هیچ لاپەڕەیەک.

  3. The browser reads the Location header and asks for thanks.php by itself. The visitor does nothing.

    Location دەخوێنێتەوە و خۆی داوای thanks.php دەکات. سەردانکەر هیچ ناکات.

  4. The server sends thanks.php normally (200 OK). The address bar now shows thanks.php.

    thanks.php بە شێوەی ئاسایی دەنێرێت (200 OK). ئێستا thanks.php پیشان دەدات.

This is the real first answer from our test server for the example in the picture (a real server also adds headers such as Date and Server):

ئەمە یەکەم ڕاستەقینەی تاقیکردنەوەکەمانە بۆ نموونەکەی ناو وێنەکە ( ڕاستەقینە چەند تریش زیاد دەکات، وەک Date و Server):

The response to POST /order.phpوەڵامی ⁦POST /order.php⁩HTTP
HTTP/1.1 302 Found
Location: thanks.php
Content-Type: text/html; charset=UTF-8

(empty body)
The redirect status codes you will meet کە دەیانبینیت
Status codeNameناوMeaningواتاIn PHPلە PHPـدا
302FoundTemporary move. The default for Location.گواستنەوەی کاتی. بنەڕەتیی Locationـە.header("Location: new.php");
301Moved PermanentlyThe page moved for ever. Browsers and search engines remember the new address.لاپەڕەکە بۆ هەمیشە گوازراوەتەوە. و ناونیشانە نوێیەکە لە بیریان دەمێنێت.header("Location: new.php", true, 301);
303See OtherAfter a form was sent with POST: "now open this page with GET".دوای ناردنی بە POST: «ئێستا ئەم لاپەڕەیە بە GET بکەرەوە».header("Location: thanks.php", true, 303);
Quick checkپشکنینی خێراWhat status code does header("Location: x.php"); send by default?header("Location: x.php"); بە بنەڕەت کام دەنێرێت؟

HTTP Status Codes Explained In 5 MinutesByteByteGo · Englishئینگلیزی · 160K viewsبینین · 5.4K likesلایک · Partبەشی 3:30–4:07 (ofلە 5:06)

A short animated part about 3xx status codes: the server's answer that tells the browser to go to a different address.

بەشێکی کورت بە دەربارەی ⁦3xx⁩: ، کە بە دەڵێت بڕۆ بۆ ناونیشانێکی تر.

Watch 3:30–4:07: redirection and 3xx status codes.

لە ⁦3:30⁩ تا ⁦4:07⁩ سەیر بکە: و ⁦3xx⁩.

Redirecting with header()ئاڕاستەکردنەوە بە ⁦header()⁩

The course slide explains browser redirection in four points:

کۆرسەکە لە چوار خاڵدا ڕوون دەکاتەوە:

  • The PHP header() function supplies a raw HTTP header to the browser, and it can be used to redirect the browser to another location.
  • The redirection script should be at the very top of the page, to prevent any other part of the page from loading.
  • The target is given by the Location: header, as the argument of the header() function.
  • After calling this function, the exit() function can be used to halt the parsing of the rest of the code.
  • header() لە PHPـدا وەک خۆی بۆ دەنێرێت و دەتوانرێت بۆ بۆ شوێنێکی تر بەکاربهێنرێت.
  • دەبێت لە هەرە سەرەوەی لاپەڕەکەدا بێت، بۆ ئەوەی ڕێگە لە بارکردنی هەر بەشێکی تری لاپەڕەکە بگرێت.
  • ئامانجەکە بە Location: دیاری دەکرێت، وەک header().
  • دوای بانگکردنی ئەم ، دەتوانرێت exit() بەکاربهێنرێت بۆ ڕاگرتنی خوێندنەوە و جێبەجێکردنی باقی کۆدەکە.
The shortest redirect there isکورتترین ئاڕاستەکردنەوە کە هەیەgo.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
header("Location: http://www.google.com");
exit();
?>
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2

Send the Location header. PHP also sets the status code to 302 for you.

Location بنێرە. PHP خۆی دەکاتە ⁦302⁩.

Lineدێڕی 3

Stop the script here. Nothing after this line runs.

لێرە ڕابگرە. هیچ شتێک دوای ئەم دێڕە جێبەجێ ناکرێت.

Writing the header correctly

نووسینی دروستی سەردێڕەکەی HTTP

  • Write Location, a colon, a space, then the address: header("Location: thanks.php");.
  • The address can be a full (https://www.example.com/page.php), a path from the site's root (/shop/thanks.php), or a file next to the current page (thanks.php).
  • To send another status code, give it as the third argument: header("Location: contact.php", true, 301);.
  • Location، دوو خاڵ، ، پاشان ناونیشانەکە بنووسە: header("Location: thanks.php");.
  • ناونیشانەکە دەکرێت تەواو بێت (https://www.example.com/page.php)، لە ڕەگی (/shop/thanks.php)، یان لە تەنیشت لاپەڕەی ئێستاوە (thanks.php).
  • بۆ ناردنی تر، وەک سێیەم بینێرە: header("Location: contact.php", true, 301);.
old-contact.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
// old-contact.php: this page has moved for ever
header("Location: contact.php", true, 301);
exit;
Quick checkپشکنینی خێراWhich function redirects the browser?کام ئاڕاستە دەکاتەوە؟

HTTP Headers In PHP - Request & Response Headers - Full PHP 8 TutorialProgram With Gio · Englishئینگلیزی · 42K viewsبینین · 1.3K likesلایک · Partبەشی 6:26–11:59 (ofلە 11:59)

Shows how PHP's header() function sends HTTP headers, including the Location header that sends the visitor to another page.

نیشان دەدات header() لە چۆن دەنێرێت، لەوانە Location کە سەردانکەر دەباتە تر.

Watch from 6:26: sending headers with header(), then the Location header.

لە ⁦6:26⁩ بەدواوە سەیر بکە: ناردنی بە header()، پاشان Location.

Call header() before any output⁦header()⁩ پێش هەر دەرخستەیەک بانگ بکە

A response is sent in a fixed order: first the status line and the headers, then an empty line, then the body (the HTML). PHP sends the headers at the moment your script produces its first output: the first echo, or the first HTML outside <?php ... ?>. After that the headers are gone, and header() can no longer change them.

بە ڕیزبەندییەکی جێگیر دەنێردرێت: سەرەتا دێڕی دۆخ و ، پاشان دێڕێکی بەتاڵ، پاشان جەستەکە (HTMLـەکە). PHP ئەو ساتە دەنێرێت کە یەکەم خۆی دروست دەکات: یەکەم echo، یان یەکەم HTML لە دەرەوەی <?php ... ?>. دوای ئەوە ڕۆیشتوون و header() ئیتر ناتوانێت بیانگۆڕێت.

An HTTP response drawn as one box with two parts. Part 1, status line and headers: HTTP/1.1 302 Found, Location: thanks.php, Content-Type: text/html, then an empty line. Part 2, the body: <html>, <body>, <h1>Welcome</h1>. A note points to part 1: header("Location: ...") can only add lines here, so call it before any output. A note points to part 2: echo or <html> is the first output and starts the body; PHP sends the headers at once and they cannot change any more: "headers already sent".وەڵامێکی HTTP وەک یەک سندوق بە دوو بەشەوە. بەشی ١، دێڕی دۆخ و سەردێڕەکانی HTTP: HTTP/1.1 302 Found، Location: thanks.php، Content-Type: text/html، پاشان دێڕێکی بەتاڵ. بەشی ٢، جەستە: <html>، <body>، <h1>Welcome</h1>. تێبینییەک ئاماژە بە بەشی ١ دەکات: header("Location: ...") تەنها لێرە دەتوانێت دێڕ زیاد بکات، بۆیە پێش هەر دەرخستەیەک بانگی بکە. تێبینییەک ئاماژە بە بەشی ٢ دەکات: echo یان <html> یەکەم دەرخستەیە و جەستەکە دەست پێدەکات؛ PHP دەستبەجێ سەردێڕەکانی HTTP دەنێرێت و ئیتر ناگۆڕدرێن: «headers already sent».
Headers travel before the body. Once the body has started, header() is too late. پێش جەستە دەڕۆن. کاتێک جەستە دەستی پێکرد، header() درەنگە.CêIT
late.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<html>
<body>
<h1>Welcome</h1>
<?php
header("Location: http://www.google.com");
exit();
?>
</body>
</html>
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1-3

This HTML is output. PHP sends the headers here, before line 5 runs.

ئەم HTMLـە . PHP لێرەدا دەنێرێت، پێش ئەوەی دێڕی 5 جێبەجێ بکرێت.

Lineدێڕی 5

Too late: the redirect cannot be added any more.

زۆر درەنگە: ئیتر زیاد ناکرێت.

Call header() before any output⁦header()⁩ پێش هەر دەرخستەیەک بانگ بکە

Invisible output breaks it tooدەرخستەی نەبینراویش تێکیدەدات

The output can also be invisible. In the next file there is a single space before <?php. That space is output, so the redirect fails again:

دەشکرێت نەبینراو بێت. لە داهاتوودا تەنها یەک پێش <?php هەیە. ئەو ، بۆیە دیسان شکست دەهێنێت:

space.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
 
<?php
header("Location: thanks.php");
exit;
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

One space character before <?php.

تەنها یەک پێش <?php.

Where unexpected output comes from

دەرخستەی چاوەڕواننەکراو لە کوێوە دێت

  • HTML, spaces or empty lines before the first <?php.
  • An echo used for testing, or a PHP warning printed on the page.
  • An included file that prints something, such as a connection file that echoes "connected", or empty lines after its closing ?>.
  • An invisible byte-order mark (BOM) at the start of a file saved as "UTF-8 with BOM". Save PHP files as UTF-8 without BOM.
  • HTML، یان دێڕی بەتاڵ پێش یەکەم <?php.
  • echoیەک بۆ تاقیکردنەوە، یان PHP کە لەسەر لاپەڕەکە چاپ کراوە.
  • هێنراو کە شتێک چاپ دەکات، وەک پەیوەندی کە «connected» چاپ دەکات، یان دێڕی بەتاڵ دوای ?>ی کۆتایی.
  • نیشانەیەکی نەبینراوی BOM لە سەرەتای کە وەک «⁦UTF-8 with BOM⁩» خەزن کراوە. PHP وەک ⁦UTF-8⁩ بەبێ BOM خەزن بکە.
Quick checkپشکنینی خێراA file starts with one empty line, then <?php header("Location: home.php"); exit;. On a server without output buffering, what happens? بە یەک دێڕی بەتاڵ دەست پێدەکات، پاشان <?php header("Location: home.php"); exit;. لەسەر بەبێ ، چی ڕوودەدات؟

Call header() before any output⁦header()⁩ پێش هەر دەرخستەیەک بانگ بکە

Why it sometimes works on XAMPPبۆچی هەندێک جار لەسەر XAMPP کار دەکات

Why exit must follow header()بۆچی دەبێت exit دوای ⁦header()⁩ بێت

header() only adds a line to the response. It does not stop your script. Without exit, PHP keeps running the rest of the page even though the visitor is already on their way somewhere else.

header() تەنها دێڕێک بۆ زیاد دەکات. ڕاناگرێت. بەبێ exit، PHP بەردەوام دەبێت لە جێبەجێکردنی باقی لاپەڕەکە، هەرچەندە سەردانکەر پێشتر بەڕێکەوتووە بۆ شوێنێکی تر.

This matters most on private pages. The page below should send visitors who are not logged in to login.php, but it forgets exit:

ئەمە زیاتر لە لاپەڕە تایبەتەکاندا گرنگە. لاپەڕەی خوارەوە دەبێت ئەو سەردانکەرانەی نەچوونەتە ژوورەوە بنێرێت بۆ login.php، بەڵام exitی لەبیر کردووە:

accounts.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
$loggedIn = false;   // in a real site this comes from the login system

if (!$loggedIn) {
    header("Location: login.php");
    // no exit here!
}

echo "<h1>Shop accounts (manager only)</h1>";
echo "<p>Money in the safe today: 1,250,000 IQD</p>";

The browser follows the Location header, so a normal visitor never sees this page. But the secret HTML was still sent in the body. Anyone who reads the raw response, for example with a tool such as curl or a browser extension, can read it. And if the code below did something, such as deleting a record, it would really run. Add exit and the body stays empty:

بەدوای Locationدا دەڕوات، بۆیە سەردانکەرێکی ئاسایی هەرگیز ئەم لاپەڕەیە نابینێت. بەڵام HTMLـە نهێنییەکە هەر لە جەستەکەدا نێردرا. هەر کەسێک وەک خۆی بخوێنێتەوە، بۆ نموونە بە ئامرازێکی وەک curl یان ، دەتوانێت بیخوێنێتەوە. وە ئەگەر کۆدی خوارەوە کارێکی بکردایە، وەک سڕینەوەی ، بە ڕاستی جێبەجێ دەکرا. exit زیاد بکە و جەستەکە بەتاڵ دەمێنێتەوە:

accounts.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
$loggedIn = false;   // in a real site this comes from the login system

if (!$loggedIn) {
    header("Location: login.php");
    exit;            // stop here: nothing below runs or is sent
}

echo "<h1>Shop accounts (manager only)</h1>";
echo "<p>Money in the safe today: 1,250,000 IQD</p>";
Quick checkپشکنینی خێراWhy do we call exit() after header()?بۆچی دوای header() بانگی exit() دەکەین؟

exit and die are explained in Including files: die() and exit.

exit و die لە هاوردەکردنی فایل: ⁦die()⁩ و exit ڕوون کراونەتەوە.

A complete example: a form that sends you to another siteنموونەیەکی تەواو: فۆرمێک کە دەتنێرێت بۆ تۆڕگەیەکی تر

The course's complete example has two parts: a form with a of websites, and PHP that redirects the visitor to the chosen site. The slide shows the flow in five steps:

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

Five boxes joined by arrows. 1: the visitor picks a site. 2: the visitor presses the submit button. 3: PHP reads $_POST["location"]. 4: header() sends the visitor away. 5: the new site opens. A note under box 4 says: corrected version, only addresses on the allow-list.پێنج سندوق کە بە تیر بەیەکەوە بەستراون. ١: سەردانکەر تۆڕگەیەک هەڵدەبژێرێت. ٢: سەردانکەر دوگمەی ناردن دادەگرێت. ٣: PHP $_POST["location"] دەخوێنێتەوە. ٤: header() سەردانکەر دەنێرێت. ٥: تۆڕگە نوێیەکە دەکرێتەوە. تێبینییەک لە ژێر سندوقی ٤ دەڵێت: وەشانی ڕاستکراوە، تەنها ئەو ناونیشانانەی لە لیستە ڕێگەپێدراوەکەدان.
The course's five-step flow, from the visitor's choice to the new site.ڕەوتە پێنج هەنگاوییەکەی کۆرسەکە، لە هەڵبژاردنی سەردانکەرەوە تا نوێ.CêIT, after the course slide

Here is the example, corrected. The PHP part comes first in the file, before any HTML, and it only accepts the addresses that are in the list:

ئەمە نموونەکەیە، ڕاستکراوە. بەشی PHP لە یەکەم دێت، پێش هەر HTMLـێک و تەنها ئەو ناونیشانانە قبووڵ دەکات کە لە لیستەکەدان:

choose.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
// PART 2 - THE PHP: it must run first, before any HTML is sent
$allowed = ["https://www.microsoft.com", "https://www.google.com"];

if (isset($_POST["go"])) {
    $location = $_POST["location"] ?? "";
    if (in_array($location, $allowed, true)) {
        header("Location: $location");
        exit();
    }
    $error = "Please choose a site from the list.";
}
?>
<!DOCTYPE html>
<html>
<body>
<h1>Choose a site to visit:</h1>
<?php if (isset($error)) { echo "<p>$error</p>"; } ?>
<form method="post" action="">
  <select name="location">
    <option value="https://www.microsoft.com">Microsoft</option>
    <option value="https://www.google.com">Google</option>
  </select>
  <input type="submit" name="go" value="Go">
</form>
</body>
</html>
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2-12

PART 2 of the slide, the PHP. It must run before any HTML is sent, so it is at the top of the file.

بەشی ٢ی ، PHPـەکە. دەبێت پێش ناردنی هەر HTMLـێک جێبەجێ بکرێت، بۆیە لە سەرەوەی .

Lineدێڕی 3

The : the only addresses we will ever redirect to.

: تاکە ئەو ناونیشانانەی کە سەردانکەری بۆ دەنێرین.

Lineدێڕی 5

isset() asks: did this value actually arrive? Only then do we redirect.

isset() دەپرسێت: ئایا ئەم بە ڕاستی گەیشت؟ تەنها ئەوکاتە ئاڕاستە دەکەینەوە.

Lineدێڕی 7

The value comes from the visitor, so we check it against the list first.

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

Lineدێڕی 8-9

Redirect, then stop.

ئاڕاستە بکەرەوە، پاشان بوەستە.

Lineدێڕی 19

action="" sends the form back to this same page.

action="" دەنێرێتەوە بۆ هەمان ئەم لاپەڕەیە.

A complete example: a form that sends you to another siteنموونەیەکی تەواو: فۆرمێک کە دەتنێرێت بۆ تۆڕگەیەکی تر

What happens (tested)چی ڕوودەدات (تاقیکراوەتەوە)

We sent three requests to choose.php: a normal visit, a correct choice, and a changed value. Here is what the server answered:

سێ بۆ choose.php نارد: سەردانێکی ئاسایی، هەڵبژاردنێکی دروست و گۆڕدراو. ئەمە ئەوەیە کە وەڵامی دایەوە:

1. First visit (GET): the form١. یەکەم سەردان ⁦(GET)⁩: فۆرمەکە
Choose a site to visit:
[Microsoft ▾] [Go]
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<!DOCTYPE html>
<html>
<body>
<h1>Choose a site to visit:</h1>
<form method="post" action="">
  <select name="location">
    <option value="https://www.microsoft.com">Microsoft</option>
    <option value="https://www.google.com">Google</option>
  </select>
  <input type="submit" name="go" value="Go">
</form>
</body>
</html>
2. The visitor chooses Google and presses Go٢. سەردانکەر Google هەڵدەبژێرێت و Go دادەگرێت
HTTP/1.1 302 Found
Location: https://www.google.com
Content-Type: text/html; charset=UTF-8

(empty body)
3. Someone changes the option's value to another address٣. کەسێک نرخی هەڵبژاردەکە دەگۆڕێت بۆ ناونیشانێکی تر
Choose a site to visit:
Please choose a site from the list.
[Microsoft ▾] [Go]
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<!DOCTYPE html>
<html>
<body>
<h1>Choose a site to visit:</h1>
<p>Please choose a site from the list.</p><form method="post" action="">
  <select name="location">
    <option value="https://www.microsoft.com">Microsoft</option>
    <option value="https://www.google.com">Google</option>
  </select>
  <input type="submit" name="go" value="Go">
</form>
</body>
</html>

Status 200 and no Location header: the page refused to redirect.

کۆدی ⁦200⁩ و هیچ سەردێڕێکی Location نییە: لاپەڕەکە ڕازی نەبوو ئاڕاستە بکاتەوە.

A complete example: a form that sends you to another siteنموونەیەکی تەواو: فۆرمێک کە دەتنێرێت بۆ تۆڕگەیەکی تر

The slide's version and what was wrongوەشانەکەی سلایدەکە و هەڵەکانی

Quick checkپشکنینی خێراWhy is header("Location: " . $_POST["location"]); dangerous?بۆچی header("Location: " . $_POST["location"]); مەترسیدارە؟

Redirect after a form is savedئاڕاستەکردنەوە دوای پاشەکەوتکردنی فۆرمێک

When a page shows its result directly after a POST, and the visitor presses Refresh, the browser asks "Confirm form resubmission?" and may send the same order twice. The usual cure: after the data is saved, redirect to a normal page. A refresh then only reloads that page.

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

order.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
if (isset($_POST["order"])) {
    $tea = $_POST["tea"] ?? "";
    // ... check the input and save the order in the database here ...
    header("Location: thanks.php");   // 1. POST is done: send the visitor on
    exit;
}
?>
<!DOCTYPE html>
<html>
<body>
<form method="post" action="">
  How many glasses of tea? <input type="number" name="tea">
  <input type="submit" name="order" value="Order">
</form>
</body>
</html>
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 4

Here you would check the input and save the order (you will learn databases later).

لێرەدا نێوخستەکە دەپشکنیت و فەرمایشەکە پاشەکەوت دەکەیت (دواتر فێر دەبیت).

Lineدێڕی 5-6

Send the visitor to the thank-you page and stop.

سەردانکەر بنێرە بۆ لاپەڕەی سوپاس و بوەستە.

thanks.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
echo "<p>Thank you! Your order is on its way.</p>";
Quick checkپشکنینی خێراA visitor sends an order form and then presses Refresh on the result page. How do you stop the order from being sent twice?سەردانکەرێک فەرمایش دەنێرێت و پاشان لەسەر لاپەڕەی ئەنجامەکە Refresh دادەگرێت. چۆن ڕێگە دەگریت لەوەی فەرمایشەکە دوو جار بنێردرێت؟

HTML redirection: the meta refresh tagئاڕاستەکردنەوەی HTML: تاگی ⁦meta refresh⁩

A redirect can also be written in HTML, without PHP. An HTML redirect (also called a meta refresh or meta redirect) sends the visitor from one HTML page to another using a tag in the page's source code. It tells the browser: "the content you are looking for is not at this URL, but we will send you to the right place".

دەشکرێت بە HTML بنووسرێت، بەبێ PHP. HTML (کە پێی دەوترێت ⁦meta refresh⁩ یان ⁦meta redirect⁩) سەردانکەر لە لاپەڕەیەکی HTMLـەوە دەنێرێت بۆ لاپەڕەیەکی تر، بە لە لاپەڕەکەدا. بە دەڵێت: «ئەو ناوەڕۆکەی بەدوایدا دەگەڕێیت لەم URLـەدا نییە، بەڵام دەتنێرین بۆ شوێنی دروست».

It is best to avoid redirects when possible, but most site owners need one at some point: when a page is moved, when the site moves to a new domain, or when the addresses change from HTTP to HTTPS. A redirect stops visitors and search engines from running into dead-end 404 ("Not Found") pages, which hurt both the visitors' experience and the site's ranking in search engines (SEO).

باشترە هەتا بکرێت خۆت لە بپارێزیت، بەڵام زۆربەی خاوەن لە کاتێکدا پێویستیان پێی دەبێت: کاتێک لاپەڕەیەک دەگوازرێتەوە، کاتێک دەگوازرێتەوە بۆ دۆمەینێکی نوێ، یان کاتێک ناونیشانەکان لە HTTPـەوە دەگۆڕدرێن بۆ HTTPS. ڕێگە دەگرێت لەوەی سەردانکەران و بگەنە لاپەڕەی داخراوی ⁦404⁩ («⁦Not Found⁩»)، کە هەم ئەزموونی سەردانکەران و هەم پلەی لە ⁦(SEO)⁩ خراپ دەکەن.

To redirect one HTML page to another, add a <meta> tag inside the of the old page. The <head> holds information (metadata) that is useful for the browser but invisible to visitors. The syntax is:

بۆ لاپەڕەیەکی HTML بۆ لاپەڕەیەکی تر، <meta> لەناو لاپەڕە کۆنەکەدا زیاد بکە. <head> ئەو زانیارییانەی ⁦(metadata)⁩ تێدایە کە بۆ بەسوودن بەڵام بۆ سەردانکەران نابینرێن. داڕشتنەکەی ئەمەیە:

HTML
<meta http-equiv="refresh" content="delay_time; URL=new_website_url" />
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

delay_time is the number of seconds to wait (0 = at once); URL= is the new address.

delay_time ژمارەی ئەو چرکانەیە کە چاوەڕێ دەکرێت (⁦0⁩ = دەستبەجێ)؛ URL= ناونیشانە نوێیەکەیە.

contact.html (old page)HTMLRuns in the browserلە ناو تۆڕگەڕ کار دەکات
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="refresh" content="5; URL=https://www.example.com/contact.html">
  <title>This page has moved</title>
</head>
<body>
  <p>This page has moved to a new address.</p>
  <p>You will be taken there in 5 seconds. If nothing happens,
     <a href="https://www.example.com/contact.html">click here</a>.</p>
</body>
</html>

HTML redirection: the meta refresh tagئاڕاستەکردنەوەی HTML: تاگی ⁦meta refresh⁩

PHP redirect or meta refresh?ئاڕاستەکردنەوەی PHP یان ⁦meta refresh⁩؟

Here are the two ways to redirect side by side:

ئەمە دوو ڕێگاکەی لە تەنیشت یەکترەوە:

Two ways to redirectدوو ڕێگای
Featureتایبەتمەندیheader("Location: ...")<meta http-equiv="refresh">
Where it worksلە کوێ کار دەکاتOn the server, in PHP, before any output.لەسەر ، لە PHPـدا، پێش هەر .In the browser, inside an HTML page; no PHP needed.لە ، لەناو لاپەڕەیەکی HTML؛ پێویستی بە PHP نییە.
SpeedخێراییImmediate: the old page is never shown.دەستبەجێ: لاپەڕە کۆنەکە هەرگیز پیشان نادرێت.The old page loads first, then the browser waits the delay.سەرەتا لاپەڕە کۆنەکە بار دەکرێت، پاشان چاوەڕێی ماوەکە دەکات.
Status code302 by default, or 301/303.بە بنەڕەت ⁦302⁩، یان ⁦301/303⁩.200: the server sends a normal page. Search engines may treat it as a redirect, but less reliably than a 301.⁦200⁩: لاپەڕەیەکی ئاسایی دەنێرێت. لەوانەیە وەک مامەڵەی لەگەڵ بکەن، بەڵام بە دڵنیاییەکی کەمتر لە ⁦301⁩.
Best forباشترە بۆMoved pages, forms, logins: almost always.لاپەڕەی گوازراوە، ، : نزیکەی هەمیشە.Simple HTML hosting where you cannot run server code.خانەخوێیەتیی سادەی HTML کە ناتوانیت کۆدی جێبەجێ بکەیت.
Quick checkپشکنینی خێراWhere do you put the meta refresh tag? ⁦meta refresh⁩ لە کوێ دادەنێیت؟

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

  • Output before header(). HTML, echo, a space before <?php or text from an included file. Result: "Cannot modify header information - headers already sent". Move the redirect code to the top.
  • No exit after header(). The rest of the page still runs and is sent. Always write exit;.
  • A typo in the header, such as Locaton: or a missing colon. PHP sends the line, but the browser does not treat it as a redirect.
  • A redirect loop. A page redirects to itself, or two pages redirect to each other. The browser gives up with "too many redirects". Check the condition before you redirect.
  • Redirecting to an address taken from the visitor (an ). Use an .
  • پێش header(). HTML، echo، پێش <?php یان دەقێک لە هێنراوەوە. ئەنجام: «⁦Cannot modify header information - headers already sent⁩». کۆدی بگوازەرەوە بۆ سەرەوە.
  • هیچ exitێک دوای header() نییە. باقی لاپەڕەکە هەر جێبەجێ دەکرێت و دەنێردرێت. هەمیشە exit; بنووسە.
  • هەڵەی نووسین لە ، وەک Locaton: یان دوو خاڵی لەبیرکراو. PHP دێڕەکە دەنێرێت، بەڵام وەک مامەڵەی لەگەڵ ناکات.
  • . لاپەڕەیەک بۆ خۆی ئاڕاستە دەکاتەوە، یان دوو لاپەڕە یەکتر ئاڕاستە دەکەنەوە. بە «⁦too many redirects⁩» واز دەهێنێت. پێش بپشکنە.
  • بۆ ناونیشانێک کە لە سەردانکەرەوە وەرگیراوە (). بەکاربهێنە.
A redirect loopخولێکی ئاڕاستەکردنەوەloop.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
header("Location: loop.php");   // sends the visitor back to this same page
exit;

Exercisesڕاهێنانەکان

ExerciseڕاهێنانMove a page permanentlyلاپەڕەیەک بە هەمیشەیی بگوازەرەوە

Your contact page was renamed from old-contact.php to contact.php. Replace the whole content of old-contact.php with code that sends visitors and search engines to the new page for ever.

لاپەڕەی پەیوەندییەکەت ناوی گۆڕدرا لە old-contact.php بۆ contact.php. هەموو ناوەڕۆکی old-contact.php بە کۆدێک بگۆڕە کە سەردانکەران و بۆ هەمیشە بنێرێت بۆ لاپەڕە نوێیەکە.

Hintئاماژە

Which status code means "moved for ever"?

کام واتای «بۆ هەمیشە گوازراوەتەوە» دەدات؟

Show answerوەڵامەکە پیشان بدە
PHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
// old-contact.php: this page has moved for ever
header("Location: contact.php", true, 301);
exit;
ExerciseڕاهێنانFind the bugهەڵەکە بدۆزەرەوە

This page should send visitors to welcome.php, but the browser shows "Welcome" and a warning instead. Explain why and fix it.

ئەم لاپەڕەیە دەبێت سەردانکەران بنێرێت بۆ welcome.php، بەڵام لە جیاتی ئەوە «Welcome» و پیشان دەدات. ڕوونی بکەرەوە بۆچی و چاکی بکەرەوە.

PHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<html>
<body>
<h1>Welcome</h1>
<?php
header("Location: welcome.php");
exit();
?>
</body>
</html>
Show answerوەڵامەکە پیشان بدە

Lines 1-3 are output, so PHP sent the headers before line 5. Move the PHP block to the very top, before <html>, or remove the HTML because the visitor will never see it:

دێڕەکانی ⁦1-3⁩ دەرخستەن، بۆیە PHP پێش دێڕی 5 سەردێڕەکانی نارد. بلۆکی PHP بگوازەرەوە بۆ هەرە سەرەوە، پێش <html>، یان HTMLـەکە لابەرە چونکە سەردانکەر هەرگیز نایبینێت:

PHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
header("Location: welcome.php");
exit();
?>
ExerciseڕاهێنانProtect a pageلاپەڕەیەک بپارێزە

Rewrite accounts.php from this lecture so that a visitor who is not logged in is sent to login.php and nothing of the private content is sent.

accounts.phpی ئەم وانەیە دووبارە بنووسەوە بە شێوەیەک کە سەردانکەرێک کە نەچووەتە ژوورەوە بنێردرێت بۆ login.php و هیچ بەشێک لە ناوەڕۆکە تایبەتەکە نەنێردرێت.

Show answerوەڵامەکە پیشان بدە
PHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
<?php
$loggedIn = false;   // in a real site this comes from the login system

if (!$loggedIn) {
    header("Location: login.php");
    exit;            // stop here: nothing below runs or is sent
}

echo "<h1>Shop accounts (manager only)</h1>";
echo "<p>Money in the safe today: 1,250,000 IQD</p>";

In a real site $loggedIn comes from a session; see Sessions.

لە ڕاستەقینەدا $loggedIn لە دێت؛ بڕوانە سێشنەکان.

ExerciseڕاهێنانA site chooser with three sitesهەڵبژێری تۆڕگە بە سێ تۆڕگەوە

Extend choose.php with a third site (for example https://www.wikipedia.org). Make sure that changing the option's value in the browser cannot send the visitor anywhere else.

choose.php فراوان بکە بە سێیەم (بۆ نموونە https://www.wikipedia.org). دڵنیابە کە گۆڕینی هەڵبژاردەکە لە ناتوانێت سەردانکەر بنێرێت بۆ هیچ شوێنێکی تر.

Hintئاماژە

The new address must be added in two places.

ناونیشانە نوێیەکە دەبێت لە دوو شوێندا زیاد بکرێت.

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

Add the address to the $allowed array and add a new <option>. The in_array(..., true) check stays the same:

ناونیشانەکە بۆ $allowed زیاد بکە و <option>ێکی نوێ زیاد بکە. پشکنینی in_array(..., true) وەک خۆی دەمێنێتەوە:

PHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات
$allowed = ["https://www.microsoft.com", "https://www.google.com", "https://www.wikipedia.org"];
HTMLRuns in the browserلە ناو تۆڕگەڕ کار دەکات
<option value="https://www.wikipedia.org">Wikipedia</option>
ExerciseڕاهێنانAn HTML page that movedلاپەڕەیەکی HTML کە گوازراوەتەوە

Write an HTML page prices.html that tells the visitor the price list has moved to https://www.example.com/prices.html and takes them there after 3 seconds. Include a link for visitors whose browser does not redirect.

لاپەڕەیەکی HTML بە ناوی prices.html بنووسە کە بە سەردانکەر بڵێت لیستی نرخەکان گوازراوەتەوە بۆ https://www.example.com/prices.html و دوای ٣ چرکە بیبات بۆ ئەوێ. دابنێ بۆ ئەو سەردانکەرانەی ئاڕاستە ناکاتەوە.

Show answerوەڵامەکە پیشان بدە
HTMLRuns in the browserلە ناو تۆڕگەڕ کار دەکات
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="refresh" content="3; URL=https://www.example.com/prices.html">
  <title>This page has moved</title>
</head>
<body>
  <p>This page has moved to a new address.</p>
  <p>You will be taken there in 3 seconds. If nothing happens,
     <a href="https://www.example.com/prices.html">click here</a>.</p>
</body>
</html>

Summary and reviewپوختە و پێداچوونەوە

  • A redirect is an answer with status 302 (or 301/303) and a Location header; the browser then asks for the new address by itself.
  • In PHP: header("Location: page.php"); exit;
  • header() must come before any output; otherwise you get "headers already sent".
  • exit stops the rest of the page from running and from being sent.
  • Never redirect to an address from the visitor without an allow-list.
  • HTML pages can redirect with <meta http-equiv="refresh" content="5; URL=..."> in the <head>.
  • بە ⁦302⁩ (یان ⁦301/303⁩) و Location؛ پاشان خۆی داوای ناونیشانە نوێیەکە دەکات.
  • لە PHPـدا: header("Location: page.php"); exit;
  • header() دەبێت پێش هەر بێت؛ دەنا «⁦headers already sent⁩» وەردەگریت.
  • exit ڕێگە دەگرێت لە جێبەجێبوون و ناردنی باقی لاپەڕەکە.
  • هەرگیز بەبێ ئاڕاستە مەکەرەوە بۆ ناونیشانێک کە لە سەردانکەرەوە هاتووە.
  • لاپەڕەکانی HTML دەتوانن بە <meta http-equiv="refresh" content="5; URL=..."> لەناو <head>دا ئاڕاستە بکەنەوە.
Review questionsپرسیارەکانی پێداچوونەوە
Which function redirects the browser?کام کردار تۆڕگەڕ ئاڕاستە دەکاتەوە؟

header("Location: ..."), and it must be at the very top of the page.

⁦header("Location: ...")⁩ و دەبێت لە هەرە سەرەوەی لاپەڕەکەدا بێت.

Why call exit() after header()?بۆچی دوای ⁦header()⁩ بانگی ⁦exit()⁩ دەکەیت؟

To halt the parsing of the rest of the code, so nothing else runs (and nothing else is sent).

بۆ ڕاگرتنی باقی کۆدەکە، تاکو هیچ شتێکی تر جێبەجێ نەبێت (و هیچ شتێکی تر نەنێردرێت).

What does the server send for a redirect?ڕاژەکار بۆ ئاڕاستەکردنەوە چی دەنێرێت؟

A status code such as 302 Found and a Location header with the new address, usually with an empty body.

وەک ⁦302 Found⁩ و Location کە ناونیشانە نوێیەکەی تێدایە، زۆرجار بە جەستەیەکی بەتاڵەوە.

What is the difference between 301 and 302?جیاوازیی نێوان ⁦301⁩ و ⁦302⁩ چییە؟

301 means the page moved for ever (browsers and search engines remember it); 302 means a temporary move and is the default.

⁦301⁩ واتە لاپەڕەکە بۆ هەمیشە گوازراوەتەوە ( و لە بیریان دەمێنێت)؛ ⁦302⁩ واتە گواستنەوەی کاتی و بنەڕەتییە.

What is an HTML redirect (meta refresh) and where do you put it?ئاڕاستەکردنەوەی ⁦HTML (meta refresh)⁩ چییە و لە کوێ دایدەنێیت؟

A <meta http-equiv="refresh" content="delay; URL=new-address"> tag inside the <head> of the old page; it sends the visitor to the new page after the delay.

⁦<meta http-equiv="refresh" content="delay; URL=new-address">⁩ لەناو ⁦<head>⁩ی لاپەڕە کۆنەکەدا؛ دوای ماوەکە سەردانکەر دەنێرێت بۆ لاپەڕە نوێیەکە.

Why do sites use redirects when pages move?بۆچی تۆڕگەکان کاتێک لاپەڕەکان دەگوازرێنەوە ئاڕاستەکردنەوە بەکار دەهێنن؟

So that visitors and search engines do not reach dead-end 404 pages, which hurt the user experience and SEO.

بۆ ئەوەی سەردانکەران و نەگەنە لاپەڕەی داخراوی ⁦404⁩، کە ئەزموونی و SEO خراپ دەکەن.

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

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

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

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

Uploading Filesبارکردنی فایل

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

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