{"id":2719,"date":"2021-09-21T11:17:16","date_gmt":"2021-09-21T11:17:16","guid":{"rendered":"https:\/\/phptutorial.net\/?page_id=2719"},"modified":"2025-04-09T07:48:52","modified_gmt":"2025-04-09T07:48:52","slug":"php-registration-form","status":"publish","type":"page","link":"https:\/\/www.phptutorial.net\/php-tutorial\/php-registration-form\/","title":{"rendered":"PHP Registration Form"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn how to create a PHP registration form from scratch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='introduction-to-php-registration-form'>Introduction to PHP registration form <a href=\"#introduction-to-php-registration-form\" class=\"anchor\" id=\"introduction-to-php-registration-form\" title=\"Anchor for Introduction to PHP registration form\">#<\/a><\/h2>\n\n\n\n<p>In this tutorial, you&#8217;ll create a user registration form that consists of the following input fields: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Username <\/li>\n\n\n\n<li>Email<\/li>\n\n\n\n<li>Password <\/li>\n\n\n\n<li>Password confirmation <\/li>\n\n\n\n<li>Agreement checkbox<\/li>\n\n\n\n<li>Register button<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"568\" height=\"763\" src=\"https:\/\/phptutorial.net\/wp-content\/uploads\/2021\/09\/php-registration-form.png\" alt=\"PHP Registration Form\" class=\"wp-image-2723\" style=\"width:568px;height:763px\" srcset=\"https:\/\/www.phptutorial.net\/wp-content\/uploads\/2021\/09\/php-registration-form.png 568w, https:\/\/www.phptutorial.net\/wp-content\/uploads\/2021\/09\/php-registration-form-223x300.png 223w\" sizes=\"auto, (max-width: 568px) 100vw, 568px\" \/><\/figure>\n<\/div>\n\n\n<p>When a user fills out the form and click the Register button, you need to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-sanitize-input\/\">Sanitize<\/a> &amp; <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-validation\/\">validate<\/a> the user inputs.<\/li>\n\n\n\n<li>If the form data is not valid, show the form with the user inputs and error messages.<\/li>\n\n\n\n<li>If the form data is valid, <a href=\"https:\/\/phptutorial.net\/php-pdo\/php-pdo-insert\/\">insert<\/a> the new user into the <code>users<\/code> database table, set a <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-flash-messages\/\">flash message<\/a>, <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-redirection\/\">redirect<\/a> the user to the <code>login.php<\/code> page and display the flash message. Note that you&#8217;ll learn how to <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-login\/\">build a login form<\/a> in the next tutorial.<\/li>\n<\/ul>\n\n\n\n<p><a href=\"https:\/\/phptutorial.net\/wp-content\/uploads\/2025\/04\/auth.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Download the Registration Form Project Source Code<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='setup-project-structure'>Setup project structure <a href=\"#setup-project-structure\" class=\"anchor\" id=\"setup-project-structure\" title=\"Anchor for Setup project structure\">#<\/a><\/h2>\n\n\n\n<p>First, create a project root folder, e.g., <code>auth<\/code>.<\/p>\n\n\n\n<p>Second, create the following folders under the project root folder:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">\u251c\u2500\u2500 config\n\u251c\u2500\u2500 public\n\u2514\u2500\u2500 src\n   \u251c\u2500\u2500 inc\n   \u2514\u2500\u2500 libs<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The following describes the purpose of each folder:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Folder<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td><code>config<\/code><\/td><td>Store the configuration file such as database configuration<\/td><\/tr><tr><td><code>public<\/code><\/td><td>Store the public files accessed directly by the users<\/td><\/tr><tr><td><code>src<\/code><\/td><td>Store the source files that should not be exposed to the public<\/td><\/tr><tr><td><code>src\/inc<\/code><\/td><td>Store the commonly included files such as the header and footer of a page<\/td><\/tr><tr><td><code>src\/libs<\/code><\/td><td>Store the library files, e.g., validation, sanitization, etc.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id='remove-the-public-from-the-url'>Remove the public from the URL <a href=\"#remove-the-public-from-the-url\" class=\"anchor\" id=\"remove-the-public-from-the-url\" title=\"Anchor for Remove the public from the URL\">#<\/a><\/h2>\n\n\n\n<p>First, create  <code>register.php<\/code> in the <code>public<\/code> folder. To access the <code>register.php<\/code> page, you need to use the following URL:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">http:&#47;&#47;localhost\/auth\/public\/register.php<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To remove the <code>public<\/code> from the above URL, you can use the URL Rewrite module of the Apache Web Server. To do it, you need to use a <code>.htaccess<\/code> file.<\/p>\n\n\n\n<p>Second, create <code>.htaccess<\/code> file in the project root folder (<code>auth<\/code>) and use the following code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">&lt;IfModule mod_rewrite.c&gt;\n    RewriteEngine on\n    RewriteRule ^$ public\/ &#91;L]\n    RewriteRule (.*) public\/$1 &#91;L]\n&lt;\/IfModule&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The above directives instruct Apache to remove the <code>public<\/code> from the URL. If you open the URL <code>http:\/\/localhost\/auth\/register.php<\/code>, you&#8217;ll see an error. <\/p>\n\n\n\n<p>To fix the error, you&#8217;ll need another <code>.htaccess<\/code> file in the <code>public<\/code> folder.<\/p>\n\n\n\n<p>Third, create another <code>.htaccess<\/code> in the <code>public<\/code> folder and use the following directives:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">&lt;IfModule mod_rewrite.c&gt;\n    Options -Multiviews\n    RewriteEngine On\n    RewriteBase \/auth\/public\n    RewriteCond %{REQUEST_FILENAME} !-d\n    RewriteCond %{REQUEST_FILENAME} !-f\n&lt;\/IfModule&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now, you can access the <code>register.php<\/code> page without using the <code>\/public\/<\/code> in the URL like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">http:&#47;&#47;localhost\/auth\/register.php<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='create-the-registration-form'>Create the registration form <a href=\"#create-the-registration-form\" class=\"anchor\" id=\"create-the-registration-form\" title=\"Anchor for Create the registration form\">#<\/a><\/h2>\n\n\n\n<p>First, create a registration form in the <code>register.php<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" 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>\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>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">head<\/span>&gt;<\/span>\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>\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>\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>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Register<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span> <span class=\"hljs-attr\">action<\/span>=<span class=\"hljs-string\">\"register.php\"<\/span> <span class=\"hljs-attr\">method<\/span>=<span class=\"hljs-string\">\"post\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>Sign Up<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\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>\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>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">for<\/span>=<span class=\"hljs-string\">\"email\"<\/span>&gt;<\/span>Email:<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"email\"<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"email\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"email\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\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>\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>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">for<\/span>=<span class=\"hljs-string\">\"password2\"<\/span>&gt;<\/span>Password Again:<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\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\">\"password2\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"password2\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">for<\/span>=<span class=\"hljs-string\">\"agree\"<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"checkbox\"<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"agree\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"agree\"<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"yes\"<\/span>\/&gt;<\/span> I agree\n                with the\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"#\"<\/span> <span class=\"hljs-attr\">title<\/span>=<span class=\"hljs-string\">\"term of services\"<\/span>&gt;<\/span>term of services<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\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>Register<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">footer<\/span>&gt;<\/span>Already a member? <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"login.php\"<\/span>&gt;<\/span>Login here<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">footer<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><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>\n\n\n<p>If you access the URL <code>http:\/\/localhost\/auth\/register.php<\/code>, you&#8217;ll see a user registration form.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id='make-the-registration-form-more-organized'>Make the registration form more organized <a href=\"#make-the-registration-form-more-organized\" class=\"anchor\" id=\"make-the-registration-form-more-organized\" title=\"Anchor for Make the registration form more organized\">#<\/a><\/h3>\n\n\n\n<p>First, create the <code>header.php<\/code> file in the <code>src\/inc<\/code> folder and copy the header section of the <code>register.php<\/code> file to the <code>header.php<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" 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>\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>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">head<\/span>&gt;<\/span>\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>\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>\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>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Register<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><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>\n\n\n<p>Second, create the <code>footer.php<\/code> file in the <code>src\/inc<\/code> folder and copy the footer section of the <code>register.php<\/code> file to the <code>footer.php<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><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>\n\n\n<p>Third, include the <code>header.php<\/code> and <code>footer.php<\/code> files from the <code>inc<\/code> folder in the <code>register.php<\/code> file. Typically, you use the <code><a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-require\/\">require<\/a><\/code> or <code><a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-include-file\/\">include<\/a><\/code> construct.<\/p>\n\n\n\n<p>However, you may want to include the <code>header.php<\/code> and <code>footer.php<\/code> files in other files, e.g., <code>login.php<\/code>. Therefore, the title of the page should not be fixed like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Register<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><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>\n\n\n<p>To&nbsp;make&nbsp;the&nbsp;<code>&lt;title&gt;<\/code>&nbsp;tag dynamic,&nbsp;you&nbsp;can create a <code>helpers.php<\/code> file in the <code>src\/libs<\/code> folder and&nbsp;define the&nbsp;<code>view()<\/code> function&nbsp;that&nbsp;loads&nbsp;the&nbsp;code&nbsp;from&nbsp;a&nbsp;PHP file&nbsp;and&nbsp;passes&nbsp;data&nbsp;to&nbsp;it:<code><title>&lt;\/code&gt; more dynamic, you can define a new function called &lt;code&gt;view()&lt;\/code&gt; that loads the code from a file and passes data to it:&lt;\/p&gt;<\/title><\/code><\/p>\n\n\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\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">view<\/span><span class=\"hljs-params\">(string $filename, array $data = &#91;])<\/span>: <span class=\"hljs-title\">void<\/span>\n<\/span>{\n    <span class=\"hljs-comment\">\/\/ create variables from the associative array<\/span>\n    <span class=\"hljs-keyword\">foreach<\/span> ($data <span class=\"hljs-keyword\">as<\/span> $key =&gt; $value) {\n        $$key = $value;\n    }\n    <span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/inc\/'<\/span> . $filename . <span class=\"hljs-string\">'.php'<\/span>;\n}\n<\/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>\n\n\n<p>This <code>view()<\/code> function loads the code from a file without the need of specifying the <code>.php<\/code> file extension. <\/p>\n\n\n\n<p>The <code>view()<\/code> function allows you to pass data to the included file as an <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-associative-arrays\/\">associative array<\/a>. In the included file, you can use the keys of elements as the variable names and the values as the variable values. Check out the <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-variable-variables\/\">variable variables<\/a> for more detail.<\/p>\n\n\n\n<p>For example, the following uses the <code>view()<\/code> function to load the code from the <code>header.php<\/code> file and makes the <code>title<\/code> as a variable in the <code>header.php<\/code> file:<\/p>\n\n\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> view(<span class=\"hljs-string\">'header'<\/span>, &#91;<span class=\"hljs-string\">'title'<\/span> =&gt; <span class=\"hljs-string\">'Register'<\/span>]) <span class=\"hljs-meta\">?&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>\n\n\n<p>Since the <code>header.php<\/code> file accept the <code>title<\/code> as a variable, you need to update it as follows:<\/p>\n\n\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\">&lt;!DOCTYPE html&gt;\n&lt;html lang=<span class=\"hljs-string\">\"en\"<\/span>&gt;\n&lt;head&gt;\n    &lt;meta charset=<span class=\"hljs-string\">\"UTF-8\"<\/span>&gt;\n    &lt;meta name=<span class=\"hljs-string\">\"viewport\"<\/span> content=<span class=\"hljs-string\">\"width=device-width, initial-scale=1.0\"<\/span>&gt;\n    &lt;link rel=<span class=\"hljs-string\">\"stylesheet\"<\/span> href=<span class=\"hljs-string\">\"https:\/\/phptutorial.net\/app\/css\/style.css\"<\/span>&gt;\n    &lt;title&gt;<span class=\"hljs-meta\">&lt;?<\/span>= $title ?? <span class=\"hljs-string\">'Home'<\/span> <span class=\"hljs-meta\">?&gt;<\/span>&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;main&gt;<\/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>\n\n\n<p>In this new <code>header.php<\/code> file, the <code>title<\/code> variable will default to <code>Home<\/code> if it is not set.   <\/p>\n\n\n\n<p>To use the <code>view()<\/code> function in the <code>register.php<\/code>, the <code>register.php<\/code> must include the <code>helpers.php<\/code>.<\/p>\n\n\n\n<p>To centrally include the files, you can create a <code>bootstrap.php<\/code> file in the <code>src<\/code> folder. The <code>bootstrap.php<\/code> will include all the necessary files. And you include the <code>bootstrap.php<\/code> file in the <code>register.php<\/code> file.<\/p>\n\n\n\n<p>The <code>boostrap.php<\/code> file will be like this:<\/p>\n\n\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\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/helpers.php'<\/span>;<\/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>\n\n\n<p>And the <code>register.php<\/code> file will look like the following:<\/p>\n\n\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-meta\">&lt;?php<\/span>\n\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/bootstrap.php'<\/span>;\n<span class=\"hljs-meta\">?&gt;<\/span>\n\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\">'Register'<\/span>]) <span class=\"hljs-meta\">?&gt;<\/span>\n\n&lt;form action=<span class=\"hljs-string\">\"register.php\"<\/span> method=<span class=\"hljs-string\">\"post\"<\/span>&gt;\n...\n&lt;\/form&gt;\n\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-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>\n\n\n<h2 class=\"wp-block-heading\" id='process-the-registration-form-submission'>Process the registration form submission <a href=\"#process-the-registration-form-submission\" class=\"anchor\" id=\"process-the-registration-form-submission\" title=\"Anchor for Process the registration form submission\">#<\/a><\/h2>\n\n\n\n<p>The registration form submits to <code>register.php<\/code> using the HTTP POST method. To process the form data, you can check if the HTTP request is POST at the beginning of the <code>register.php<\/code> file like this:<\/p>\n\n\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-keyword\">if<\/span>(strtoupper($_SERVER&#91;<span class=\"hljs-string\">'REQUEST_METHOD'<\/span>]) === <span class=\"hljs-string\">'POST'<\/span>) {\n    <span class=\"hljs-comment\">\/\/ process the form<\/span>\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>\n\n\n<p>Since the above code can be used on other pages, you can define the <code>is_post_request()<\/code> function in the <code>helpers.php<\/code> file to encapsulate it:<\/p>\n\n\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_post_request<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> strtoupper($_SERVER&#91;<span class=\"hljs-string\">'REQUEST_METHOD'<\/span>]) === <span class=\"hljs-string\">'POST'<\/span>;\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>\n\n\n<p>Similarly, you can also define the <code>is_get_request()<\/code> function that returns <code>true<\/code> if the current HTTP request is GET:<\/p>\n\n\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\">is_get_request<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> strtoupper($_SERVER&#91;<span class=\"hljs-string\">'REQUEST_METHOD'<\/span>]) === <span class=\"hljs-string\">'GET'<\/span>;\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>\n\n\n<p>And at the beginning of the <code>register.php<\/code> file, you can use the <code>is_post_request()<\/code> function as follows:<\/p>\n\n\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>\n\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/bootstrap.php'<\/span>;\n\n\n<span class=\"hljs-keyword\">if<\/span> (is_post_request()) {\n    <span class=\"hljs-comment\">\/\/...<\/span>\n}<\/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>\n\n\n<h3 class=\"wp-block-heading\" id='sanitize-validate-user-inputs'>Sanitize &amp; validate user inputs <a href=\"#sanitize-validate-user-inputs\" class=\"anchor\" id=\"sanitize-validate-user-inputs\" title=\"Anchor for Sanitize &amp; validate user inputs\">#<\/a><\/h3>\n\n\n\n<p>To sanitize &amp; validate user inputs, you can use the <code>sanitize()<\/code> and <code>valdiate()<\/code> functions developed in the <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-sanitize-input\/\">sanitizing<\/a> and <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-validation\/\">validating input tutorial<\/a> or you can use the <code><a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-filter\/\">filter()<\/a><\/code> function.<\/p>\n\n\n\n<p>To use these functions, you need to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First, create the <code>sanitization.php<\/code>, <code>validation.php<\/code>, and <code>filter.php<\/code> files in the <code>src\/libs<\/code> folder.<\/li>\n\n\n\n<li>Second, add the code to these files (please look at the code in the end of this tutorial).<\/li>\n\n\n\n<li>Third, include these files in the <code>bootstrap.php<\/code> file.<\/li>\n<\/ul>\n\n\n\n<p>The <code>bootstrap.php<\/code> file will look like the following:<\/p>\n\n\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-meta\">&lt;?php<\/span>\n\nsession_start();\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/helpers.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/sanitization.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/validation.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/filter.php'<\/span>;<\/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>\n\n\n<p>The following shows how to use the <code>filter()<\/code> function to sanitize and validate the user inputs:<\/p>\n\n\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\">$fields = &#91;\n    <span class=\"hljs-string\">'username'<\/span> =&gt; <span class=\"hljs-string\">'string | required | alphanumeric | between: 3, 25 | unique: users, username'<\/span>,\n    <span class=\"hljs-string\">'email'<\/span> =&gt; <span class=\"hljs-string\">'email | required | email | unique: users, email'<\/span>,\n    <span class=\"hljs-string\">'password'<\/span> =&gt; <span class=\"hljs-string\">'string | required | secure'<\/span>,\n    <span class=\"hljs-string\">'password2'<\/span> =&gt; <span class=\"hljs-string\">'string | required | same: password'<\/span>,\n    <span class=\"hljs-string\">'agree'<\/span> =&gt; <span class=\"hljs-string\">'string | required'<\/span>\n];\n\n<span class=\"hljs-comment\">\/\/ custom messages<\/span>\n$messages = &#91;\n    <span class=\"hljs-string\">'password2'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'required'<\/span> =&gt; <span class=\"hljs-string\">'Please enter the password again'<\/span>,\n        <span class=\"hljs-string\">'same'<\/span> =&gt; <span class=\"hljs-string\">'The password does not match'<\/span>\n    ],\n    <span class=\"hljs-string\">'agree'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'required'<\/span> =&gt; <span class=\"hljs-string\">'You need to agree to the term of services to register'<\/span>\n    ]\n];\n\n&#91;$inputs, $errors] = filter($_POST, $fields, $messages);<\/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>\n\n\n<p>In the <code>filter()<\/code> function, you pass three arguments:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <code>$_POST<\/code> array stores the user inputs.<\/li>\n\n\n\n<li>The <code>$fields<\/code> associative array stores the rules of all fields.<\/li>\n\n\n\n<li>The <code>$messages<\/code> is a <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-multidimensional-array\/\">multidimensional array<\/a> that specifies the custom messages for the the required and same rules of the <code>password2<\/code> and <code>agree<\/code> fields. This argument is optional. If you skip it, the <code>filter()<\/code> function will use default validation messages.<\/li>\n<\/ul>\n\n\n\n<p>If the form is invalid, you need to redirect the users to the <code>register.php<\/code> page using the <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-prg\/\">post-redirect-get<\/a> (PRG) technique. Also, you need to add the <code>$inputs<\/code> and <code>$errors<\/code> arrays to the <code>$_SESSION<\/code> variable so that you can access them in the <code>GET<\/code> request after redirection.<\/p>\n\n\n\n<p>If the form is valid, you need to create a user account and redirect the users to the <code>login.php<\/code> page using the PRG technique. To show a message once across pages, you can use the session-based <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-flash-messages\/\">flash messages<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id='manage-flash-messages'>Manage flash messages <a href=\"#manage-flash-messages\" class=\"anchor\" id=\"manage-flash-messages\" title=\"Anchor for Manage flash messages\">#<\/a><\/h3>\n\n\n\n<p>To manage flash messages, you use the <code>flash()<\/code> function defined in the <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-flash-messages\/\">flash message tutorial<\/a>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First, create a new file <code>flash.php<\/code> in the <code>src\/libs<\/code> folder.<\/li>\n\n\n\n<li>Second, add the code to the <code>flash.php<\/code> file.<\/li>\n\n\n\n<li>Third, include the <code>flash.php<\/code> file in the <code>bootstrap.php<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>To create a flash message in the <code>register.php<\/code> file, you call the <code>flash()<\/code> function:<\/p>\n\n\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\">flash(\n    <span class=\"hljs-string\">'user_register_success'<\/span>,\n    <span class=\"hljs-string\">'Your account has been created successfully. Please login here.'<\/span>,\n    <span class=\"hljs-string\">'success'<\/span>\n);<\/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>\n\n\n<p>To show all the flash messages, you call the <code>flash()<\/code> function without passing any arguments:<\/p>\n\n\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\">flash()<\/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>\n\n\n<p>For example, you can show the flash messages in the <code>header.php<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;!DOCTYPE html&gt;\n&lt;html lang=<span class=\"hljs-string\">\"en\"<\/span>&gt;\n&lt;head&gt;\n    &lt;meta charset=<span class=\"hljs-string\">\"UTF-8\"<\/span>&gt;\n    &lt;meta name=<span class=\"hljs-string\">\"viewport\"<\/span> content=<span class=\"hljs-string\">\"width=device-width, initial-scale=1.0\"<\/span>&gt;\n    &lt;link rel=<span class=\"hljs-string\">\"stylesheet\"<\/span> href=<span class=\"hljs-string\">\"https:\/\/phptutorial.net\/app\/css\/style.css\"<\/span>&gt;\n    &lt;title&gt;<span class=\"hljs-meta\">&lt;?<\/span>= $title ?? <span class=\"hljs-string\">'Home'<\/span> <span class=\"hljs-meta\">?&gt;<\/span>&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;main&gt;\n<span class=\"hljs-meta\">&lt;?php<\/span> flash() <span class=\"hljs-meta\">?&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='set-the-error-css-class'>Set the error CSS class <a href=\"#set-the-error-css-class\" class=\"anchor\" id=\"set-the-error-css-class\" title=\"Anchor for Set the error CSS class\">#<\/a><\/h3>\n\n\n\n<p>When a form field has invalid data, e.g., wrong email address format, you need to highlight it by adding an <code>error<\/code> CSS class.<\/p>\n\n\n\n<p>The following defines the <code>error_class()<\/code> function in the <code>src\/libs\/helpers.php<\/code> file, which returns the <code>'error'<\/code> class if the <code>$errors<\/code> array has an error associated with a field:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" 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\">error_class<\/span><span class=\"hljs-params\">(array $errors, string $field)<\/span>: <span class=\"hljs-title\">string<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">isset<\/span>($errors&#91;$field]) ? <span class=\"hljs-string\">'error'<\/span> : <span class=\"hljs-string\">''<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='redirect'>Redirect <a href=\"#redirect\" class=\"anchor\" id=\"redirect\" title=\"Anchor for Redirect\">#<\/a><\/h3>\n\n\n\n<p>After users register for accounts successfully, you need to <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-redirection\/\">redirect<\/a> them to the login page. To do that, you can use the <code>header()<\/code> function with the <code>exit<\/code> construct:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">header (<span class=\"hljs-string\">'Location: login.php'<\/span>);\n<span class=\"hljs-keyword\">exit<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><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>\n\n\n<p>The following defines a function called <code>redirect_to()<\/code> function in the <code>helpers.php<\/code> file to wrap the above code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-26\" 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\">redirect_to<\/span><span class=\"hljs-params\">(string $url)<\/span>: <span class=\"hljs-title\">void<\/span>\n<\/span>{\n    header(<span class=\"hljs-string\">'Location:'<\/span> . $url);\n    <span class=\"hljs-keyword\">exit<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-26\"><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>\n\n\n<p>If the form data is invalid, you can redirect users back to the <code>register.php<\/code> page. Before doing it, you need to add the <code>$inputs<\/code> and <code>$errors<\/code> variables to the <code>$_SESSION<\/code> variable so that you can access them in the subsequent request.<\/p>\n\n\n\n<p>The following defines the <code>redirect_with()<\/code> function that adds the elements of the <code>$items<\/code> array to the <code>$_SESSION<\/code> variable and redirects to a URL:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-27\" 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\">redirect_with<\/span><span class=\"hljs-params\">(string $url, array $items)<\/span>: <span class=\"hljs-title\">void<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">foreach<\/span> ($items <span class=\"hljs-keyword\">as<\/span> $key =&gt; $value) {\n        $_SESSION&#91;$key] = $value;\n    }\n\n    redirect_to($url);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-27\"><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>\n\n\n<p>Notice that the <code>redirect_with()<\/code> function calls the <code>redirect_to()<\/code> function to redirect users to a URL.<\/p>\n\n\n\n<p>The following shows how to use the <code>redirect_with()<\/code> function that adds the <code>$inputs<\/code> and <code>$errors<\/code> array and redirect to the <code>register.php<\/code> page:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-28\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">redirect_with(<span class=\"hljs-string\">'register.php'<\/span>, &#91;\n   <span class=\"hljs-string\">'inputs'<\/span> =&gt; $inputs,\n   <span class=\"hljs-string\">'errors'<\/span> =&gt; $errors\n]);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-28\"><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>\n\n\n<p>If you want to set a flash message and redirect to another page, you can define a new helper function <code>redirect_with_message()<\/code> like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-29\" 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\">redirect_with_message<\/span><span class=\"hljs-params\">(string $url, string $message, string $type=FLASH_SUCCESS)<\/span>\n<\/span>{\n    flash(<span class=\"hljs-string\">'flash_'<\/span> . uniqid(), $message, $type);\n    redirect_to($url);\n\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-29\"><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>\n\n\n<p>Note that the flash message&#8217;s name starts with the <code>flash_<\/code> and is followed by a unique id returned by the <code>uniqid()<\/code> function. It&#8217;ll look like this:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">flash_615481fce49e8<\/code><\/span><\/pre>\n\n\n<p>We use a generated name for the flash message because it&#8217;s not important in this case. And we&#8217;ll display all the flash messages anyway. <\/p>\n\n\n\n<p>For example, you can redirect users to the login page with a success message like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-30\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">redirect_with_message(\n    <span class=\"hljs-string\">'login.php'<\/span>,\n    <span class=\"hljs-string\">'Your account has been created successfully. Please login here.'<\/span>\n);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-30\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" id='flash-session-data'>Flash session data <a href=\"#flash-session-data\" class=\"anchor\" id=\"flash-session-data\" title=\"Anchor for Flash session data\">#<\/a><\/h3>\n\n\n\n<p>To get data from the <code>$_SESSION<\/code> and remove it immediately, you can define a helper function <code>session_flash()<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-31\" 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\">session_flash<\/span><span class=\"hljs-params\">(...$keys)<\/span>: <span class=\"hljs-title\">array<\/span>\n<\/span>{\n    $data = &#91;];\n    <span class=\"hljs-keyword\">foreach<\/span> ($keys <span class=\"hljs-keyword\">as<\/span> $key) {\n        <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-keyword\">isset<\/span>($_SESSION&#91;$key])) {\n            $data&#91;] = $_SESSION&#91;$key];\n            <span class=\"hljs-keyword\">unset<\/span>($_SESSION&#91;$key]);\n        } <span class=\"hljs-keyword\">else<\/span> {\n            $data&#91;] = &#91;];\n        }\n    }\n    <span class=\"hljs-keyword\">return<\/span> $data;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-31\"><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>\n\n\n<p>The <code>session_flash()<\/code> function accepts a variable number of keys. It&#8217;s also known as a <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-variadic-functions\/\">variadic function<\/a>.<\/p>\n\n\n\n<p>If a key exists in the <code>$_SESSION<\/code> variable, the function adds the value of that key to the return array and unsets the value. Otherwise, the function will return an empty array for that key. <\/p>\n\n\n\n<p>The following uses the <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-array-destructuring\/\">array destructuring<\/a> to get the <code>$inputs<\/code> and <code>$errors<\/code> from the <code>$_SESSION<\/code> variable and unset them using the <code>session_flash()<\/code> function:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-32\" 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-32\"><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>\n\n\n<p>The <code>boostrap.php<\/code> function is updated to include the call to <code>session_start()<\/code> function and the <code>flash.php<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-33\" 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>\n\nsession_start();\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/helpers.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/flash.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/sanitization.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/validation.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/filter.php'<\/span>;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-33\"><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>\n\n\n<p id=\"note\">Note that you need to call the <code>session_start()<\/code> function to start a new <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-session\/\">session<\/a> or resume an existing one to manage the session data.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='the-complete-register-php-file'>The complete register.php file <a href=\"#the-complete-register-php-file\" class=\"anchor\" id=\"the-complete-register-php-file\" title=\"Anchor for The complete register.php file\">#<\/a><\/h2>\n\n\n\n<p>The following shows the complete <code>register.php<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-34\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/bootstrap.php'<\/span>;\n\n$errors = &#91;];\n$inputs = &#91;];\n\n<span class=\"hljs-keyword\">if<\/span> (is_post_request()) {\n\n    $fields = &#91;\n        <span class=\"hljs-string\">'username'<\/span> =&gt; <span class=\"hljs-string\">'string | required | alphanumeric | between: 3, 25 | unique: users, username'<\/span>,\n        <span class=\"hljs-string\">'email'<\/span> =&gt; <span class=\"hljs-string\">'email | required | email | unique: users, email'<\/span>,\n        <span class=\"hljs-string\">'password'<\/span> =&gt; <span class=\"hljs-string\">'string | required | secure'<\/span>,\n        <span class=\"hljs-string\">'password2'<\/span> =&gt; <span class=\"hljs-string\">'string | required | same: password'<\/span>,\n        <span class=\"hljs-string\">'agree'<\/span> =&gt; <span class=\"hljs-string\">'string | required'<\/span>\n    ];\n\n    <span class=\"hljs-comment\">\/\/ custom messages<\/span>\n    $messages = &#91;\n        <span class=\"hljs-string\">'password2'<\/span> =&gt; &#91;\n            <span class=\"hljs-string\">'required'<\/span> =&gt; <span class=\"hljs-string\">'Please enter the password again'<\/span>,\n            <span class=\"hljs-string\">'same'<\/span> =&gt; <span class=\"hljs-string\">'The password does not match'<\/span>\n        ],\n        <span class=\"hljs-string\">'agree'<\/span> =&gt; &#91;\n            <span class=\"hljs-string\">'required'<\/span> =&gt; <span class=\"hljs-string\">'You need to agree to the term of services to register'<\/span>\n        ]\n    ];\n\n    &#91;$inputs, $errors] = filter($_POST, $fields, $messages);\n\n    <span class=\"hljs-keyword\">if<\/span> ($errors) {\n        redirect_with(<span class=\"hljs-string\">'register.php'<\/span>, &#91;\n            <span class=\"hljs-string\">'inputs'<\/span> =&gt; $inputs,\n            <span class=\"hljs-string\">'errors'<\/span> =&gt; $errors\n        ]);\n    }\n\n    <span class=\"hljs-keyword\">if<\/span> (register_user($inputs&#91;<span class=\"hljs-string\">'email'<\/span>], $inputs&#91;<span class=\"hljs-string\">'username'<\/span>], $inputs&#91;<span class=\"hljs-string\">'password'<\/span>])) {\n        redirect_with_message(\n            <span class=\"hljs-string\">'login.php'<\/span>,\n            <span class=\"hljs-string\">'Your account has been created successfully. Please login here.'<\/span>\n        );\n\n    }\n\n} <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (is_get_request()) {\n    &#91;$inputs, $errors] = session_flash(<span class=\"hljs-string\">'inputs'<\/span>, <span class=\"hljs-string\">'errors'<\/span>);\n}\n\n<span class=\"hljs-meta\">?&gt;<\/span>\n\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\">'Register'<\/span>]) <span class=\"hljs-meta\">?&gt;<\/span>\n\n&lt;form action=<span class=\"hljs-string\">\"register.php\"<\/span> method=<span class=\"hljs-string\">\"post\"<\/span>&gt;\n    &lt;h1&gt;Sign Up&lt;\/h1&gt;\n    &lt;div&gt;\n        &lt;label <span class=\"hljs-keyword\">for<\/span>=<span class=\"hljs-string\">\"username\"<\/span>&gt;Username:&lt;\/label&gt;\n        &lt;input type=<span class=\"hljs-string\">\"text\"<\/span> name=<span class=\"hljs-string\">\"username\"<\/span> id=<span class=\"hljs-string\">\"username\"<\/span> value=<span class=\"hljs-string\">\"&lt;?= $inputs&#91;'username'] ?? '' ?&gt;\"<\/span>\n               <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span>=\"&lt;?= <span class=\"hljs-title\">error_class<\/span>($<span class=\"hljs-title\">errors<\/span>, '<span class=\"hljs-title\">username<\/span>') ?&gt;\"&gt;\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;\n    &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\n\n    &lt;<span class=\"hljs-title\">div<\/span>&gt;\n        &lt;<span class=\"hljs-title\">label<\/span> <span class=\"hljs-title\">for<\/span>=\"<span class=\"hljs-title\">email<\/span>\"&gt;<span class=\"hljs-title\">Email<\/span>:&lt;\/<span class=\"hljs-title\">label<\/span>&gt;\n        &lt;<span class=\"hljs-title\">input<\/span> <span class=\"hljs-title\">type<\/span>=\"<span class=\"hljs-title\">email<\/span>\" <span class=\"hljs-title\">name<\/span>=\"<span class=\"hljs-title\">email<\/span>\" <span class=\"hljs-title\">id<\/span>=\"<span class=\"hljs-title\">email<\/span>\" <span class=\"hljs-title\">value<\/span>=\"&lt;?= $<span class=\"hljs-title\">inputs<\/span>&#91;'<span class=\"hljs-title\">email<\/span>'] ?? '' ?&gt;\"\n               <span class=\"hljs-title\">class<\/span>=\"&lt;?= <span class=\"hljs-title\">error_class<\/span>($<span class=\"hljs-title\">errors<\/span>, '<span class=\"hljs-title\">email<\/span>') ?&gt;\"&gt;\n        &lt;<span class=\"hljs-title\">small<\/span>&gt;&lt;?= $<span class=\"hljs-title\">errors<\/span>&#91;'<span class=\"hljs-title\">email<\/span>'] ?? '' ?&gt;&lt;\/<span class=\"hljs-title\">small<\/span>&gt;\n    &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\n\n    &lt;<span class=\"hljs-title\">div<\/span>&gt;\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;\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>\" <span class=\"hljs-title\">value<\/span>=\"&lt;?= $<span class=\"hljs-title\">inputs<\/span>&#91;'<span class=\"hljs-title\">password<\/span>'] ?? '' ?&gt;\"\n               <span class=\"hljs-title\">class<\/span>=\"&lt;?= <span class=\"hljs-title\">error_class<\/span>($<span class=\"hljs-title\">errors<\/span>, '<span class=\"hljs-title\">password<\/span>') ?&gt;\"&gt;\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;\n    &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\n\n    &lt;<span class=\"hljs-title\">div<\/span>&gt;\n        &lt;<span class=\"hljs-title\">label<\/span> <span class=\"hljs-title\">for<\/span>=\"<span class=\"hljs-title\">password2<\/span>\"&gt;<span class=\"hljs-title\">Password<\/span> <span class=\"hljs-title\">Again<\/span>:&lt;\/<span class=\"hljs-title\">label<\/span>&gt;\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\">password2<\/span>\" <span class=\"hljs-title\">id<\/span>=\"<span class=\"hljs-title\">password2<\/span>\" <span class=\"hljs-title\">value<\/span>=\"&lt;?= $<span class=\"hljs-title\">inputs<\/span>&#91;'<span class=\"hljs-title\">password2<\/span>'] ?? '' ?&gt;\"\n               <span class=\"hljs-title\">class<\/span>=\"&lt;?= <span class=\"hljs-title\">error_class<\/span>($<span class=\"hljs-title\">errors<\/span>, '<span class=\"hljs-title\">password2<\/span>') ?&gt;\"&gt;\n        &lt;<span class=\"hljs-title\">small<\/span>&gt;&lt;?= $<span class=\"hljs-title\">errors<\/span>&#91;'<span class=\"hljs-title\">password2<\/span>'] ?? '' ?&gt;&lt;\/<span class=\"hljs-title\">small<\/span>&gt;\n    &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\n\n    &lt;<span class=\"hljs-title\">div<\/span>&gt;\n        &lt;<span class=\"hljs-title\">label<\/span> <span class=\"hljs-title\">for<\/span>=\"<span class=\"hljs-title\">agree<\/span>\"&gt;\n            &lt;<span class=\"hljs-title\">input<\/span> <span class=\"hljs-title\">type<\/span>=\"<span class=\"hljs-title\">checkbox<\/span>\" <span class=\"hljs-title\">name<\/span>=\"<span class=\"hljs-title\">agree<\/span>\" <span class=\"hljs-title\">id<\/span>=\"<span class=\"hljs-title\">agree<\/span>\" <span class=\"hljs-title\">value<\/span>=\"<span class=\"hljs-title\">checked<\/span>\" &lt;?= $<span class=\"hljs-title\">inputs<\/span>&#91;'<span class=\"hljs-title\">agree<\/span>'] ?? '' ?&gt; \/&gt; <span class=\"hljs-title\">I<\/span>\n            <span class=\"hljs-title\">agree<\/span>\n            <span class=\"hljs-title\">with<\/span> <span class=\"hljs-title\">the<\/span>\n            &lt;<span class=\"hljs-title\">a<\/span> <span class=\"hljs-title\">href<\/span>=\"#\" <span class=\"hljs-title\">title<\/span>=\"<span class=\"hljs-title\">term<\/span> <span class=\"hljs-title\">of<\/span> <span class=\"hljs-title\">services<\/span>\"&gt;<span class=\"hljs-title\">term<\/span> <span class=\"hljs-title\">of<\/span> <span class=\"hljs-title\">services<\/span>&lt;\/<span class=\"hljs-title\">a<\/span>&gt;\n        &lt;\/<span class=\"hljs-title\">label<\/span>&gt;\n        &lt;<span class=\"hljs-title\">small<\/span>&gt;&lt;?= $<span class=\"hljs-title\">errors<\/span>&#91;'<span class=\"hljs-title\">agree<\/span>'] ?? '' ?&gt;&lt;\/<span class=\"hljs-title\">small<\/span>&gt;\n    &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\n\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\">Register<\/span>&lt;\/<span class=\"hljs-title\">button<\/span>&gt;\n\n    &lt;<span class=\"hljs-title\">footer<\/span>&gt;<span class=\"hljs-title\">Already<\/span> <span class=\"hljs-title\">a<\/span> <span class=\"hljs-title\">member<\/span>? &lt;<span class=\"hljs-title\">a<\/span> <span class=\"hljs-title\">href<\/span>=\"<span class=\"hljs-title\">login<\/span>.<span class=\"hljs-title\">php<\/span>\"&gt;<span class=\"hljs-title\">Login<\/span> <span class=\"hljs-title\">here<\/span>&lt;\/<span class=\"hljs-title\">a<\/span>&gt;&lt;\/<span class=\"hljs-title\">footer<\/span>&gt;\n\n&lt;\/<span class=\"hljs-title\">form<\/span>&gt;\n\n&lt;?<span class=\"hljs-title\">php<\/span> <span class=\"hljs-title\">view<\/span>('<span class=\"hljs-title\">footer<\/span>') ?&gt;\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-34\"><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>\n\n\n<p>To separate the logic and view parts, you can create a new file <code>register.php<\/code> in the <code>src<\/code> folder and add the first part of the <code>public\/register.php<\/code> file to it:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-35\" 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>\n\n$errors = &#91;];\n$inputs = &#91;];\n\n<span class=\"hljs-keyword\">if<\/span> (is_post_request()) {\n\n    $fields = &#91;\n        <span class=\"hljs-string\">'username'<\/span> =&gt; <span class=\"hljs-string\">'string | required | alphanumeric | between: 3, 25 | unique: users, username'<\/span>,\n        <span class=\"hljs-string\">'email'<\/span> =&gt; <span class=\"hljs-string\">'email | required | email | unique: users, email'<\/span>,\n        <span class=\"hljs-string\">'password'<\/span> =&gt; <span class=\"hljs-string\">'string | required | secure'<\/span>,\n        <span class=\"hljs-string\">'password2'<\/span> =&gt; <span class=\"hljs-string\">'string | required | same: password'<\/span>,\n        <span class=\"hljs-string\">'agree'<\/span> =&gt; <span class=\"hljs-string\">'string | required'<\/span>\n    ];\n\n    <span class=\"hljs-comment\">\/\/ custom messages<\/span>\n    $messages = &#91;\n        <span class=\"hljs-string\">'password2'<\/span> =&gt; &#91;\n            <span class=\"hljs-string\">'required'<\/span> =&gt; <span class=\"hljs-string\">'Please enter the password again'<\/span>,\n            <span class=\"hljs-string\">'same'<\/span> =&gt; <span class=\"hljs-string\">'The password does not match'<\/span>\n        ],\n        <span class=\"hljs-string\">'agree'<\/span> =&gt; &#91;\n            <span class=\"hljs-string\">'required'<\/span> =&gt; <span class=\"hljs-string\">'You need to agree to the term of services to register'<\/span>\n        ]\n    ];\n\n    &#91;$inputs, $errors] = filter($_POST, $fields, $messages);\n\n    <span class=\"hljs-keyword\">if<\/span> ($errors) {\n        redirect_with(<span class=\"hljs-string\">'register.php'<\/span>, &#91;\n            <span class=\"hljs-string\">'inputs'<\/span> =&gt; $inputs,\n            <span class=\"hljs-string\">'errors'<\/span> =&gt; $errors\n        ]);\n    }\n\n    <span class=\"hljs-keyword\">if<\/span> (register_user($inputs&#91;<span class=\"hljs-string\">'email'<\/span>], $inputs&#91;<span class=\"hljs-string\">'username'<\/span>], $inputs&#91;<span class=\"hljs-string\">'password'<\/span>])) {\n        redirect_with_message(\n            <span class=\"hljs-string\">'login.php'<\/span>,\n            <span class=\"hljs-string\">'Your account has been created successfully. Please login here.'<\/span>\n        );\n\n    }\n\n} <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (is_get_request()) {\n    &#91;$inputs, $errors] = session_flash(<span class=\"hljs-string\">'inputs'<\/span>, <span class=\"hljs-string\">'errors'<\/span>);\n}<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-35\"><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>\n\n\n<p>And the following shows the <code>public\/register.php<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-36\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">&lt;?php\n\n<span class=\"hljs-built_in\">require<\/span> __DIR__ . <span class=\"hljs-string\">'\/..\/src\/bootstrap.php'<\/span>;\n<span class=\"hljs-built_in\">require<\/span> __DIR__ . <span class=\"hljs-string\">'\/..\/src\/register.php'<\/span>;\n?&gt;\n\n&lt;?php view(<span class=\"hljs-string\">'header'<\/span>, &#91;<span class=\"hljs-string\">'title'<\/span> =&gt; <span class=\"hljs-string\">'Register'<\/span>]) ?&gt;\n\n&lt;form action=\"register.php\" method=\"post\"&gt;\n    &lt;h1&gt;Sign Up&lt;\/h1&gt;\n\n    &lt;div&gt;\n        &lt;label for=\"username\"&gt;Username:&lt;\/label&gt;\n        &lt;input type=\"text\" name=\"username\" id=\"username\" value=\"&lt;?= $inputs&#91;'username'] ?? '' ?&gt;\"\n               class=\"&lt;?= error_class($errors, 'username') ?&gt;\"&gt;\n        &lt;small&gt;&lt;?= $errors&#91;'username'] ?? '' ?&gt;&lt;\/small&gt;\n    &lt;\/div&gt;\n\n    &lt;div&gt;\n        &lt;label for=\"email\"&gt;Email:&lt;\/label&gt;\n        &lt;input type=\"email\" name=\"email\" id=\"email\" value=\"&lt;?= $inputs&#91;'email'] ?? '' ?&gt;\"\n               class=\"&lt;?= error_class($errors, 'email') ?&gt;\"&gt;\n        &lt;small&gt;&lt;?= $errors&#91;'email'] ?? '' ?&gt;&lt;\/small&gt;\n    &lt;\/div&gt;\n\n    &lt;div&gt;\n        &lt;label for=\"password\"&gt;Password:&lt;\/label&gt;\n        &lt;input type=\"password\" name=\"password\" id=\"password\" value=\"&lt;?= $inputs&#91;'password'] ?? '' ?&gt;\"\n               class=\"&lt;?= error_class($errors, 'password') ?&gt;\"&gt;\n        &lt;small&gt;&lt;?= $errors&#91;'password'] ?? '' ?&gt;&lt;\/small&gt;\n    &lt;\/div&gt;\n\n    &lt;div&gt;\n        &lt;label for=\"password2\"&gt;Password Again:&lt;\/label&gt;\n        &lt;input type=\"password\" name=\"password2\" id=\"password2\" value=\"&lt;?= $inputs&#91;'password2'] ?? '' ?&gt;\"\n               class=\"&lt;?= error_class($errors, 'password2') ?&gt;\"&gt;\n        &lt;small&gt;&lt;?= $errors&#91;'password2'] ?? '' ?&gt;&lt;\/small&gt;\n    &lt;\/div&gt;\n\n    &lt;div&gt;\n        &lt;label for=\"agree\"&gt;\n            &lt;input type=\"checkbox\" name=\"agree\" id=\"agree\" value=\"checked\" &lt;?= $inputs&#91;'agree'] ?? '' ?&gt; \/&gt; I\n            agree\n            with the\n            &lt;a href=\"#\" title=\"term of services\"&gt;term of services&lt;\/a&gt;\n        &lt;\/label&gt;\n        &lt;small&gt;&lt;?= $errors&#91;'agree'] ?? '' ?&gt;&lt;\/small&gt;\n    &lt;\/div&gt;\n\n    &lt;button type=\"submit\"&gt;Register&lt;\/button&gt;\n\n    &lt;footer&gt;Already a member? &lt;a href=\"login.php\"&gt;Login here&lt;\/a&gt;&lt;\/footer&gt;\n\n&lt;\/form&gt;\n\n&lt;?php view('footer') ?&gt;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-36\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Since the <code>register_user()<\/code> function doesn&#8217;t exist, you need to define it. Before doing that, you need to create a new database and the <code>users<\/code> table.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='create-a-new-database-and-the-users-table'>Create a new database and the users table <a href=\"#create-a-new-database-and-the-users-table\" class=\"anchor\" id=\"create-a-new-database-and-the-users-table\" title=\"Anchor for Create a new database and the users table\">#<\/a><\/h2>\n\n\n\n<p>We&#8217;ll use MySQL to store the user information. To interact with MySQL, you can use any MySQL client tool such as phpmyadmin or mysql.<\/p>\n\n\n\n<p>First, <a href=\"https:\/\/www.mysqltutorial.org\/mysql-basics\/mysql-create-database\/\" target=\"_blank\" rel=\"noreferrer noopener\">create a new database<\/a> called <code>auth<\/code> in the MySQL database server:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-37\" data-shcb-language-name=\"SQL (Structured Query Language)\" data-shcb-language-slug=\"sql\"><span><code class=\"hljs language-sql\"><span class=\"hljs-keyword\">CREATE<\/span> <span class=\"hljs-keyword\">DATABASE<\/span> auth;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-37\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">SQL (Structured Query Language)<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">sql<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, <a href=\"https:\/\/www.mysqltutorial.org\/mysql-basics\/mysql-create-table\/\" target=\"_blank\" rel=\"noreferrer noopener\">create a new table<\/a> called <code>users<\/code> to store the user information:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-38\" data-shcb-language-name=\"SQL (Structured Query Language)\" data-shcb-language-slug=\"sql\"><span><code class=\"hljs language-sql\"><span class=\"hljs-keyword\">CREATE<\/span> <span class=\"hljs-keyword\">TABLE<\/span> <span class=\"hljs-keyword\">users<\/span> (\n    <span class=\"hljs-keyword\">id<\/span> <span class=\"hljs-built_in\">INT<\/span> AUTO_INCREMENT PRIMARY <span class=\"hljs-keyword\">KEY<\/span>,\n    username <span class=\"hljs-built_in\">VARCHAR<\/span>(<span class=\"hljs-number\">25<\/span>) <span class=\"hljs-keyword\">NOT<\/span> <span class=\"hljs-literal\">NULL<\/span> <span class=\"hljs-keyword\">UNIQUE<\/span>,\n    email <span class=\"hljs-built_in\">VARCHAR<\/span>(<span class=\"hljs-number\">100<\/span>) <span class=\"hljs-keyword\">NOT<\/span> <span class=\"hljs-literal\">NULL<\/span> <span class=\"hljs-keyword\">UNIQUE<\/span>,\n    <span class=\"hljs-keyword\">password<\/span> <span class=\"hljs-built_in\">VARCHAR<\/span>(<span class=\"hljs-number\">256<\/span>) <span class=\"hljs-keyword\">NOT<\/span> <span class=\"hljs-literal\">NULL<\/span>,\n    is_admin <span class=\"hljs-built_in\">TINYINT<\/span>(<span class=\"hljs-number\">1<\/span>) <span class=\"hljs-keyword\">not<\/span> <span class=\"hljs-literal\">null<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-number\">0<\/span>,\n    created_at <span class=\"hljs-built_in\">TIMESTAMP<\/span> <span class=\"hljs-keyword\">DEFAULT<\/span> <span class=\"hljs-keyword\">CURRENT_TIMESTAMP<\/span>,\n    updated_at DATETIME <span class=\"hljs-keyword\">DEFAULT<\/span> <span class=\"hljs-keyword\">CURRENT_TIMESTAMP<\/span> <span class=\"hljs-keyword\">ON<\/span> <span class=\"hljs-keyword\">UPDATE<\/span> <span class=\"hljs-keyword\">CURRENT_TIMESTAMP<\/span>\n);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-38\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">SQL (Structured Query Language)<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">sql<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>users<\/code> table has the following columns:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>id<\/code> is the <a href=\"https:\/\/www.mysqltutorial.org\/mysql-basics\/mysql-primary-key\/\">primary key<\/a>. Since the id is an auto-increment column, MySQL will increase its value by one for each new row. In other words, you don&#8217;t need to provide the id when inserting a new row into the table.<\/li>\n\n\n\n<li><code>username<\/code> is a varying character column with the <code><a href=\"https:\/\/www.mysqltutorial.org\/mysql-basics\/mysql-not-null-constraint\/\" target=\"_blank\" rel=\"noreferrer noopener\">NOT NULL<\/a><\/code> and <code><a href=\"https:\/\/www.mysqltutorial.org\/mysql-basics\/mysql-unique-constraint\/\" target=\"_blank\" rel=\"noreferrer noopener\">UNIQUE<\/a><\/code> constraints. It means that there will be no two rows with the same username.<\/li>\n\n\n\n<li><code>email<\/code> column is like the <code>username<\/code> column, which is <code>NOT NULL<\/code> and <code>UNIQUE<\/code>.<\/li>\n\n\n\n<li><code>password<\/code> column a varying column and not null.<\/li>\n\n\n\n<li><code>is_admin<\/code> is a tiny integer column. Its default value is zero. If <code>is_admin<\/code> is zero, the user is not the admin. If the <code>is_admin<\/code> is 1, the user is an admin which has more privileges than regular users.<\/li>\n\n\n\n<li><code>created_at<\/code> is a timestamp column that MySQL will update it to the current timestamp when you insert a new row into the table.<\/li>\n\n\n\n<li><code>updated_at<\/code> is a datetime column that MySQL will update it to the current timestamp automatically when you update an existing row.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id='connect-to-the-mysql-database'>Connect to the MySQL database <a href=\"#connect-to-the-mysql-database\" class=\"anchor\" id=\"connect-to-the-mysql-database\" title=\"Anchor for Connect to the MySQL database\">#<\/a><\/h2>\n\n\n\n<p>To <a href=\"https:\/\/phptutorial.net\/php-pdo\/pdo-connecting-to-mysql\/\">connect to the MySQL database<\/a>, you&#8217;ll use the <a href=\"https:\/\/phptutorial.net\/php-pdo\/\">PHP data object (or PDO)<\/a> library.<\/p>\n\n\n\n<p>First, create a new file <code>database.php<\/code> file in the <code>config<\/code> folder and add the following database parameters to the file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-39\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> DB_HOST = <span class=\"hljs-string\">'localhost'<\/span>;\n<span class=\"hljs-keyword\">const<\/span> DB_NAME = <span class=\"hljs-string\">'auth'<\/span>;\n<span class=\"hljs-keyword\">const<\/span> DB_USER = <span class=\"hljs-string\">'root'<\/span>;\n<span class=\"hljs-keyword\">const<\/span> DB_PASSWORD = <span class=\"hljs-string\">''<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-39\"><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>\n\n\n<p>Second, create the <code>connection.php<\/code> file in the <code>src\/libs<\/code> folder.<\/p>\n\n\n\n<p>Third, define the <code>db()<\/code> function that connects the database <strong>once<\/strong> and returns a new PDO object. The <code>db()<\/code> function uses the database configuration defined in the <code>config\/database.php<\/code> file.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-40\" 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\">db<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">PDO<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">static<\/span> $pdo;\n\n    <span class=\"hljs-keyword\">if<\/span> (!$pdo) {\n        $pdo = <span class=\"hljs-keyword\">new<\/span> PDO(\n            sprintf(<span class=\"hljs-string\">\"mysql:host=%s;dbname=%s;charset=UTF8\"<\/span>, DB_HOST, DB_NAME),\n            DB_USER,\n            DB_PASSWORD,\n            &#91;PDO::ATTR_ERRMODE =&gt; PDO::ERRMODE_EXCEPTION]\n        );\n    }\n    <span class=\"hljs-keyword\">return<\/span> $pdo;\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-40\"><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>\n\n\n<p>In the <code>db()<\/code> function, the <code>$pdo<\/code> is a static variable. When you call the <code>db()<\/code> function for the first time, the <code>$pdo<\/code> variable is not initialized. Therefore, the code block inside the <code>if<\/code> statement executes that connects to the database and returns a new PDO object.<\/p>\n\n\n\n<p>Since the <code>$pdo<\/code> is a static variable, it&#8217;s still alive after the function <code>db()<\/code> function completes. Therefore, when you call the <code>db()<\/code> function again, it returns the PDO object. In other words, the function doesn&#8217;t connect to the database again.<\/p>\n\n\n\n<p>Since creating a connection to the database is expensive in terms of time and resources, you should connect to the database once per request.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='define-the-register_user-function'>Define the register_user() function <a href=\"#define-the-register_user-function\" class=\"anchor\" id=\"define-the-register_user-function\" title=\"Anchor for Define the register_user() function\">#<\/a><\/h2>\n\n\n\n<p>First, create a new file called <code>auth.php<\/code> in the <code>src<\/code> folder.<\/p>\n\n\n\n<p>Second, define the <code>register_user()<\/code> function that <a href=\"https:\/\/phptutorial.net\/php-pdo\/php-pdo-insert\/\">inserts<\/a> a new user into the <code>users<\/code> table:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-41\" 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\">register_user<\/span><span class=\"hljs-params\">(string $email, string $username, string $password, bool $is_admin = false)<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    $sql = <span class=\"hljs-string\">'INSERT INTO users(username, email, password, is_admin)\n            VALUES(:username, :email, :password, :is_admin)'<\/span>;\n\n    $statement = db()-&gt;prepare($sql);\n\n    $statement-&gt;bindValue(<span class=\"hljs-string\">':username'<\/span>, $username, PDO::PARAM_STR);\n    $statement-&gt;bindValue(<span class=\"hljs-string\">':email'<\/span>, $email, PDO::PARAM_STR);\n    $statement-&gt;bindValue(<span class=\"hljs-string\">':password'<\/span>, password_hash($password, PASSWORD_BCRYPT), PDO::PARAM_STR);\n    $statement-&gt;bindValue(<span class=\"hljs-string\">':is_admin'<\/span>, (int)$is_admin, PDO::PARAM_INT);\n\n    <span class=\"hljs-keyword\">return<\/span> $statement-&gt;execute();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-41\"><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>\n\n\n<p>When storing a password in the database, you never store it in plain text for security reasons. Instead, you should always hash the password before storing it.<\/p>\n\n\n\n<p>To hash a password, you use the built-in <code><a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-password_hash\/\">password_hash()<\/a><\/code> function:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-42\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">password_hash($password, PASSWORD_BCRYPT)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-42\"><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>\n\n\n<p>For example, if the password is <code>Password1<\/code>, the <code>password_hash()<\/code> function returns the following hash:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-43\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n<span class=\"hljs-keyword\">echo<\/span> password_hash(<span class=\"hljs-string\">'Password1'<\/span>, PASSWORD_BCRYPT);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-43\"><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>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-44\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">$2y$10$QlUdCEXY68bswdVsKlE.5OjHa7X8fvtCmlYLnIkfvbcGd..mqDfwq<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-44\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>PASSWORD_BCRYPT<\/code> argument instructs the <code>password_hash()<\/code> function to use the <code>CRYPT_BLOWFISH<\/code>&nbsp;algorithm which is very secure.<\/p>\n\n\n\n<p>Since <code>password_hash()<\/code> is a one-way function, hackers cannot &#8220;decrypt&#8221; it to the original plain text (<code>Password1<\/code>). This provides a defense against the passwords being compromised when a database is leaked.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='put-it-all-together'>Put it all together <a href=\"#put-it-all-together\" class=\"anchor\" id=\"put-it-all-together\" title=\"Anchor for Put it all together\">#<\/a><\/h2>\n\n\n\n<p>The project folder and file structure will be like the following:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-45\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">\u251c\u2500\u2500 config\n|  \u2514\u2500\u2500 database.php\n\u251c\u2500\u2500 <span class=\"hljs-keyword\">public<\/span>\n|  \u2514\u2500\u2500 register.php\n\u2514\u2500\u2500 src\n   \u251c\u2500\u2500 auth.php\n   \u251c\u2500\u2500 bootstrap.php\n   \u251c\u2500\u2500 inc\n   |  \u251c\u2500\u2500 footer.php\n   |  \u2514\u2500\u2500 header.php\n   \u251c\u2500\u2500 libs\n   |  \u251c\u2500\u2500 connection.php\n   |  \u251c\u2500\u2500 flash.php\n   |  \u251c\u2500\u2500 helpers.php\n   |  \u251c\u2500\u2500 sanitization.php\n   |  \u251c\u2500\u2500 validation.php\n   |  \u2514\u2500\u2500 filter.php\n   \u2514\u2500\u2500 register.php<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-45\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='configdatabase-php-file'>config\/database.php file <a href=\"#configdatabase-php-file\" class=\"anchor\" id=\"configdatabase-php-file\" title=\"Anchor for config\/database.php file\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-46\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> DB_HOST = <span class=\"hljs-string\">'localhost'<\/span>;\n<span class=\"hljs-keyword\">const<\/span> DB_NAME = <span class=\"hljs-string\">'auth'<\/span>;\n<span class=\"hljs-keyword\">const<\/span> DB_USER = <span class=\"hljs-string\">'root'<\/span>;\n<span class=\"hljs-keyword\">const<\/span> DB_PASSWORD = <span class=\"hljs-string\">''<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-46\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='srcincauth-php-file'>src\/inc\/auth.php file <a href=\"#srcincauth-php-file\" class=\"anchor\" id=\"srcincauth-php-file\" title=\"Anchor for src\/inc\/auth.php file\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-47\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n<span class=\"hljs-comment\">\/**\n* Register a user\n*\n* <span class=\"hljs-doctag\">@param<\/span> string $email\n* <span class=\"hljs-doctag\">@param<\/span> string $username\n* <span class=\"hljs-doctag\">@param<\/span> string $password\n* <span class=\"hljs-doctag\">@param<\/span> bool $is_admin\n* <span class=\"hljs-doctag\">@return<\/span> bool\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">register_user<\/span><span class=\"hljs-params\">(string $email, string $username, string $password, bool $is_admin = false)<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    $sql = <span class=\"hljs-string\">'INSERT INTO users(username, email, password, is_admin)\n            VALUES(:username, :email, :password, :is_admin)'<\/span>;\n\n    $statement = db()-&gt;prepare($sql);\n\n    $statement-&gt;bindValue(<span class=\"hljs-string\">':username'<\/span>, $username, PDO::PARAM_STR);\n    $statement-&gt;bindValue(<span class=\"hljs-string\">':email'<\/span>, $email, PDO::PARAM_STR);\n    $statement-&gt;bindValue(<span class=\"hljs-string\">':password'<\/span>, password_hash($password, PASSWORD_BCRYPT), PDO::PARAM_STR);\n    $statement-&gt;bindValue(<span class=\"hljs-string\">':is_admin'<\/span>, (int)$is_admin, PDO::PARAM_INT);\n\n\n    <span class=\"hljs-keyword\">return<\/span> $statement-&gt;execute();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-47\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='srclibsconnection-php'>src\/libs\/connection.php <a href=\"#srclibsconnection-php\" class=\"anchor\" id=\"srclibsconnection-php\" title=\"Anchor for src\/libs\/connection.php\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-48\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n<span class=\"hljs-comment\">\/**\n * Connect to the database and returns an instance of PDO class\n * or false if the connection fails\n *\n * <span class=\"hljs-doctag\">@return<\/span> PDO\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">db<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">PDO<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">static<\/span> $pdo;\n\n    <span class=\"hljs-keyword\">if<\/span> (!$pdo) {\n        $pdo = <span class=\"hljs-keyword\">new<\/span> PDO(\n            sprintf(<span class=\"hljs-string\">\"mysql:host=%s;dbname=%s;charset=UTF8\"<\/span>, DB_HOST, DB_NAME),\n            DB_USER,\n            DB_PASSWORD,\n            &#91;PDO::ATTR_ERRMODE =&gt; PDO::ERRMODE_EXCEPTION]\n        );\n    }\n    \n    <span class=\"hljs-keyword\">return<\/span> $pdo;\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-48\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='srclibsflash-php-file'>src\/libs\/flash.php file <a href=\"#srclibsflash-php-file\" class=\"anchor\" id=\"srclibsflash-php-file\" title=\"Anchor for src\/libs\/flash.php file\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-49\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> FLASH = <span class=\"hljs-string\">'FLASH_MESSAGES'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> FLASH_ERROR = <span class=\"hljs-string\">'error'<\/span>;\n<span class=\"hljs-keyword\">const<\/span> FLASH_WARNING = <span class=\"hljs-string\">'warning'<\/span>;\n<span class=\"hljs-keyword\">const<\/span> FLASH_INFO = <span class=\"hljs-string\">'info'<\/span>;\n<span class=\"hljs-keyword\">const<\/span> FLASH_SUCCESS = <span class=\"hljs-string\">'success'<\/span>;\n\n<span class=\"hljs-comment\">\/**\n* Create a flash message\n*\n* <span class=\"hljs-doctag\">@param<\/span> string $name\n* <span class=\"hljs-doctag\">@param<\/span> string $message\n* <span class=\"hljs-doctag\">@param<\/span> string $type\n* <span class=\"hljs-doctag\">@return<\/span> void\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">create_flash_message<\/span><span class=\"hljs-params\">(string $name, string $message, string $type)<\/span>: <span class=\"hljs-title\">void<\/span>\n<\/span>{\n    <span class=\"hljs-comment\">\/\/ remove existing message with the name<\/span>\n    <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-keyword\">isset<\/span>($_SESSION&#91;FLASH]&#91;$name])) {\n        <span class=\"hljs-keyword\">unset<\/span>($_SESSION&#91;FLASH]&#91;$name]);\n    }\n    <span class=\"hljs-comment\">\/\/ add the message to the session<\/span>\n    $_SESSION&#91;FLASH]&#91;$name] = &#91;<span class=\"hljs-string\">'message'<\/span> =&gt; $message, <span class=\"hljs-string\">'type'<\/span> =&gt; $type];\n}\n\n\n<span class=\"hljs-comment\">\/**\n* Format a flash message\n*\n* <span class=\"hljs-doctag\">@param<\/span> array $flash_message\n* <span class=\"hljs-doctag\">@return<\/span> string\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">format_flash_message<\/span><span class=\"hljs-params\">(array $flash_message)<\/span>: <span class=\"hljs-title\">string<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> sprintf(<span class=\"hljs-string\">'&lt;div class=\"alert alert-%s\"&gt;%s&lt;\/div&gt;'<\/span>,\n        $flash_message&#91;<span class=\"hljs-string\">'type'<\/span>],\n        $flash_message&#91;<span class=\"hljs-string\">'message'<\/span>]\n    );\n}\n\n<span class=\"hljs-comment\">\/**\n* Display a flash message\n*\n* <span class=\"hljs-doctag\">@param<\/span> string $name\n* <span class=\"hljs-doctag\">@return<\/span> void\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">display_flash_message<\/span><span class=\"hljs-params\">(string $name)<\/span>: <span class=\"hljs-title\">void<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-keyword\">isset<\/span>($_SESSION&#91;FLASH]&#91;$name])) {\n        <span class=\"hljs-keyword\">return<\/span>;\n    }\n\n    <span class=\"hljs-comment\">\/\/ get message from the session<\/span>\n    $flash_message = $_SESSION&#91;FLASH]&#91;$name];\n\n    <span class=\"hljs-comment\">\/\/ delete the flash message<\/span>\n    <span class=\"hljs-keyword\">unset<\/span>($_SESSION&#91;FLASH]&#91;$name]);\n\n    <span class=\"hljs-comment\">\/\/ display the flash message<\/span>\n    <span class=\"hljs-keyword\">echo<\/span> format_flash_message($flash_message);\n}\n\n<span class=\"hljs-comment\">\/**\n* Display all flash messages\n*\n* <span class=\"hljs-doctag\">@return<\/span> void\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">display_all_flash_messages<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">void<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-keyword\">isset<\/span>($_SESSION&#91;FLASH])) {\n        <span class=\"hljs-keyword\">return<\/span>;\n    }\n\n    <span class=\"hljs-comment\">\/\/ get flash messages<\/span>\n    $flash_messages = $_SESSION&#91;FLASH];\n\n    <span class=\"hljs-comment\">\/\/ remove all the flash messages<\/span>\n    <span class=\"hljs-keyword\">unset<\/span>($_SESSION&#91;FLASH]);\n\n    <span class=\"hljs-comment\">\/\/ show all flash messages<\/span>\n    <span class=\"hljs-keyword\">foreach<\/span> ($flash_messages <span class=\"hljs-keyword\">as<\/span> $flash_message) {\n        <span class=\"hljs-keyword\">echo<\/span> format_flash_message($flash_message);\n    }\n}\n\n<span class=\"hljs-comment\">\/**\n* Flash a message\n*\n* <span class=\"hljs-doctag\">@param<\/span> string $name\n* <span class=\"hljs-doctag\">@param<\/span> string $message\n* <span class=\"hljs-doctag\">@param<\/span> string $type (error, warning, info, success)\n* <span class=\"hljs-doctag\">@return<\/span> void\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">flash<\/span><span class=\"hljs-params\">(string $name = <span class=\"hljs-string\">''<\/span>, string $message = <span class=\"hljs-string\">''<\/span>, string $type = <span class=\"hljs-string\">''<\/span>)<\/span>: <span class=\"hljs-title\">void<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">if<\/span> ($name !== <span class=\"hljs-string\">''<\/span> &amp;&amp; $message !== <span class=\"hljs-string\">''<\/span> &amp;&amp; $type !== <span class=\"hljs-string\">''<\/span>) {\n        <span class=\"hljs-comment\">\/\/ create a flash message<\/span>\n        create_flash_message($name, $message, $type);\n    } <span class=\"hljs-keyword\">elseif<\/span> ($name !== <span class=\"hljs-string\">''<\/span> &amp;&amp; $message === <span class=\"hljs-string\">''<\/span> &amp;&amp; $type === <span class=\"hljs-string\">''<\/span>) {\n        <span class=\"hljs-comment\">\/\/ display a flash message<\/span>\n        display_flash_message($name);\n    } <span class=\"hljs-keyword\">elseif<\/span> ($name === <span class=\"hljs-string\">''<\/span> &amp;&amp; $message === <span class=\"hljs-string\">''<\/span> &amp;&amp; $type === <span class=\"hljs-string\">''<\/span>) {\n        <span class=\"hljs-comment\">\/\/ display all flash message<\/span>\n        display_all_flash_messages();\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-49\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='srcincheader-php'>src\/inc\/header.php <a href=\"#srcincheader-php\" class=\"anchor\" id=\"srcincheader-php\" title=\"Anchor for src\/inc\/header.php\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-50\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;!DOCTYPE html&gt;\n&lt;html lang=<span class=\"hljs-string\">\"en\"<\/span>&gt;\n&lt;head&gt;\n    &lt;meta charset=<span class=\"hljs-string\">\"UTF-8\"<\/span>&gt;\n    &lt;meta name=<span class=\"hljs-string\">\"viewport\"<\/span> content=<span class=\"hljs-string\">\"width=device-width, initial-scale=1.0\"<\/span>&gt;\n    &lt;link rel=<span class=\"hljs-string\">\"stylesheet\"<\/span> href=<span class=\"hljs-string\">\"https:\/\/phptutorial.net\/app\/css\/style.css\"<\/span>&gt;\n    &lt;title&gt;<span class=\"hljs-meta\">&lt;?<\/span>= $title ?? <span class=\"hljs-string\">'Home'<\/span> <span class=\"hljs-meta\">?&gt;<\/span>&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;main&gt;\n<span class=\"hljs-meta\">&lt;?php<\/span> flash() <span class=\"hljs-meta\">?&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-50\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='srcincfooter-php-file'>src\/inc\/footer.php file <a href=\"#srcincfooter-php-file\" class=\"anchor\" id=\"srcincfooter-php-file\" title=\"Anchor for src\/inc\/footer.php file\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-51\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;\/main&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-51\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='srclibshelpers-php'>src\/libs\/helpers.php <a href=\"#srclibshelpers-php\" class=\"anchor\" id=\"srclibshelpers-php\" title=\"Anchor for src\/libs\/helpers.php\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-52\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n<span class=\"hljs-comment\">\/**\n * Display a view\n *\n * <span class=\"hljs-doctag\">@param<\/span> string $filename\n * <span class=\"hljs-doctag\">@param<\/span> array $data\n * <span class=\"hljs-doctag\">@return<\/span> void\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">view<\/span><span class=\"hljs-params\">(string $filename, array $data = &#91;])<\/span>: <span class=\"hljs-title\">void<\/span>\n<\/span>{\n    <span class=\"hljs-comment\">\/\/ create variables from the associative array<\/span>\n    <span class=\"hljs-keyword\">foreach<\/span> ($data <span class=\"hljs-keyword\">as<\/span> $key =&gt; $value) {\n        $$key = $value;\n    }\n    <span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/inc\/'<\/span> . $filename . <span class=\"hljs-string\">'.php'<\/span>;\n}\n\n\n\n<span class=\"hljs-comment\">\/**\n * Return the error class if error is found in the array $errors\n *\n * <span class=\"hljs-doctag\">@param<\/span> array $errors\n * <span class=\"hljs-doctag\">@param<\/span> string $field\n * <span class=\"hljs-doctag\">@return<\/span> string\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">error_class<\/span><span class=\"hljs-params\">(array $errors, string $field)<\/span>: <span class=\"hljs-title\">string<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">isset<\/span>($errors&#91;$field]) ? <span class=\"hljs-string\">'error'<\/span> : <span class=\"hljs-string\">''<\/span>;\n}\n\n<span class=\"hljs-comment\">\/**\n * Return true if the request method is POST\n *\n * <span class=\"hljs-doctag\">@return<\/span> boolean\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_post_request<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> strtoupper($_SERVER&#91;<span class=\"hljs-string\">'REQUEST_METHOD'<\/span>]) === <span class=\"hljs-string\">'POST'<\/span>;\n}\n\n<span class=\"hljs-comment\">\/**\n * Return true if the request method is GET\n *\n * <span class=\"hljs-doctag\">@return<\/span> boolean\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_get_request<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> strtoupper($_SERVER&#91;<span class=\"hljs-string\">'REQUEST_METHOD'<\/span>]) === <span class=\"hljs-string\">'GET'<\/span>;\n}\n\n<span class=\"hljs-comment\">\/**\n * Redirect to another URL\n *\n * <span class=\"hljs-doctag\">@param<\/span> string $url\n * <span class=\"hljs-doctag\">@return<\/span> void\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">redirect_to<\/span><span class=\"hljs-params\">(string $url)<\/span>: <span class=\"hljs-title\">void<\/span>\n<\/span>{\n    header(<span class=\"hljs-string\">'Location:'<\/span> . $url);\n    <span class=\"hljs-keyword\">exit<\/span>;\n}\n\n<span class=\"hljs-comment\">\/**\n * Redirect to a URL with data stored in the items array\n * <span class=\"hljs-doctag\">@param<\/span> string $url\n * <span class=\"hljs-doctag\">@param<\/span> array $items\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">redirect_with<\/span><span class=\"hljs-params\">(string $url, array $items)<\/span>: <span class=\"hljs-title\">void<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">foreach<\/span> ($items <span class=\"hljs-keyword\">as<\/span> $key =&gt; $value) {\n        $_SESSION&#91;$key] = $value;\n    }\n\n    redirect_to($url);\n}\n\n<span class=\"hljs-comment\">\/**\n * Redirect to a URL with a flash message\n * <span class=\"hljs-doctag\">@param<\/span> string $url\n * <span class=\"hljs-doctag\">@param<\/span> string $message\n * <span class=\"hljs-doctag\">@param<\/span> string $type\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">redirect_with_message<\/span><span class=\"hljs-params\">(string $url, string $message, string $type = FLASH_SUCCESS)<\/span>\n<\/span>{\n    flash(<span class=\"hljs-string\">'flash_'<\/span> . uniqid(), $message, $type);\n    redirect_to($url);\n}\n\n<span class=\"hljs-comment\">\/**\n * Flash data specified by $keys from the $_SESSION\n * <span class=\"hljs-doctag\">@param<\/span> ...$keys\n * <span class=\"hljs-doctag\">@return<\/span> array\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">session_flash<\/span><span class=\"hljs-params\">(...$keys)<\/span>: <span class=\"hljs-title\">array<\/span>\n<\/span>{\n    $data = &#91;];\n    <span class=\"hljs-keyword\">foreach<\/span> ($keys <span class=\"hljs-keyword\">as<\/span> $key) {\n        <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-keyword\">isset<\/span>($_SESSION&#91;$key])) {\n            $data&#91;] = $_SESSION&#91;$key];\n            <span class=\"hljs-keyword\">unset<\/span>($_SESSION&#91;$key]);\n        } <span class=\"hljs-keyword\">else<\/span> {\n            $data&#91;] = &#91;];\n        }\n    }\n    <span class=\"hljs-keyword\">return<\/span> $data;\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-52\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='inclibssanitization-php'>inc\/libs\/sanitization.php <a href=\"#inclibssanitization-php\" class=\"anchor\" id=\"inclibssanitization-php\" title=\"Anchor for inc\/libs\/sanitization.php\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-53\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> FILTERS = &#91;\n    <span class=\"hljs-string\">'string'<\/span> =&gt; FILTER_SANITIZE_FULL_SPECIAL_CHARS,\n    <span class=\"hljs-string\">'string&#91;]'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'filter'<\/span> =&gt; FILTER_SANITIZE_FULL_SPECIAL_CHARS,\n        <span class=\"hljs-string\">'flags'<\/span> =&gt; FILTER_REQUIRE_ARRAY\n    ],\n    <span class=\"hljs-string\">'email'<\/span> =&gt; FILTER_SANITIZE_EMAIL,\n    <span class=\"hljs-string\">'int'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'filter'<\/span> =&gt; FILTER_SANITIZE_NUMBER_INT,\n        <span class=\"hljs-string\">'flags'<\/span> =&gt; FILTER_REQUIRE_SCALAR\n    ],\n    <span class=\"hljs-string\">'int&#91;]'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'filter'<\/span> =&gt; FILTER_SANITIZE_NUMBER_INT,\n        <span class=\"hljs-string\">'flags'<\/span> =&gt; FILTER_REQUIRE_ARRAY\n    ],\n    <span class=\"hljs-string\">'float'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'filter'<\/span> =&gt; FILTER_SANITIZE_NUMBER_FLOAT,\n        <span class=\"hljs-string\">'flags'<\/span> =&gt; FILTER_FLAG_ALLOW_FRACTION\n    ],\n    <span class=\"hljs-string\">'float&#91;]'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'filter'<\/span> =&gt; FILTER_SANITIZE_NUMBER_FLOAT,\n        <span class=\"hljs-string\">'flags'<\/span> =&gt; FILTER_REQUIRE_ARRAY\n    ],\n    <span class=\"hljs-string\">'url'<\/span> =&gt; FILTER_SANITIZE_URL,\n];\n\n<span class=\"hljs-comment\">\/**\n* Recursively trim strings in an array\n* <span class=\"hljs-doctag\">@param<\/span> array $items\n* <span class=\"hljs-doctag\">@return<\/span> array\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">array_trim<\/span><span class=\"hljs-params\">(array $items)<\/span>: <span class=\"hljs-title\">array<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> array_map(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">($item)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">if<\/span> (is_string($item)) {\n            <span class=\"hljs-keyword\">return<\/span> trim($item);\n        } <span class=\"hljs-keyword\">elseif<\/span> (is_array($item)) {\n            <span class=\"hljs-keyword\">return<\/span> array_trim($item);\n        } <span class=\"hljs-keyword\">else<\/span>\n            <span class=\"hljs-keyword\">return<\/span> $item;\n    }, $items);\n}\n\n<span class=\"hljs-comment\">\/**\n* Sanitize the inputs based on the rules an optionally trim the string\n* <span class=\"hljs-doctag\">@param<\/span> array $inputs\n* <span class=\"hljs-doctag\">@param<\/span> array $fields\n* <span class=\"hljs-doctag\">@param<\/span> int $default_filter FILTER_SANITIZE_FULL_SPECIAL_CHARS\n* <span class=\"hljs-doctag\">@param<\/span> array $filters FILTERS\n* <span class=\"hljs-doctag\">@param<\/span> bool $trim\n* <span class=\"hljs-doctag\">@return<\/span> array\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">sanitize<\/span><span class=\"hljs-params\">(array $inputs, array $fields = &#91;], int $default_filter = FILTER_SANITIZE_FULL_SPECIAL_CHARS, array $filters = FILTERS, bool $trim = true)<\/span>: <span class=\"hljs-title\">array<\/span>\n<\/span>{\n\n    <span class=\"hljs-comment\">\/\/ var_dump($fields);<\/span>\n\n    <span class=\"hljs-keyword\">if<\/span> ($fields) {\n        <span class=\"hljs-comment\">\/\/ remove trailiing and leading spaces  from fields<\/span>\n        $fields = array_map(<span class=\"hljs-string\">'trim'<\/span>, $fields);\n        <span class=\"hljs-comment\">\/\/<\/span>\n        $options = array_map(fn($field) =&gt; $filters&#91;$field], $fields);\n        $data = filter_var_array($inputs, $options);\n    } <span class=\"hljs-keyword\">else<\/span> {\n        $data = filter_var_array($inputs, $default_filter);\n    }\n\n    <span class=\"hljs-keyword\">return<\/span> $trim ? array_trim($data) : $data;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-53\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='srclibsvalidation-php'>src\/libs\/validation.php <a href=\"#srclibsvalidation-php\" class=\"anchor\" id=\"srclibsvalidation-php\" title=\"Anchor for src\/libs\/validation.php\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-54\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n\n<span class=\"hljs-keyword\">const<\/span> DEFAULT_VALIDATION_ERRORS = &#91;\n    <span class=\"hljs-string\">'required'<\/span> =&gt; <span class=\"hljs-string\">'The %s is required'<\/span>,\n    <span class=\"hljs-string\">'email'<\/span> =&gt; <span class=\"hljs-string\">'The %s is not a valid email address'<\/span>,\n    <span class=\"hljs-string\">'min'<\/span> =&gt; <span class=\"hljs-string\">'The %s must have at least %s characters'<\/span>,\n    <span class=\"hljs-string\">'max'<\/span> =&gt; <span class=\"hljs-string\">'The %s must have at most %s characters'<\/span>,\n    <span class=\"hljs-string\">'between'<\/span> =&gt; <span class=\"hljs-string\">'The %s must have between %d and %d characters'<\/span>,\n    <span class=\"hljs-string\">'same'<\/span> =&gt; <span class=\"hljs-string\">'The %s must match with %s'<\/span>,\n    <span class=\"hljs-string\">'alphanumeric'<\/span> =&gt; <span class=\"hljs-string\">'The %s should have only letters and numbers'<\/span>,\n    <span class=\"hljs-string\">'secure'<\/span> =&gt; <span class=\"hljs-string\">'The %s must have between 8 and 64 characters and contain at least one number, one upper case letter, one lower case letter and one special character'<\/span>,\n    <span class=\"hljs-string\">'unique'<\/span> =&gt; <span class=\"hljs-string\">'The %s already exists'<\/span>,\n];\n\n\n<span class=\"hljs-comment\">\/**\n* Validate\n* <span class=\"hljs-doctag\">@param<\/span> array $data\n* <span class=\"hljs-doctag\">@param<\/span> array $fields\n* <span class=\"hljs-doctag\">@param<\/span> array $messages\n* <span class=\"hljs-doctag\">@return<\/span> array\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">validate<\/span><span class=\"hljs-params\">(array $data, array $fields, array $messages = &#91;])<\/span>: <span class=\"hljs-title\">array<\/span>\n<\/span>{\n    <span class=\"hljs-comment\">\/\/ Split the array by a separator, trim each element<\/span>\n    <span class=\"hljs-comment\">\/\/ and return the array<\/span>\n    $split = fn($str, $separator) =&gt; array_map(<span class=\"hljs-string\">'trim'<\/span>, explode($separator, $str));\n\n    <span class=\"hljs-comment\">\/\/ get the message rules<\/span>\n    $rule_messages = array_filter($messages, fn($message) =&gt; is_string($message));\n    <span class=\"hljs-comment\">\/\/ overwrite the default message<\/span>\n    $validation_errors = array_merge(DEFAULT_VALIDATION_ERRORS, $rule_messages);\n\n    $errors = &#91;];\n\n    <span class=\"hljs-keyword\">foreach<\/span> ($fields <span class=\"hljs-keyword\">as<\/span> $field =&gt; $option) {\n\n        $rules = $split($option, <span class=\"hljs-string\">'|'<\/span>);\n\n        <span class=\"hljs-keyword\">foreach<\/span> ($rules <span class=\"hljs-keyword\">as<\/span> $rule) {\n            <span class=\"hljs-comment\">\/\/ get rule name params<\/span>\n            $params = &#91;];\n            <span class=\"hljs-comment\">\/\/ if the rule has parameters e.g., min: 1<\/span>\n            <span class=\"hljs-keyword\">if<\/span> (strpos($rule, <span class=\"hljs-string\">':'<\/span>)) {\n                &#91;$rule_name, $param_str] = $split($rule, <span class=\"hljs-string\">':'<\/span>);\n                $params = $split($param_str, <span class=\"hljs-string\">','<\/span>);\n            } <span class=\"hljs-keyword\">else<\/span> {\n                $rule_name = trim($rule);\n            }\n            <span class=\"hljs-comment\">\/\/ by convention, the callback should be is_&lt;rule&gt; e.g.,is_required<\/span>\n            $fn = <span class=\"hljs-string\">'is_'<\/span> . $rule_name;\n\n            <span class=\"hljs-keyword\">if<\/span> (is_callable($fn)) {\n                $pass = $fn($data, $field, ...$params);\n                <span class=\"hljs-keyword\">if<\/span> (!$pass) {\n                    <span class=\"hljs-comment\">\/\/ get the error message for a specific field and rule if exists<\/span>\n                    <span class=\"hljs-comment\">\/\/ otherwise get the error message from the $validation_errors<\/span>\n                    $errors&#91;$field] = sprintf(\n                        $messages&#91;$field]&#91;$rule_name] ?? $validation_errors&#91;$rule_name],\n                        $field,\n                        ...$params\n                    );\n                }\n            }\n        }\n    }\n\n    <span class=\"hljs-keyword\">return<\/span> $errors;\n}\n\n<span class=\"hljs-comment\">\/**\n* Return true if a string is not empty\n* <span class=\"hljs-doctag\">@param<\/span> array $data\n* <span class=\"hljs-doctag\">@param<\/span> string $field\n* <span class=\"hljs-doctag\">@return<\/span> bool\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_required<\/span><span class=\"hljs-params\">(array $data, string $field)<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">isset<\/span>($data&#91;$field]) &amp;&amp; trim($data&#91;$field]) !== <span class=\"hljs-string\">''<\/span>;\n}\n\n<span class=\"hljs-comment\">\/**\n* Return true if the value is a valid email\n* <span class=\"hljs-doctag\">@param<\/span> array $data\n* <span class=\"hljs-doctag\">@param<\/span> string $field\n* <span class=\"hljs-doctag\">@return<\/span> bool\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_email<\/span><span class=\"hljs-params\">(array $data, string $field)<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-keyword\">empty<\/span>($data&#91;$field])) {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\n    }\n\n    <span class=\"hljs-keyword\">return<\/span> filter_var($data&#91;$field], FILTER_VALIDATE_EMAIL);\n}\n\n<span class=\"hljs-comment\">\/**\n* Return true if a string has at least min length\n* <span class=\"hljs-doctag\">@param<\/span> array $data\n* <span class=\"hljs-doctag\">@param<\/span> string $field\n* <span class=\"hljs-doctag\">@param<\/span> int $min\n* <span class=\"hljs-doctag\">@return<\/span> bool\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_min<\/span><span class=\"hljs-params\">(array $data, string $field, int $min)<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-keyword\">isset<\/span>($data&#91;$field])) {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\n    }\n\n    <span class=\"hljs-keyword\">return<\/span> mb_strlen($data&#91;$field]) &gt;= $min;\n}\n\n<span class=\"hljs-comment\">\/**\n* Return true if a string cannot exceed max length\n* <span class=\"hljs-doctag\">@param<\/span> array $data\n* <span class=\"hljs-doctag\">@param<\/span> string $field\n* <span class=\"hljs-doctag\">@param<\/span> int $max\n* <span class=\"hljs-doctag\">@return<\/span> bool\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_max<\/span><span class=\"hljs-params\">(array $data, string $field, int $max)<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-keyword\">isset<\/span>($data&#91;$field])) {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\n    }\n\n    <span class=\"hljs-keyword\">return<\/span> mb_strlen($data&#91;$field]) &lt;= $max;\n}\n\n<span class=\"hljs-comment\">\/**\n* <span class=\"hljs-doctag\">@param<\/span> array $data\n* <span class=\"hljs-doctag\">@param<\/span> string $field\n* <span class=\"hljs-doctag\">@param<\/span> int $min\n* <span class=\"hljs-doctag\">@param<\/span> int $max\n* <span class=\"hljs-doctag\">@return<\/span> bool\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_between<\/span><span class=\"hljs-params\">(array $data, string $field, int $min, int $max)<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-keyword\">isset<\/span>($data&#91;$field])) {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\n    }\n\n    $len = mb_strlen($data&#91;$field]);\n    <span class=\"hljs-keyword\">return<\/span> $len &gt;= $min &amp;&amp; $len &lt;= $max;\n}\n\n<span class=\"hljs-comment\">\/**\n* Return true if a string equals the other\n* <span class=\"hljs-doctag\">@param<\/span> array $data\n* <span class=\"hljs-doctag\">@param<\/span> string $field\n* <span class=\"hljs-doctag\">@param<\/span> string $other\n* <span class=\"hljs-doctag\">@return<\/span> bool\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_same<\/span><span class=\"hljs-params\">(array $data, string $field, string $other)<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-keyword\">isset<\/span>($data&#91;$field], $data&#91;$other])) {\n        <span class=\"hljs-keyword\">return<\/span> $data&#91;$field] === $data&#91;$other];\n    }\n\n    <span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-keyword\">isset<\/span>($data&#91;$field]) &amp;&amp; !<span class=\"hljs-keyword\">isset<\/span>($data&#91;$other])) {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\n    }\n\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">false<\/span>;\n}\n\n<span class=\"hljs-comment\">\/**\n* Return true if a string is alphanumeric\n* <span class=\"hljs-doctag\">@param<\/span> array $data\n* <span class=\"hljs-doctag\">@param<\/span> string $field\n* <span class=\"hljs-doctag\">@return<\/span> bool\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_alphanumeric<\/span><span class=\"hljs-params\">(array $data, string $field)<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-keyword\">isset<\/span>($data&#91;$field])) {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\n    }\n\n    <span class=\"hljs-keyword\">return<\/span> ctype_alnum($data&#91;$field]);\n}\n\n<span class=\"hljs-comment\">\/**\n* Return true if a password is secure\n* <span class=\"hljs-doctag\">@param<\/span> array $data\n* <span class=\"hljs-doctag\">@param<\/span> string $field\n* <span class=\"hljs-doctag\">@return<\/span> bool\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_secure<\/span><span class=\"hljs-params\">(array $data, string $field)<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-keyword\">isset<\/span>($data&#91;$field])) {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">false<\/span>;\n    }\n\n    $pattern = <span class=\"hljs-string\">\"#.*^(?=.{8,64})(?=.*&#91;a-z])(?=.*&#91;A-Z])(?=.*&#91;0-9])(?=.*\\W).*$#\"<\/span>;\n    <span class=\"hljs-keyword\">return<\/span> preg_match($pattern, $data&#91;$field]);\n}\n\n<span class=\"hljs-comment\">\/**\n* Return true if the $value is unique in the column of a table\n* <span class=\"hljs-doctag\">@param<\/span> array $data\n* <span class=\"hljs-doctag\">@param<\/span> string $field\n* <span class=\"hljs-doctag\">@param<\/span> string $table\n* <span class=\"hljs-doctag\">@param<\/span> string $column\n* <span class=\"hljs-doctag\">@return<\/span> bool\n*\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">is_unique<\/span><span class=\"hljs-params\">(array $data, string $field, string $table, string $column)<\/span>: <span class=\"hljs-title\">bool<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-keyword\">isset<\/span>($data&#91;$field])) {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\n    }\n\n    $sql = <span class=\"hljs-string\">\"SELECT $column FROM $table WHERE $column = :value\"<\/span>;\n\n    $stmt = db()-&gt;prepare($sql);\n    $stmt-&gt;bindValue(<span class=\"hljs-string\">\":value\"<\/span>, $data&#91;$field]);\n\n    $stmt-&gt;execute();\n\n    <span class=\"hljs-keyword\">return<\/span> $stmt-&gt;fetchColumn() === <span class=\"hljs-keyword\">false<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-54\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='srclibsfilter-php'>src\/libs\/filter.php <a href=\"#srclibsfilter-php\" class=\"anchor\" id=\"srclibsfilter-php\" title=\"Anchor for src\/libs\/filter.php\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-55\" 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>\n\n<span class=\"hljs-comment\">\/**\n * Sanitize and validate data\n * <span class=\"hljs-doctag\">@param<\/span> array $data\n * <span class=\"hljs-doctag\">@param<\/span> array $fields\n * <span class=\"hljs-doctag\">@param<\/span> array $messages\n * <span class=\"hljs-doctag\">@return<\/span> array\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">filter<\/span><span class=\"hljs-params\">(array $data, array $fields, array $messages = &#91;])<\/span>: <span class=\"hljs-title\">array<\/span>\n<\/span>{\n    $sanitization = &#91;];\n    $validation = &#91;];\n\n    <span class=\"hljs-comment\">\/\/ extract sanitization &amp; validation rules<\/span>\n    <span class=\"hljs-keyword\">foreach<\/span> ($fields <span class=\"hljs-keyword\">as<\/span> $field =&gt; $rules) {\n        <span class=\"hljs-keyword\">if<\/span> (strpos($rules, <span class=\"hljs-string\">'|'<\/span>)) {\n            &#91;$sanitization&#91;$field], $validation&#91;$field]] = explode(<span class=\"hljs-string\">'|'<\/span>, $rules, <span class=\"hljs-number\">2<\/span>);\n        } <span class=\"hljs-keyword\">else<\/span> {\n            $sanitization&#91;$field] = $rules;\n        }\n    }\n\n    \n\n    $inputs = sanitize($data, $sanitization);\n    $errors = validate($inputs, $validation, $messages);\n\n    <span class=\"hljs-keyword\">return<\/span> &#91;$inputs, $errors];\n}<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-55\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='srcbootstrap-php'> src\/bootstrap.php <a href=\"#srcbootstrap-php\" class=\"anchor\" id=\"srcbootstrap-php\" title=\"Anchor for  src\/bootstrap.php\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-56\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\nsession_start();\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/config\/database.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/helpers.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/flash.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/sanitization.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/validation.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/filter.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/libs\/connection.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'..\/inc\/auth.php'<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-56\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='publicregister-php'>public\/register.php <a href=\"#publicregister-php\" class=\"anchor\" id=\"publicregister-php\" title=\"Anchor for public\/register.php\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-57\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/bootstrap.php'<\/span>;\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/register.php'<\/span>;\n<span class=\"hljs-meta\">?&gt;<\/span>\n\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\">'Register'<\/span>]) <span class=\"hljs-meta\">?&gt;<\/span>\n\n&lt;form action=<span class=\"hljs-string\">\"register.php\"<\/span> method=<span class=\"hljs-string\">\"post\"<\/span>&gt;\n    &lt;h1&gt;Sign Up&lt;\/h1&gt;\n\n    &lt;div&gt;\n        &lt;label <span class=\"hljs-keyword\">for<\/span>=<span class=\"hljs-string\">\"username\"<\/span>&gt;Username:&lt;\/label&gt;\n        &lt;input type=<span class=\"hljs-string\">\"text\"<\/span> name=<span class=\"hljs-string\">\"username\"<\/span> id=<span class=\"hljs-string\">\"username\"<\/span> value=<span class=\"hljs-string\">\"&lt;?= $inputs&#91;'username'] ?? '' ?&gt;\"<\/span>\n               <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span>=\"&lt;?= <span class=\"hljs-title\">error_class<\/span>($<span class=\"hljs-title\">errors<\/span>, '<span class=\"hljs-title\">username<\/span>') ?&gt;\"&gt;\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;\n    &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\n\n    &lt;<span class=\"hljs-title\">div<\/span>&gt;\n        &lt;<span class=\"hljs-title\">label<\/span> <span class=\"hljs-title\">for<\/span>=\"<span class=\"hljs-title\">email<\/span>\"&gt;<span class=\"hljs-title\">Email<\/span>:&lt;\/<span class=\"hljs-title\">label<\/span>&gt;\n        &lt;<span class=\"hljs-title\">input<\/span> <span class=\"hljs-title\">type<\/span>=\"<span class=\"hljs-title\">email<\/span>\" <span class=\"hljs-title\">name<\/span>=\"<span class=\"hljs-title\">email<\/span>\" <span class=\"hljs-title\">id<\/span>=\"<span class=\"hljs-title\">email<\/span>\" <span class=\"hljs-title\">value<\/span>=\"&lt;?= $<span class=\"hljs-title\">inputs<\/span>&#91;'<span class=\"hljs-title\">email<\/span>'] ?? '' ?&gt;\"\n               <span class=\"hljs-title\">class<\/span>=\"&lt;?= <span class=\"hljs-title\">error_class<\/span>($<span class=\"hljs-title\">errors<\/span>, '<span class=\"hljs-title\">email<\/span>') ?&gt;\"&gt;\n        &lt;<span class=\"hljs-title\">small<\/span>&gt;&lt;?= $<span class=\"hljs-title\">errors<\/span>&#91;'<span class=\"hljs-title\">email<\/span>'] ?? '' ?&gt;&lt;\/<span class=\"hljs-title\">small<\/span>&gt;\n    &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\n\n    &lt;<span class=\"hljs-title\">div<\/span>&gt;\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;\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>\" <span class=\"hljs-title\">value<\/span>=\"&lt;?= $<span class=\"hljs-title\">inputs<\/span>&#91;'<span class=\"hljs-title\">password<\/span>'] ?? '' ?&gt;\"\n               <span class=\"hljs-title\">class<\/span>=\"&lt;?= <span class=\"hljs-title\">error_class<\/span>($<span class=\"hljs-title\">errors<\/span>, '<span class=\"hljs-title\">password<\/span>') ?&gt;\"&gt;\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;\n    &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\n\n    &lt;<span class=\"hljs-title\">div<\/span>&gt;\n        &lt;<span class=\"hljs-title\">label<\/span> <span class=\"hljs-title\">for<\/span>=\"<span class=\"hljs-title\">password2<\/span>\"&gt;<span class=\"hljs-title\">Password<\/span> <span class=\"hljs-title\">Again<\/span>:&lt;\/<span class=\"hljs-title\">label<\/span>&gt;\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\">password2<\/span>\" <span class=\"hljs-title\">id<\/span>=\"<span class=\"hljs-title\">password2<\/span>\" <span class=\"hljs-title\">value<\/span>=\"&lt;?= $<span class=\"hljs-title\">inputs<\/span>&#91;'<span class=\"hljs-title\">password2<\/span>'] ?? '' ?&gt;\"\n               <span class=\"hljs-title\">class<\/span>=\"&lt;?= <span class=\"hljs-title\">error_class<\/span>($<span class=\"hljs-title\">errors<\/span>, '<span class=\"hljs-title\">password2<\/span>') ?&gt;\"&gt;\n        &lt;<span class=\"hljs-title\">small<\/span>&gt;&lt;?= $<span class=\"hljs-title\">errors<\/span>&#91;'<span class=\"hljs-title\">password2<\/span>'] ?? '' ?&gt;&lt;\/<span class=\"hljs-title\">small<\/span>&gt;\n    &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\n\n    &lt;<span class=\"hljs-title\">div<\/span>&gt;\n        &lt;<span class=\"hljs-title\">label<\/span> <span class=\"hljs-title\">for<\/span>=\"<span class=\"hljs-title\">agree<\/span>\"&gt;\n            &lt;<span class=\"hljs-title\">input<\/span> <span class=\"hljs-title\">type<\/span>=\"<span class=\"hljs-title\">checkbox<\/span>\" <span class=\"hljs-title\">name<\/span>=\"<span class=\"hljs-title\">agree<\/span>\" <span class=\"hljs-title\">id<\/span>=\"<span class=\"hljs-title\">agree<\/span>\" <span class=\"hljs-title\">value<\/span>=\"<span class=\"hljs-title\">checked<\/span>\" &lt;?= $<span class=\"hljs-title\">inputs<\/span>&#91;'<span class=\"hljs-title\">agree<\/span>'] ?? '' ?&gt; \/&gt; <span class=\"hljs-title\">I<\/span>\n            <span class=\"hljs-title\">agree<\/span>\n            <span class=\"hljs-title\">with<\/span> <span class=\"hljs-title\">the<\/span>\n            &lt;<span class=\"hljs-title\">a<\/span> <span class=\"hljs-title\">href<\/span>=\"#\" <span class=\"hljs-title\">title<\/span>=\"<span class=\"hljs-title\">term<\/span> <span class=\"hljs-title\">of<\/span> <span class=\"hljs-title\">services<\/span>\"&gt;<span class=\"hljs-title\">term<\/span> <span class=\"hljs-title\">of<\/span> <span class=\"hljs-title\">services<\/span>&lt;\/<span class=\"hljs-title\">a<\/span>&gt;\n        &lt;\/<span class=\"hljs-title\">label<\/span>&gt;\n        &lt;<span class=\"hljs-title\">small<\/span>&gt;&lt;?= $<span class=\"hljs-title\">errors<\/span>&#91;'<span class=\"hljs-title\">agree<\/span>'] ?? '' ?&gt;&lt;\/<span class=\"hljs-title\">small<\/span>&gt;\n    &lt;\/<span class=\"hljs-title\">div<\/span>&gt;\n\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\">Register<\/span>&lt;\/<span class=\"hljs-title\">button<\/span>&gt;\n\n    &lt;<span class=\"hljs-title\">footer<\/span>&gt;<span class=\"hljs-title\">Already<\/span> <span class=\"hljs-title\">a<\/span> <span class=\"hljs-title\">member<\/span>? &lt;<span class=\"hljs-title\">a<\/span> <span class=\"hljs-title\">href<\/span>=\"<span class=\"hljs-title\">login<\/span>.<span class=\"hljs-title\">php<\/span>\"&gt;<span class=\"hljs-title\">Login<\/span> <span class=\"hljs-title\">here<\/span>&lt;\/<span class=\"hljs-title\">a<\/span>&gt;&lt;\/<span class=\"hljs-title\">footer<\/span>&gt;\n\n&lt;\/<span class=\"hljs-title\">form<\/span>&gt;\n\n&lt;?<span class=\"hljs-title\">php<\/span> <span class=\"hljs-title\">view<\/span>('<span class=\"hljs-title\">footer<\/span>') ?&gt;\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-57\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='srcregister-php'>src\/register.php <a href=\"#srcregister-php\" class=\"anchor\" id=\"srcregister-php\" title=\"Anchor for src\/register.php\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-58\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n$errors = &#91;];\n$inputs = &#91;];\n\n<span class=\"hljs-keyword\">if<\/span> (is_post_request()) {\n\n    $fields = &#91;\n        <span class=\"hljs-string\">'username'<\/span> =&gt; <span class=\"hljs-string\">'string | required | alphanumeric | between: 3, 25 | unique: users, username'<\/span>,\n        <span class=\"hljs-string\">'email'<\/span> =&gt; <span class=\"hljs-string\">'email | required | email | unique: users, email'<\/span>,\n        <span class=\"hljs-string\">'password'<\/span> =&gt; <span class=\"hljs-string\">'string | required | secure'<\/span>,\n        <span class=\"hljs-string\">'password2'<\/span> =&gt; <span class=\"hljs-string\">'string | required | same: password'<\/span>,\n        <span class=\"hljs-string\">'agree'<\/span> =&gt; <span class=\"hljs-string\">'string | required'<\/span>\n    ];\n\n    <span class=\"hljs-comment\">\/\/ custom messages<\/span>\n    $messages = &#91;\n        <span class=\"hljs-string\">'password2'<\/span> =&gt; &#91;\n            <span class=\"hljs-string\">'required'<\/span> =&gt; <span class=\"hljs-string\">'Please enter the password again'<\/span>,\n            <span class=\"hljs-string\">'same'<\/span> =&gt; <span class=\"hljs-string\">'The password does not match'<\/span>\n        ],\n        <span class=\"hljs-string\">'agree'<\/span> =&gt; &#91;\n            <span class=\"hljs-string\">'required'<\/span> =&gt; <span class=\"hljs-string\">'You need to agree to the term of services to register'<\/span>\n        ]\n    ];\n\n    &#91;$inputs, $errors] = filter($_POST, $fields, $messages);\n\n    <span class=\"hljs-keyword\">if<\/span> ($errors) {\n        redirect_with(<span class=\"hljs-string\">'register.php'<\/span>, &#91;\n            <span class=\"hljs-string\">'inputs'<\/span> =&gt; $inputs,\n            <span class=\"hljs-string\">'errors'<\/span> =&gt; $errors\n        ]);\n    }\n\n    <span class=\"hljs-keyword\">if<\/span> (register_user($inputs&#91;<span class=\"hljs-string\">'email'<\/span>], $inputs&#91;<span class=\"hljs-string\">'username'<\/span>], $inputs&#91;<span class=\"hljs-string\">'password'<\/span>])) {\n        redirect_with_message(\n            <span class=\"hljs-string\">'login.php'<\/span>,\n            <span class=\"hljs-string\">'Your account has been created successfully. Please login here.'<\/span>\n        );\n\n    }\n\n} <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (is_get_request()) {\n    &#91;$inputs, $errors] = session_flash(<span class=\"hljs-string\">'inputs'<\/span>, <span class=\"hljs-string\">'errors'<\/span>);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-58\"><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>\n\n\n<h3 class=\"wp-block-heading\" id='publiclogin-php'>public\/login.php <a href=\"#publiclogin-php\" class=\"anchor\" id=\"publiclogin-php\" title=\"Anchor for public\/login.php\">#<\/a><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-59\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\n<span class=\"hljs-keyword\">require<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/..\/src\/bootstrap.php'<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-59\"><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>\n\n\n<p>The <code>login.php<\/code> will be blank. And you&#8217;ll learn how to <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-login\/\">create the login form in the next tutorial<\/a>.<\/p>\n\n\n\n<p><a href=\"https:\/\/phptutorial.net\/wp-content\/uploads\/2025\/04\/auth.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Download the Registration Form Project Source Code<\/a><\/p>\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=\"2719\"\n\t\t\t\tdata-post-url=\"https:\/\/www.phptutorial.net\/php-tutorial\/php-registration-form\/\"\n\t\t\t\tdata-post-title=\"PHP Registration Form\"\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=\"2719\"\n\t\t\t\tdata-post-url=\"https:\/\/www.phptutorial.net\/php-tutorial\/php-registration-form\/\"\n\t\t\t\tdata-post-title=\"PHP Registration Form\"\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>In this tutorial, you&#8217;ll learn how to create a PHP registration form from scratch.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":15,"menu_order":102,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2719","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages\/2719","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=2719"}],"version-history":[{"count":5,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages\/2719\/revisions"}],"predecessor-version":[{"id":3341,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages\/2719\/revisions\/3341"}],"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=2719"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}