{"id":2742,"date":"2021-09-25T11:19:29","date_gmt":"2021-09-25T11:19:29","guid":{"rendered":"https:\/\/phptutorial.net\/php-tutorial\/php-login\/"},"modified":"2025-04-09T07:58:43","modified_gmt":"2025-04-09T07:58:43","slug":"php-login","status":"publish","type":"page","link":"https:\/\/www.phptutorial.net\/php-tutorial\/php-login\/","title":{"rendered":"PHP Login"},"content":{"rendered":"\r\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn how to create a login form using a username and password.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id='prerequisites'>Prerequisites <a href=\"#prerequisites\" class=\"anchor\" id=\"prerequisites\" title=\"Anchor for Prerequisites\">#<\/a><\/h2>\r\n\r\n\r\n\r\n<p>To start this tutorial, you\u00a0<span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">must complete the\u00a0<a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-registration-form\/\" target=\"_blank\" rel=\"noopener\">previous one<\/a><\/span><a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-registration-form\/\">\u00a0that creates a registration form<\/a>.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id='introduction-to-the-php-login-form'>Introduction to the PHP login form <a href=\"#introduction-to-the-php-login-form\" class=\"anchor\" id=\"introduction-to-the-php-login-form\" title=\"Anchor for Introduction to the PHP login form\">#<\/a><\/h2>\r\n\r\n\r\n\r\n<p>In the previous tutorial, you learned how to create a form that allows <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-registration-form\/\">users to register for accounts<\/a>. Once the users register successfully, you redirect them to the login page so that they can log in using their usernames and passwords.<\/p>\r\n\r\n\r\n\r\n<p>The login page will contain a form that consists of the username and password inputs and a login button as follows:<\/p>\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"511\" height=\"354\" class=\"wp-image-2745\" style=\"width: 511px; height: 354px;\" src=\"https:\/\/phptutorial.net\/wp-content\/uploads\/2021\/09\/php-login.png\" alt=\"PHP Login\" srcset=\"https:\/\/www.phptutorial.net\/wp-content\/uploads\/2021\/09\/php-login.png 511w, https:\/\/www.phptutorial.net\/wp-content\/uploads\/2021\/09\/php-login-300x208.png 300w\" sizes=\"auto, (max-width: 511px) 100vw, 511px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n<p>To log in, users must enter their username and password and click the login button.<\/p>\r\n\r\n\r\n\r\n<p>If the username and password match, redirect them to a password-protected page. Otherwise, you redirect the users back to the login page with an error message:<\/p>\r\n\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"501\" height=\"433\" class=\"wp-image-2747\" src=\"https:\/\/phptutorial.net\/wp-content\/uploads\/2021\/09\/php-login-form.png\" alt=\"\" srcset=\"https:\/\/www.phptutorial.net\/wp-content\/uploads\/2021\/09\/php-login-form.png 501w, https:\/\/www.phptutorial.net\/wp-content\/uploads\/2021\/09\/php-login-form-300x259.png 300w\" sizes=\"auto, (max-width: 501px) 100vw, 501px\" \/><\/figure>\r\n<\/div>\r\n\r\n\r\n<p>Note that it&#8217;s more secure to issue a generic message (invalid username or password) when neither username nor password matches.<\/p>\r\n\r\n\r\n\r\n<p><a href=\"https:\/\/phptutorial.net\/wp-content\/uploads\/2025\/04\/auth_login.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Download the login form source code<\/a><\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\" id='create-the-login-form'>Create the login form <a href=\"#create-the-login-form\" class=\"anchor\" id=\"create-the-login-form\" title=\"Anchor for Create the login form\">#<\/a><\/h3>\r\n\r\n\r\n\r\n<p>First, create the <code>login.php<\/code> page in the <code>public<\/code> folder.<\/p>\r\n\r\n\r\n\r\n<p>Second, define a login form with the username and password inputs and a login button:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-meta\">&lt;!DOCTYPE <span class=\"hljs-meta-keyword\">html<\/span>&gt;<\/span>\r\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">html<\/span> <span class=\"hljs-attr\">lang<\/span>=<span class=\"hljs-string\">\"en\"<\/span>&gt;<\/span>\r\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">head<\/span>&gt;<\/span>\r\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">charset<\/span>=<span class=\"hljs-string\">\"UTF-8\"<\/span>&gt;<\/span>\r\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"viewport\"<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"width=device-width, initial-scale=1.0\"<\/span>&gt;<\/span>\r\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">link<\/span> <span class=\"hljs-attr\">rel<\/span>=<span class=\"hljs-string\">\"stylesheet\"<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"https:\/\/phptutorial.net\/app\/css\/style.css\"<\/span>&gt;<\/span>\r\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Login<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\r\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\r\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\r\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\r\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span> <span class=\"hljs-attr\">action<\/span>=<span class=\"hljs-string\">\"login.php\"<\/span> <span class=\"hljs-attr\">method<\/span>=<span class=\"hljs-string\">\"post\"<\/span>&gt;<\/span>\r\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Login<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\r\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\r\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">for<\/span>=<span class=\"hljs-string\">\"username\"<\/span>&gt;<\/span>Username:<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\r\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"text\"<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"username\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"username\"<\/span>&gt;<\/span>\r\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\r\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\r\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">for<\/span>=<span class=\"hljs-string\">\"password\"<\/span>&gt;<\/span>Password:<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\r\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"password\"<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"password\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"password\"<\/span>&gt;<\/span>\r\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\r\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">section<\/span>&gt;<\/span>\r\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"submit\"<\/span>&gt;<\/span>Login<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\r\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"register.php\"<\/span>&gt;<\/span>Register<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\r\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">section<\/span>&gt;<\/span>\r\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\r\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\r\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\r\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Like the <code>register.php<\/code> page, you can reuse the <code>header.php<\/code> and <code>footer.php<\/code> files from the <code>src\/inc<\/code> folder and use the <code>view()<\/code> function to load them to the <code>login.php<\/code> page as follows:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\r\n\r\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/bootstrap.php'<\/span>;\r\n<span class=\"hljs-meta\">?&gt;<\/span>\r\n\r\n<span class=\"hljs-meta\">&lt;?php<\/span> view(<span class=\"hljs-string\">'header'<\/span>, &#91;<span class=\"hljs-string\">'title'<\/span> =&gt; <span class=\"hljs-string\">'Login'<\/span>]) <span class=\"hljs-meta\">?&gt;<\/span>\r\n&lt;main&gt;\r\n    &lt;form action=<span class=\"hljs-string\">\"login.php\"<\/span> method=<span class=\"hljs-string\">\"post\"<\/span>&gt;\r\n        &lt;h1&gt;Login&lt;\/h1&gt;\r\n        &lt;div&gt;\r\n            &lt;label <span class=\"hljs-keyword\">for<\/span>=<span class=\"hljs-string\">\"username\"<\/span>&gt;Username:&lt;\/label&gt;\r\n            &lt;input type=<span class=\"hljs-string\">\"text\"<\/span> name=<span class=\"hljs-string\">\"username\"<\/span> id=<span class=\"hljs-string\">\"username\"<\/span>&gt;\r\n        &lt;\/div&gt;\r\n\r\n        &lt;div&gt;\r\n            &lt;label <span class=\"hljs-keyword\">for<\/span>=<span class=\"hljs-string\">\"password\"<\/span>&gt;Password:&lt;\/label&gt;\r\n            &lt;input type=<span class=\"hljs-string\">\"password\"<\/span> name=<span class=\"hljs-string\">\"password\"<\/span> id=<span class=\"hljs-string\">\"password\"<\/span>&gt;\r\n        &lt;\/div&gt;\r\n\r\n        &lt;section&gt;\r\n            &lt;button type=<span class=\"hljs-string\">\"submit\"<\/span>&gt;Login&lt;\/button&gt;\r\n            &lt;a href=<span class=\"hljs-string\">\"register.php\"<\/span>&gt;Register&lt;\/a&gt;\r\n        &lt;\/section&gt;\r\n    &lt;\/form&gt;\r\n&lt;\/main&gt;\r\n<span class=\"hljs-meta\">&lt;?php<\/span> view(<span class=\"hljs-string\">'footer'<\/span>) <span class=\"hljs-meta\">?&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>The login form is submitted to <code>login.php<\/code>. Therefore, you can check if the HTTP request method is POST before processing the form.<\/p>\r\n\r\n\r\n\r\n<p>To process the form, you create the <code>login.php<\/code> in the <code>src<\/code> folder.<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\r\n\r\n$inputs = &#91;];\r\n$errors = &#91;];\r\n\r\n<span class=\"hljs-keyword\">if<\/span> (is_post_request()) {\r\n\r\n    &#91;$inputs, $errors] = filter($_POST, &#91;\r\n        <span class=\"hljs-string\">'username'<\/span> =&gt; <span class=\"hljs-string\">'string | required'<\/span>,\r\n        <span class=\"hljs-string\">'password'<\/span> =&gt; <span class=\"hljs-string\">'string | required'<\/span>\r\n    ]);\r\n\r\n    <span class=\"hljs-keyword\">if<\/span> ($errors) {\r\n        redirect_with(<span class=\"hljs-string\">'login.php'<\/span>, &#91;<span class=\"hljs-string\">'errors'<\/span> =&gt; $errors, <span class=\"hljs-string\">'inputs'<\/span> =&gt; $inputs]);\r\n    }\r\n\r\n    <span class=\"hljs-comment\">\/\/ if login fails<\/span>\r\n    <span class=\"hljs-keyword\">if<\/span> (!login($inputs&#91;<span class=\"hljs-string\">'username'<\/span>], $inputs&#91;<span class=\"hljs-string\">'password'<\/span>])) {\r\n\r\n        $errors&#91;<span class=\"hljs-string\">'login'<\/span>] = <span class=\"hljs-string\">'Invalid username or password'<\/span>;\r\n\r\n        redirect_with(<span class=\"hljs-string\">'login.php'<\/span>, &#91;\r\n            <span class=\"hljs-string\">'errors'<\/span> =&gt; $errors,\r\n            <span class=\"hljs-string\">'inputs'<\/span> =&gt; $inputs\r\n        ]);\r\n    }\r\n    <span class=\"hljs-comment\">\/\/ login successfully<\/span>\r\n    redirect_to(<span class=\"hljs-string\">'index.php'<\/span>);\r\n\r\n} <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (is_get_request()) {\r\n    &#91;$errors, $inputs] = session_flash(<span class=\"hljs-string\">'errors'<\/span>, <span class=\"hljs-string\">'inputs'<\/span>);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>How it works.<\/p>\r\n\r\n\r\n\r\n<p>First, define two variables to store the sanitized data and error messages:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$inputs = &#91;];\r\n$errors = &#91;];<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Second, check if the HTTP request method is POST using the <code>is_post_request()<\/code> function:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">if<\/span> (is_post_request()) {\r\n    <span class=\"hljs-comment\">\/\/ ...<\/span>\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Third, sanitize and validate user inputs using the <code>filter()<\/code> function:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&#91;$inputs, $errors] = filter($_POST, &#91;\r\n    <span class=\"hljs-string\">'username'<\/span> =&gt; <span class=\"hljs-string\">'string | required'<\/span>,\r\n    <span class=\"hljs-string\">'password'<\/span> =&gt; <span class=\"hljs-string\">'string | required'<\/span>\r\n]);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Fourth, if either username or password is not provided, redirect users to the <code>login.php<\/code> page using the <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-prg\/\">post-redirect-get (PRG) technique<\/a> and set the <code>$errors<\/code> and <code>$inputs<\/code> in the session, using the <code>redirect_with()<\/code> function.<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">if<\/span> ($errors) {\r\n    redirect_with(<span class=\"hljs-string\">'login.php'<\/span>, &#91;\r\n        <span class=\"hljs-string\">'errors'<\/span> =&gt; $errors,\r\n        <span class=\"hljs-string\">'inputs'<\/span> =&gt; $inputs\r\n    ]);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Fifth, call the <code>login()<\/code> function to verify the username and password.<\/p>\r\n\r\n\r\n\r\n<p>If either username or password doesn&#8217;t match, set an error message with the key <code>login<\/code> and redirect users back to the <code>login.php<\/code> page:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\r\n\r\n<span class=\"hljs-keyword\">if<\/span> (!login($inputs&#91;<span class=\"hljs-string\">'username'<\/span>], $inputs&#91;<span class=\"hljs-string\">'password'<\/span>])) {\r\n\r\n    $errors&#91;<span class=\"hljs-string\">'login'<\/span>] = <span class=\"hljs-string\">'Invalid username or password'<\/span>;\r\n\r\n    redirect_with(<span class=\"hljs-string\">'login.php'<\/span>, &#91;\r\n        <span class=\"hljs-string\">'errors'<\/span> =&gt; $errors,\r\n        <span class=\"hljs-string\">'inputs'<\/span> =&gt; $inputs\r\n    ]);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Seventh, if both username and password match, redirect users to the <code>index.php<\/code> page:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">redirect_to(<span class=\"hljs-string\">'index.php'<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>The <code>index.php<\/code> is the password-protected page. Only logged-in users can access it\u2014more on this in the next section.<\/p>\r\n\r\n\r\n\r\n<p>Finally, get the <code>$inputs<\/code> and <code>$errors<\/code> from the session if the HTTP request method is GET.<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&#91;$errors, $inputs] = session_flash(<span class=\"hljs-string\">'errors'<\/span>, <span class=\"hljs-string\">'inputs'<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<h3 class=\"wp-block-heading\" id='show-the-entered-data-error-message-on-the-login-php-page'>Show the entered data &amp; error message on the login.php page <a href=\"#show-the-entered-data-error-message-on-the-login-php-page\" class=\"anchor\" id=\"show-the-entered-data-error-message-on-the-login-php-page\" title=\"Anchor for Show the entered data &amp; error message on the login.php page\">#<\/a><\/h3>\r\n\r\n\r\n\r\n<p>The <code>public\/login.php<\/code> needs to change to the following to show the user inputs as well as error messages:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\r\n\r\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/bootstrap.php'<\/span>;\r\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/login.php'<\/span>;\r\n<span class=\"hljs-meta\">?&gt;<\/span>\r\n\r\n<span class=\"hljs-meta\">&lt;?php<\/span> view(<span class=\"hljs-string\">'header'<\/span>, &#91;<span class=\"hljs-string\">'title'<\/span> =&gt; <span class=\"hljs-string\">'Login'<\/span>]) <span class=\"hljs-meta\">?&gt;<\/span>\r\n\r\n<span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-keyword\">isset<\/span>($errors&#91;<span class=\"hljs-string\">'login'<\/span>])) : <span class=\"hljs-meta\">?&gt;<\/span>\r\n    &lt;div <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span>=\"<span class=\"hljs-title\">alert<\/span> <span class=\"hljs-title\">alert<\/span>-<span class=\"hljs-title\">error<\/span>\"&gt;\r\n        &lt;?= $<span class=\"hljs-title\">errors<\/span>&#91;'<span class=\"hljs-title\">login<\/span>'] ?&gt;\r\n    &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\r\n&lt;?<span class=\"hljs-title\">php<\/span> <span class=\"hljs-title\">endif<\/span> ?&gt;\r\n\r\n    &lt;<span class=\"hljs-title\">form<\/span> <span class=\"hljs-title\">action<\/span>=\"<span class=\"hljs-title\">login<\/span>.<span class=\"hljs-title\">php<\/span>\" <span class=\"hljs-title\">method<\/span>=\"<span class=\"hljs-title\">post<\/span>\"&gt;\r\n        &lt;<span class=\"hljs-title\">h1<\/span>&gt;<span class=\"hljs-title\">Login<\/span>&lt;\/<span class=\"hljs-title\">h1<\/span>&gt;\r\n        &lt;<span class=\"hljs-title\">div<\/span>&gt;\r\n            &lt;<span class=\"hljs-title\">label<\/span> <span class=\"hljs-title\">for<\/span>=\"<span class=\"hljs-title\">username<\/span>\"&gt;<span class=\"hljs-title\">Username<\/span>:&lt;\/<span class=\"hljs-title\">label<\/span>&gt;\r\n            &lt;<span class=\"hljs-title\">input<\/span> <span class=\"hljs-title\">type<\/span>=\"<span class=\"hljs-title\">text<\/span>\" <span class=\"hljs-title\">name<\/span>=\"<span class=\"hljs-title\">username<\/span>\" <span class=\"hljs-title\">id<\/span>=\"<span class=\"hljs-title\">username<\/span>\" <span class=\"hljs-title\">value<\/span>=\"&lt;?= $<span class=\"hljs-title\">inputs<\/span>&#91;'<span class=\"hljs-title\">username<\/span>'] ?? '' ?&gt;\"&gt;\r\n            &lt;<span class=\"hljs-title\">small<\/span>&gt;&lt;?= $<span class=\"hljs-title\">errors<\/span>&#91;'<span class=\"hljs-title\">username<\/span>'] ?? '' ?&gt;&lt;\/<span class=\"hljs-title\">small<\/span>&gt;\r\n        &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\r\n        &lt;<span class=\"hljs-title\">div<\/span>&gt;\r\n            &lt;<span class=\"hljs-title\">label<\/span> <span class=\"hljs-title\">for<\/span>=\"<span class=\"hljs-title\">password<\/span>\"&gt;<span class=\"hljs-title\">Password<\/span>:&lt;\/<span class=\"hljs-title\">label<\/span>&gt;\r\n            &lt;<span class=\"hljs-title\">input<\/span> <span class=\"hljs-title\">type<\/span>=\"<span class=\"hljs-title\">password<\/span>\" <span class=\"hljs-title\">name<\/span>=\"<span class=\"hljs-title\">password<\/span>\" <span class=\"hljs-title\">id<\/span>=\"<span class=\"hljs-title\">password<\/span>\"&gt;\r\n            &lt;<span class=\"hljs-title\">small<\/span>&gt;&lt;?= $<span class=\"hljs-title\">errors<\/span>&#91;'<span class=\"hljs-title\">password<\/span>'] ?? '' ?&gt;&lt;\/<span class=\"hljs-title\">small<\/span>&gt;\r\n        &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\r\n        &lt;<span class=\"hljs-title\">section<\/span>&gt;\r\n            &lt;<span class=\"hljs-title\">button<\/span> <span class=\"hljs-title\">type<\/span>=\"<span class=\"hljs-title\">submit<\/span>\"&gt;<span class=\"hljs-title\">Login<\/span>&lt;\/<span class=\"hljs-title\">button<\/span>&gt;\r\n            &lt;<span class=\"hljs-title\">a<\/span> <span class=\"hljs-title\">href<\/span>=\"<span class=\"hljs-title\">register<\/span>.<span class=\"hljs-title\">php<\/span>\"&gt;<span class=\"hljs-title\">Register<\/span>&lt;\/<span class=\"hljs-title\">a<\/span>&gt;\r\n        &lt;\/<span class=\"hljs-title\">section<\/span>&gt;\r\n    &lt;\/<span class=\"hljs-title\">form<\/span>&gt;\r\n\r\n&lt;?<span class=\"hljs-title\">php<\/span> <span class=\"hljs-title\">view<\/span>('<span class=\"hljs-title\">footer<\/span>') ?&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Since the <code>login()<\/code> function doesn&#8217;t exist, we need to define it.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id='define-the-login-function'>Define the login() function <a href=\"#define-the-login-function\" class=\"anchor\" id=\"define-the-login-function\" title=\"Anchor for Define the login() function\">#<\/a><\/h2>\r\n\r\n\r\n\r\n<p>The <code>login()<\/code> function accepts username and password and returns true if they are valid. The logic of the <code>login()<\/code> function is as follows:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>First, find the username in the <code>users<\/code> table. If the user exists, go to step 2.<\/li>\r\n\r\n\r\n\r\n<li>Second, verify if the password matches.<\/li>\r\n\r\n\r\n\r\n<li>Third, issue an error message if the username doesn&#8217;t exist or the password doesn&#8217;t match.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p>To find a user from the <code>users<\/code> table by username, you can define a function <code>find_user_by_username()<\/code> in the <code>src\/auth.php<\/code> file:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">find_user_by_username<\/span><span class=\"hljs-params\">(string $username)<\/span>\r\n<\/span>{\r\n    $sql = <span class=\"hljs-string\">'SELECT username, password\r\n            FROM users\r\n            WHERE username=:username'<\/span>;\r\n\r\n    $statement = db()-&gt;prepare($sql);\r\n    $statement-&gt;bindValue(<span class=\"hljs-string\">':username'<\/span>, $username, PDO::PARAM_STR);\r\n    $statement-&gt;execute();\r\n\r\n    <span class=\"hljs-keyword\">return<\/span> $statement-&gt;fetch(PDO::FETCH_ASSOC);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>If a username exists in the <code>users<\/code> table, the <code>find_user_by_username()<\/code> function returns an associative array with two elements whose keys are username and password. Otherwise, it returns false.<\/p>\r\n\r\n\r\n\r\n<p>Since you store the password hash in the database, you need to use the built-in <code><a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-password_verify\/\">password_verify()<\/a><\/code> function to match the plain password with a hash.<\/p>\r\n\r\n\r\n\r\n<p>The <code>password_verify()<\/code> function returns true if a plain text password matches a hash, or false otherwise.<\/p>\r\n\r\n\r\n\r\n<p>If both <code>username<\/code> and <code>password<\/code> match, you can log the user in. To do that, you need to set a value in the <code>$_SESSION<\/code> for example:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$_SESSION&#91;<span class=\"hljs-string\">'username'<\/span>] = $username;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>In subsequent requests, you can check the <code>$_SESSION<\/code> variable to see if the user with a username is currently logged in. For example:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ check if the username has been logged in<\/span>\r\n<span class=\"hljs-keyword\">if<\/span>(<span class=\"hljs-keyword\">isset<\/span>($_SESSION&#91;<span class=\"hljs-string\">'username'<\/span>])) {\r\n    <span class=\"hljs-comment\">\/\/ already logged in<\/span>\r\n    <span class=\"hljs-comment\">\/\/ ...<\/span>\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Here&#8217;s the complete <code>login()<\/code> function:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">login<\/span><span class=\"hljs-params\">(string $username, string $password)<\/span>: <span class=\"hljs-title\">bool<\/span>\r\n<\/span>{\r\n    $user = find_user_by_username($username);\r\n\r\n    <span class=\"hljs-comment\">\/\/ if user found, check the password<\/span>\r\n    <span class=\"hljs-keyword\">if<\/span> ($user &amp;&amp; password_verify($password, $user&#91;<span class=\"hljs-string\">'password'<\/span>])) {\r\n\r\n        <span class=\"hljs-comment\">\/\/ prevent session fixation attack<\/span>\r\n        session_regenerate_id();\r\n\r\n        <span class=\"hljs-comment\">\/\/ set username in the session<\/span>\r\n        $_SESSION&#91;<span class=\"hljs-string\">'username'<\/span>] = $user&#91;<span class=\"hljs-string\">'username'<\/span>];\r\n        $_SESSION&#91;<span class=\"hljs-string\">'user_id'<\/span>]  = $user&#91;<span class=\"hljs-string\">'id'<\/span>];\r\n\r\n\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\r\n    }\r\n\r\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">false<\/span>;\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Note that you should call the <code>session_regenerate_id()<\/code> function to regenerate a new session id when users start logging in. It helps prevent the session fixation attack.<\/p>\r\n\r\n\r\n\r\n<p>The following defines the <code>is_user_logged_in()<\/code> function in the src\/auth.php file, which returns true if a user is currently logged in:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_user_logged_in<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">bool<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">isset<\/span>($_SESSION&#91;<span class=\"hljs-string\">'username'<\/span>]);\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>If users have not logged in, you can redirect them to the login.php page. The following defines the <code>require_login()<\/code> function that redirects to the login.php page if the current user is not logged in:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">require_login<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">void<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">if<\/span> (!is_user_logged_in()) {\r\n        redirect_to(<span class=\"hljs-string\">'login.php'<\/span>);\r\n    }\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>And you can call the <code>require_login()<\/code> function at the beginning of any page that requires login.<\/p>\r\n\r\n\r\n\r\n<p>For example, you can call it in the <code>public\/index.php<\/code> page like this:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\r\n\r\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/bootstrap.php'<\/span>;\r\nrequire_login();\r\n<span class=\"hljs-meta\">?&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id='log-a-user-out'>Log a user out <a href=\"#log-a-user-out\" class=\"anchor\" id=\"log-a-user-out\" title=\"Anchor for Log a user out\">#<\/a><\/h2>\r\n\r\n\r\n\r\n<p>To log a user out, you need to remove the value you set when logged in and redirect to the login.php page.<\/p>\r\n\r\n\r\n\r\n<p>In the <code>login()<\/code> function, you add the username to the <code>$_SESSION<\/code> variable. Therefore, you need to remove it to log the user out.<\/p>\r\n\r\n\r\n\r\n<p>The following defines the <code>logout()<\/code> function in the <code>auth.php<\/code> that logs a user out by removing the <code>username<\/code> and <code>user_id<\/code> from the <code>$_SESSION<\/code> variable:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">logout<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">void<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">if<\/span> (is_user_logged_in()) {\r\n        <span class=\"hljs-keyword\">unset<\/span>($_SESSION&#91;<span class=\"hljs-string\">'username'<\/span>], $_SESSION&#91;<span class=\"hljs-string\">'user_id'<\/span>]);\r\n        session_destroy();\r\n        redirect_to(<span class=\"hljs-string\">'login.php'<\/span>);\r\n    }\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>The following defines the <code>current_user()<\/code> function that returns the username of the currently logged-in user:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">current_user<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">if<\/span> (is_user_logged_in()) {\r\n        <span class=\"hljs-keyword\">return<\/span> $_SESSION&#91;<span class=\"hljs-string\">'username'<\/span>];\r\n    }\r\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">null<\/span>;\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<h3 class=\"wp-block-heading\" id='create-the-logout-link'>Create the logout link <a href=\"#create-the-logout-link\" class=\"anchor\" id=\"create-the-logout-link\" title=\"Anchor for Create the logout link\">#<\/a><\/h3>\r\n\r\n\r\n\r\n<p>When users log in successfully, they are redirected to the <code>index.php<\/code>.<\/p>\r\n\r\n\r\n\r\n<p>On the <code>index.php<\/code>, you can show a welcome message as well as a logout link like this:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\r\n\r\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/bootstrap.php'<\/span>;\r\nrequire_login();\r\n<span class=\"hljs-meta\">?&gt;<\/span>\r\n\r\n<span class=\"hljs-meta\">&lt;?php<\/span> view(<span class=\"hljs-string\">'header'<\/span>, &#91;<span class=\"hljs-string\">'title'<\/span> =&gt; <span class=\"hljs-string\">'Dashboard'<\/span>]) <span class=\"hljs-meta\">?&gt;<\/span>\r\n&lt;p&gt;Welcome <span class=\"hljs-meta\">&lt;?<\/span>= current_user() <span class=\"hljs-meta\">?&gt;<\/span> &lt;a href=<span class=\"hljs-string\">\"logout.php\"<\/span>&gt;Logout&lt;\/a&gt;&lt;\/p&gt;\r\n<span class=\"hljs-meta\">&lt;?php<\/span> view(<span class=\"hljs-string\">'footer'<\/span>) <span class=\"hljs-meta\">?&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>When users click the logout link, you need to call the <code>logout()<\/code> function to log the users out.<\/p>\r\n\r\n\r\n\r\n<p>To do that, you need to create the <code>logout.php<\/code> in the <code>public<\/code> folder.<\/p>\r\n\r\n\r\n\r\n<p>In the <code>logout.php<\/code>, you need to call the <code>logout()<\/code> function as follows:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\r\n\r\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/bootstrap.php'<\/span>;\r\nlogout();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id='redirect-if-users-already-logged-in'>Redirect if users already logged in <a href=\"#redirect-if-users-already-logged-in\" class=\"anchor\" id=\"redirect-if-users-already-logged-in\" title=\"Anchor for Redirect if users already logged in\">#<\/a><\/h2>\r\n\r\n\r\n\r\n<p>If users already logged in and navigated to the login.php or register.php page, you need to redirect them to the index.php.<\/p>\r\n\r\n\r\n\r\n<p>To do it, you can add the following code to the beginning of the <code>login.php<\/code> and <code>register.php<\/code> file in the <code>src<\/code> folder:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">\r\n<span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span>\r\n\r\n<span class=\"hljs-keyword\">if<\/span> (is_user_logged_in()) {\r\n    redirect_to(<span class=\"hljs-string\">'index.php'<\/span>);\r\n}<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>The following shows the <code>login.php<\/code> in the <code>src<\/code> folder:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span>\r\n\r\n<span class=\"hljs-keyword\">if<\/span> (is_user_logged_in()) {\r\n    redirect_to(<span class=\"hljs-string\">'index.php'<\/span>);\r\n}\r\n\r\n$inputs = &#91;];\r\n$errors = &#91;];\r\n\r\n<span class=\"hljs-keyword\">if<\/span> (is_post_request()) {\r\n\r\n    <span class=\"hljs-comment\">\/\/ sanitize &amp; validate user inputs<\/span>\r\n    &#91;$inputs, $errors] = filter($_POST, &#91;\r\n        <span class=\"hljs-string\">'username'<\/span> =&gt; <span class=\"hljs-string\">'string | required'<\/span>,\r\n        <span class=\"hljs-string\">'password'<\/span> =&gt; <span class=\"hljs-string\">'string | required'<\/span>\r\n    ]);\r\n\r\n    <span class=\"hljs-comment\">\/\/ if validation error<\/span>\r\n    <span class=\"hljs-keyword\">if<\/span> ($errors) {\r\n        redirect_with(<span class=\"hljs-string\">'login.php'<\/span>, &#91;\r\n            <span class=\"hljs-string\">'errors'<\/span> =&gt; $errors,\r\n            <span class=\"hljs-string\">'inputs'<\/span> =&gt; $inputs\r\n        ]);\r\n    }\r\n\r\n    <span class=\"hljs-comment\">\/\/ if login fails<\/span>\r\n    <span class=\"hljs-keyword\">if<\/span> (!login($inputs&#91;<span class=\"hljs-string\">'username'<\/span>], $inputs&#91;<span class=\"hljs-string\">'password'<\/span>])) {\r\n\r\n        $errors&#91;<span class=\"hljs-string\">'login'<\/span>] = <span class=\"hljs-string\">'Invalid username or password'<\/span>;\r\n\r\n        redirect_with(<span class=\"hljs-string\">'login.php'<\/span>, &#91;\r\n            <span class=\"hljs-string\">'errors'<\/span> =&gt; $errors,\r\n            <span class=\"hljs-string\">'inputs'<\/span> =&gt; $inputs\r\n        ]);\r\n    }\r\n\r\n    <span class=\"hljs-comment\">\/\/ login successfully<\/span>\r\n    redirect_to(<span class=\"hljs-string\">'index.php'<\/span>);\r\n\r\n} <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (is_get_request()) {\r\n    &#91;$errors, $inputs] = session_flash(<span class=\"hljs-string\">'errors'<\/span>, <span class=\"hljs-string\">'inputs'<\/span>);\r\n}<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p><a href=\"https:\/\/phptutorial.net\/wp-content\/uploads\/2025\/04\/auth_login.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Download the login form source code<\/a><\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id='summary'>Summary <a href=\"#summary\" class=\"anchor\" id=\"summary\" title=\"Anchor for Summary\">#<\/a><\/h2>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Use the <code>password_verify()<\/code> function to verify the password.<\/li>\r\n\r\n\r\n\r\n<li>Call the <code>session_regenerate_id()<\/code> function to prevent the session fixation attack.<\/li>\r\n\r\n\r\n\r\n<li>Add one or more values (username and user id) to the <code>$_SESSION<\/code> variable to mark if a user has been logged in.<\/li>\r\n<\/ul>\r\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Did you find this tutorial useful?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"2742\"\n\t\t\t\tdata-post-url=\"https:\/\/www.phptutorial.net\/php-tutorial\/php-login\/\"\n\t\t\t\tdata-post-title=\"PHP Login\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"2742\"\n\t\t\t\tdata-post-url=\"https:\/\/www.phptutorial.net\/php-tutorial\/php-login\/\"\n\t\t\t\tdata-post-title=\"PHP Login\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\n\t\t\t<button class=\"btn btn-primary wth-btn-submit\">Send<\/button>\n\t\t\t<button class=\"btn wth-btn-cancel\">Cancel<\/button>\n\t\t\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>PHP Login Form<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":15,"menu_order":103,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2742","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages\/2742","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/comments?post=2742"}],"version-history":[{"count":5,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages\/2742\/revisions"}],"predecessor-version":[{"id":3344,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages\/2742\/revisions\/3344"}],"up":[{"embeddable":true,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages\/15"}],"wp:attachment":[{"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/media?parent=2742"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}