<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Assia Ettalibi</title>
    <description>The latest articles on DEV Community by Assia Ettalibi (@ettalibi02assia).</description>
    <link>https://dev.to/ettalibi02assia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1414638%2Fd157fdd5-c862-4e6a-9a27-f806205d24ae.jpg</url>
      <title>DEV Community: Assia Ettalibi</title>
      <link>https://dev.to/ettalibi02assia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ettalibi02assia"/>
    <language>en</language>
    <item>
      <title>Building a Secured User Authentication System with PHP, MySQL, PDO and hashed password</title>
      <dc:creator>Assia Ettalibi</dc:creator>
      <pubDate>Tue, 14 May 2024 16:03:38 +0000</pubDate>
      <link>https://dev.to/ettalibi02assia/building-a-secured-user-authentication-system-with-php-mysql-pdo-and-hashed-password-4mpj</link>
      <guid>https://dev.to/ettalibi02assia/building-a-secured-user-authentication-system-with-php-mysql-pdo-and-hashed-password-4mpj</guid>
      <description>&lt;p&gt;&lt;strong&gt;Tired of Boring and insecured Logins&lt;/strong&gt;? Let's ditch the basic sign-up and sign-in systems and build a secure, engaging application with a personalized dashboard using PHP! This tutorial will guide you through creating a user management system with a focus on security best practices and user experience.&lt;/p&gt;

&lt;p&gt;What You'll Learn:&lt;br&gt;
How to handle user registration and login.&lt;br&gt;
Securely store passwords using bcrypt hashing.&lt;br&gt;
Implement a basic routing system.&lt;br&gt;
Leverage a service container to manage dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of PHP, HTML forms, and SQL&lt;/li&gt;
&lt;li&gt;PHP (version 7.4 or higher) installed on your local machine&lt;/li&gt;
&lt;li&gt;A web server (e.g., Apache, Nginx)&lt;/li&gt;
&lt;li&gt;A database server (e.g., MySQL)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;1. Project Setup:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Begin by creating a new project directory and setting up the basic file structure:&lt;/p&gt;

&lt;p&gt;└── 📁App&lt;br&gt;
    └── 📁Config : config.php , container.php , Database.php &lt;br&gt;
    └── 📁Controller : AuthController.php , &lt;br&gt;
                       DashboardController.php&lt;br&gt;
    └── 📁Core : app.php&lt;br&gt;
    └── 📁Helper : Autholoader.php , validator.php&lt;br&gt;
    └── 📁Model : userModel.php&lt;br&gt;
    └── 📁Routes : api.php , Router.php&lt;br&gt;
    └── 📁services : AuthService.php , container.php&lt;br&gt;
    └── 📁View&lt;br&gt;
        └── 📁Dashboard : DashboardView.php&lt;br&gt;
        └── 📁Login : Mainview.php , SignInView.php , &lt;br&gt;
                      SignUpView.php&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;warning ! : in this tutorial we gonna see the most important files in our project &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;2. Database Configuration (config/config.php):&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a config.php file to store your database credentials and other configuration settings:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8q94a6r27evhuasifta0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8q94a6r27evhuasifta0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;3. Database Interaction (model/UserModel.php):&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8scbti1fjk3zvk5cto8a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8scbti1fjk3zvk5cto8a.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code defines a class UserModel within the namespace App\Model. The class is designed to interact with a database to perform operations related to user management, specifically creating and validating users. Here's a breakdown of the principal components and functionalities:&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Namespace and Imports:&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;namespace App\Model;&lt;/code&gt; :&lt;br&gt;
 Declares that the UserModel class is part of the App\Model namespace.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;use App\Config\DataBase;&lt;/code&gt;:&lt;br&gt;
 Imports the DataBase class from the App\Config namespace, which presumably handles database connections.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;use PDOException;&lt;/code&gt;: Imports the PDOException class, which is used to catch exceptions thrown by PDO operations.&lt;br&gt;
&lt;u&gt;Class Definition :&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;class &lt;code&gt;UserModel:&lt;/code&gt; Defines the UserModel class, which encapsulates methods for interacting with the database regarding user data.&lt;br&gt;
&lt;u&gt;Constructor and Destructor :&lt;/u&gt; &lt;/p&gt;

&lt;p&gt;The constructor (&lt;code&gt;__construct&lt;/code&gt;) accepts an instance of DataBase and connects to the database using &lt;code&gt;$this-&amp;gt;db::connect();&lt;/code&gt;.&lt;br&gt;
The destructor (&lt;code&gt;__destruct&lt;/code&gt;) unsets the &lt;code&gt;$db&lt;/code&gt; property, effectively closing the database connection when the object is destroyed.&lt;br&gt;
&lt;u&gt;Public Methods : &lt;/u&gt;&lt;br&gt;
&lt;code&gt;create($data)&lt;/code&gt; : &lt;br&gt;
This method attempts to insert a new user into the users table with the provided data ($data). It uses prepared statements to prevent SQL injection.&lt;/p&gt;

&lt;p&gt;It checks for a duplicate entry error (code 23000) and returns an error message if the email already exists in the database.&lt;br&gt;
On success, it returns an array indicating success and the ID of the newly inserted user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78ohh4oa6idq8jiy4qlb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78ohh4oa6idq8jiy4qlb.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;validateUser($data)&lt;/code&gt; (it's inside the class also ):&lt;br&gt;
This method queries the database to find a user with the provided email address.&lt;br&gt;
It uses a prepared statement to safely query the database.&lt;br&gt;
If a user is found, it returns an array indicating success and the user's data.&lt;br&gt;
If no user is found, it returns an array indicating failure.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Error Handling:&lt;/u&gt;&lt;br&gt;
Both methods use a try-catch block to catch PDOException exceptions, which are thrown by PDO when there's an error executing a database operation.&lt;br&gt;
In the create method, if a PDOException is caught and its code indicates a duplicate entry error, it returns an error message indicating that the email already exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;4. Routing (routes/api.php):&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiy9jawr1fle93dksakiu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiy9jawr1fle93dksakiu.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This code defines routes for our application, connecting URLs to specific controller actions.&lt;br&gt;
It uses a Router class to define how different HTTP requests (GET and POST) to specific URLs are handled.&lt;br&gt;
Each route maps a URL to a controller and a method within that controller. For example, a GET request to /login will execute the showLoginForm method of the AuthController.&lt;br&gt;
This allows for organized and efficient handling of requests, directing them to the appropriate code based on the URL and HTTP method.&lt;br&gt;
This is a common way to manage routing in MVC applications, ensuring clear separation between URL handling and application logic.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;what is a Router ?? &lt;br&gt;
: &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Router: The MVC Traffic Cop&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the MVC (Model-View-Controller) architectural pattern, the router acts as a traffic cop, directing incoming requests to the correct controller action. Think of it as the "switchboard" of your application.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Definition:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
The router analyzes the URL of a request and determines which controller and action should handle it. It then passes the request to that controller, allowing the MVC flow to continue.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Importance:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Organizes Request Handling: Without a router, it would be chaotic to handle different types of requests. The router ensures each request goes to the right place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Maintainable Code:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
It keeps the code clean and organized by separating URL mapping from application logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Flexibility and Scalability:&lt;/em&gt;&lt;/strong&gt; &lt;br&gt;
Routers allow for easy addition of new features and functionalities without major restructuring.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;SEO-Friendliness: Routers can create clean, descriptive URLs that are beneficial for Search Engine Optimization *&lt;/em&gt;(SEO).&lt;br&gt;
 this is the endspoint of the router : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu28nw1ubk6jie3yfemh5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu28nw1ubk6jie3yfemh5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;5. Dependency Management (Container.php):&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;By using a Dependency Injection Container, you can:&lt;br&gt;
Decouple components by injecting dependencies instead of hardcoding them.&lt;br&gt;
Easily switch implementations of dependencies (e.g., for testing or different environments).&lt;br&gt;
Improve code organization and testability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9l4gnrps2vk8u2yep62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9l4gnrps2vk8u2yep62.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This code defines a simple Dependency Injection Container in PHP. Here's a breakdown of the important parts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Namespace:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;namespace App\Services;&lt;/code&gt;: This line indicates that the code belongs to the namespace App\Services. Namespaces help organize code and prevent naming collisions.&lt;br&gt;
&lt;strong&gt;2. Class Definition:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;class Container { ... }&lt;/code&gt;: This defines a class called Container, which will hold and manage dependencies.&lt;br&gt;
&lt;strong&gt;3. Bindings Property:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;private $bindings = [];&lt;/code&gt;: This is a private property that stores the dependencies. It's an array where keys are dependency "identifiers" and values are "factories" responsible for creating those dependencies.&lt;br&gt;
&lt;strong&gt;4. set Method:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;public function set(string $id, callable $factory): void&lt;/code&gt;: This method registers a dependency.&lt;br&gt;
&lt;code&gt;$id&lt;/code&gt;: The unique identifier for the dependency (e.g., 'database', 'logger').&lt;br&gt;
&lt;code&gt;$factory&lt;/code&gt;: A callable (function or closure) that knows how to create an instance of the dependency.&lt;br&gt;
&lt;strong&gt;5. get Method:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;public function get(string $id)&lt;/code&gt;: This method retrieves a dependency by its identifier.&lt;br&gt;
It checks if the dependency is registered using &lt;code&gt;isset($this-&amp;gt;bindings[$id])&lt;/code&gt;.&lt;br&gt;
If found, it retrieves the &lt;code&gt;$factory&lt;/code&gt; associated with the &lt;code&gt;$id&lt;/code&gt;.&lt;br&gt;
It then calls the &lt;code&gt;$factory&lt;/code&gt; with the container itself as an argument &lt;code&gt;($factory($this))&lt;/code&gt;, allowing the factory to potentially access other dependencies from the container.&lt;br&gt;
Finally, it returns the created instance of the dependency.&lt;br&gt;
If the dependency is not found, it throws an Exception.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;6. Views (views/signup.php, views/login.php):&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;signUp view :&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9tkf4wwumt3zpicsd3t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9tkf4wwumt3zpicsd3t.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgl6719z035qjl4mqb4an.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgl6719z035qjl4mqb4an.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gi2r7rqiho4890068cs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gi2r7rqiho4890068cs.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folxx6kx61aaon71l9elq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folxx6kx61aaon71l9elq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq3bkon6nbcnust0hyr05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq3bkon6nbcnust0hyr05.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;explication :&lt;/em&gt;&lt;br&gt;
&lt;u&gt;1. Namespace:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;namespace App\View\Login;&lt;/code&gt;: Indicates the code belongs to the namespace App\View\Login, organizing view-related code for login/signup.&lt;br&gt;
&lt;u&gt;2. SignUpView Class:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;class SignUpView { ... }:&lt;/code&gt; Defines a class named SignUpView, likely responsible for rendering the HTML of the signup form.&lt;br&gt;
&lt;u&gt;3. render Method:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;public static function render($errors) { ... }&lt;/code&gt;: This static method generates the HTML content of the signup form. The $errors parameter likely contains an array of validation errors from a controller, similar to the login form example.&lt;br&gt;
Key Elements Within the render Method:&lt;br&gt;
&lt;u&gt;Output Buffering:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;ob_start();&lt;/code&gt; and &lt;code&gt;ob_get_clean();:&lt;/code&gt; Similar to the login view, utilizes output buffering to capture the generated HTML content before sending it to the browser, allowing potential manipulation or processing.&lt;br&gt;
&lt;u&gt;Welcome Message and Login Link:&lt;/u&gt;&lt;br&gt;
A simple welcome message is displayed, along with a link to the login page (./login).&lt;br&gt;
&lt;u&gt;Sign-Up Form:&lt;/u&gt;&lt;br&gt;
form method="post" &lt;code&gt;action="./register"&lt;/code&gt;: Defines a form that uses the POST method to submit data to the ./register URL&lt;br&gt;
&lt;u&gt;Input Fields:&lt;/u&gt; Creates input fields for user information like "full name," "email," "date of birth," "gender," "password," and "confirm password." Labels are included for clarity.&lt;br&gt;
&lt;code&gt;&amp;lt;div class="--scroll" data-page='0'&amp;gt;:&lt;/code&gt; This suggests a potential multi-step form implementation using JavaScript to control form sections based on the data-page attribute.&lt;br&gt;
&lt;u&gt;Error Display:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;?= $errors['full_name'][0] ?? '' ?&amp;gt;&lt;/code&gt;: This line, repeated for different fields, uses the null coalescing operator (??) to display the first error message associated with a specific field (e.g., 'full_name') from the $errors array if it exists, otherwise displays nothing.&lt;br&gt;
&lt;u&gt;Navigation Buttons:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;button class="prev hidden" type="button"&amp;gt;&lt;/code&gt;...: A "previous" button, initially hidden, likely used for multi-step navigation within the form.&lt;br&gt;
&lt;code&gt;&amp;lt;button class="next" type="button"&lt;/code&gt;&amp;gt; ...: A "next" button for navigating to the next section of the form.&lt;br&gt;
&lt;code&gt;&amp;lt;button class="submit hidden" type="submit"&amp;gt;&lt;/code&gt; ...: A "submit" button, initially hidden, to finalize the registration process. The JavaScript handling the form navigation would likely reveal this button in the last step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;_singIn view : _&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1yly40ms0t2vea4wtrtd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1yly40ms0t2vea4wtrtd.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyfv7dq17d40u3bgdie6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyfv7dq17d40u3bgdie6.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0v2wbgzozuacmxv6d5o1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0v2wbgzozuacmxv6d5o1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv1vb4qtn55hlgut6fad.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv1vb4qtn55hlgut6fad.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;_explication : _ ( " almost the same thing in the signUp"&lt;br&gt;
&lt;u&gt;1. Namespace:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;namespace App\View\Login;&lt;/code&gt;: Indicates the code belongs to the App\View\Login namespace, keeping login view code organized.&lt;br&gt;
&lt;u&gt;2. SignInView Class:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;class SignInView { ... }&lt;/code&gt;: Defines a class named SignInView to handle login form rendering.&lt;br&gt;
&lt;u&gt;3. render Method:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;public static function render($errors) { ... }&lt;/code&gt;: This static method generates the HTML for the login form. The &lt;code&gt;$errors&lt;/code&gt; parameter is crucial as it likely contains an array of validation errors passed from the controller.&lt;br&gt;
&lt;u&gt;Key Elements Within the render Method:&lt;/u&gt;&lt;br&gt;
Output Buffering:&lt;br&gt;
&lt;code&gt;ob_start();&lt;/code&gt; and&lt;code&gt;ob_get_clean();&lt;/code&gt;: These functions utilize output buffering. The HTML content is generated and stored in a buffer instead of being immediately sent to the browser. This allows for manipulation or processing of the content before it's displayed.&lt;br&gt;
&lt;u&gt;Welcome Message and Signup Link:&lt;/u&gt;&lt;br&gt;
Provides a simple welcome message and a link to the registration page (./register).&lt;br&gt;
&lt;u&gt;Login Form:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;form method="post" action="./login"&lt;/code&gt;: Defines a form that uses the POST method to submit data to the ./login URL .&lt;br&gt;
&lt;u&gt;Input Fields:&lt;/u&gt; Creates input fields for "email" and "password," including labels for user clarity.&lt;br&gt;
&lt;u&gt;Error Display:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;?= $errors['null'] ?? '' ?&amp;gt;&lt;/code&gt;: Uses the null coalescing operator (&lt;code&gt;??&lt;/code&gt;) to display an error message associated with the 'null' key in the &lt;code&gt;$errors&lt;/code&gt; array if it exists, otherwise displays nothing. This could be for a general login error.&lt;br&gt;
&lt;code&gt;&amp;lt;?= $errors['email'][0] ?? '' ?&amp;gt;&lt;/code&gt; and&lt;code&gt;&amp;lt;?= $errors['password'][0] ?? '' ?&amp;gt;&lt;/code&gt;: Similar to the above, these lines display specific error messages associated with the 'email' and 'password' fields, respectively, if they exist in the $errors array.&lt;br&gt;
&lt;u&gt;Sign In Button:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;button class="submit" type="submit"&amp;gt;Sign In&amp;lt;/button&amp;gt;&lt;/code&gt;: Creates a button for users to submit the form.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;7.services (AuthService.php ):&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faakhhznahmfm64qznrum.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faakhhznahmfm64qznrum.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2cx94bigjram9tj99hmz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2cx94bigjram9tj99hmz.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnhf07m5z4yih3pyflv1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnhf07m5z4yih3pyflv1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4rpq9ltvw9oduvyin3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4rpq9ltvw9oduvyin3g.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzejmkuer79rr6ff4mudt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzejmkuer79rr6ff4mudt.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F35o8634mivmk6ndjxwja.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F35o8634mivmk6ndjxwja.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzw3c79tkdlmvuu58j7lo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzw3c79tkdlmvuu58j7lo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This PHP code defines an &lt;strong&gt;AuthService&lt;/strong&gt;class within the App\Services namespace, which is responsible for handling user registration and &lt;strong&gt;login processes&lt;/strong&gt;, including form validation and password hashing with a salt. Here's a brief explanation focusing on form validation and the salt-hashing process:&lt;br&gt;
&lt;u&gt;Namespace and Imports:&lt;/u&gt;&lt;br&gt;
The class is part of the App\Services namespace and imports Validator and UserModel classes from other namespaces.&lt;br&gt;
&lt;u&gt;Class Properties and Constructor :&lt;/u&gt;The AuthService class has two private properties: &lt;code&gt;$model&lt;/code&gt;of type UserModel and &lt;code&gt;$validator&lt;/code&gt;of type Validator. These are injected via the constructor, allowing the class to interact with the database and validate data.&lt;br&gt;
&lt;u&gt;Form Validation in validateRegistration:&lt;/u&gt;&lt;br&gt;
The validateRegistration method uses the Validator class to validate the registration data. It sets aliases for form fields for better error messages and defines validation rules for each field:&lt;br&gt;
full_name must be required and contain only alphabetic characters.&lt;br&gt;
email must be required and in a valid email format.&lt;br&gt;
dob (date of birth) must be required and in a valid date format.&lt;br&gt;
gender must be required and a valid gender value.&lt;br&gt;
password must be required and meet the criteria defined by the password rule (likely a minimum length and complexity).&lt;br&gt;
confirm_password must match the password field.&lt;br&gt;
If validation fails, it returns an array with success set to false and the errors collected by the validator.&lt;br&gt;
If validation passes, it returns an array with success set to true and the validated data.&lt;br&gt;
&lt;strong&gt;&lt;u&gt;Password Hashing with Salt in register :&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
Before inserting the user data into the database, the register method generates a random salt using random_bytes(16) and converts it to hexadecimal with bin2hex(). This salt is then concatenated with the plain text password.&lt;br&gt;
The concatenated string (salt + password) is hashed using &lt;code&gt;password_hash()&lt;/code&gt; with the &lt;code&gt;PASSWORD_ARGON2ID&lt;/code&gt;algorithm, which is a strong hashing algorithm suitable for storing passwords securely.&lt;br&gt;
The hashed password and the generated salt are stored in the database. This ensures that even if the password is compromised, the attacker cannot reverse-engineer the original password from the hash due to the presence of the unique salt.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;6. Views (views/dashboardView.php):&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;dashbord view :&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2ru6yl3i5sq05j5ycej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2ru6yl3i5sq05j5ycej.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This code represents a view that generates a dynamic dashboard page. It highlights several important aspects of views in an MVC application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqsmzw4hmn2usgcgqiomo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqsmzw4hmn2usgcgqiomo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the html code : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnojzkowu2g65x9f4ybr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnojzkowu2g65x9f4ybr.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30ytv4i1bqqkkxraxii4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30ytv4i1bqqkkxraxii4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code represents a simple view in a PHP MVC application, likely designed for a dashboard. Here's a breakdown:&lt;br&gt;
&lt;u&gt;1. Namespace:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;namespace App\View\Dashboard;&lt;/code&gt;: Similar to the previous example, this indicates the code belongs to the namespace App\View\Dashboard, likely organizing view-related code.&lt;br&gt;
&lt;u&gt;2. SCRIPT_ROOT Constant:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;define('SCRIPT_ROOT', 'http://localhost/hackathon');&lt;/code&gt;: This defines a constant SCRIPT_ROOT with the base URL of your application. This constant is used throughout the HTML to build paths to resources like CSS files and images.&lt;br&gt;
&lt;u&gt;3. DashboardView Class:&lt;/u&gt;&lt;br&gt;
&lt;code&gt;class DashboardView { ... }&lt;/code&gt;: This defines a class DashboardView, which likely encapsulates the logic for generating the HTML of the dashboard.&lt;br&gt;
&lt;u&gt;4. render Method:&lt;/u&gt;&lt;br&gt;
public static function render() { ... }: This static method generates the actual HTML content of the dashboard. It's designed to be called from a controller, which would pass any necessary data to populate the view.&lt;br&gt;
&lt;u&gt;Key Elements Within the render Method:&lt;/u&gt;&lt;br&gt;
HTML Structure: The method outputs a standard HTML document structure, including the &lt;/p&gt; section with metadata and links to CSS stylesheets, and the  section containing the main content.&lt;br&gt;
Dynamic Paths: The&lt;code&gt;SCRIPT_ROOT&lt;/code&gt; constant is used to create dynamic paths for resources:&lt;br&gt;
&lt;code&gt;href="&amp;lt;?php echo SCRIPT_ROOT ?&amp;gt;/public/css/style.css"&lt;/code&gt;&lt;br&gt;
&lt;code&gt;src="&amp;lt;?php echo SCRIPT_ROOT ?&amp;gt;/public/images/logo.png"&lt;/code&gt;&lt;br&gt;
This ensures that resources are loaded correctly regardless of where the application is deployed.&lt;br&gt;
Sidebar and Navbar: The HTML defines a sidebar (&lt;code&gt;&amp;lt;div class="sidebar"&amp;gt;&lt;/code&gt;) containing navigation links, and a navbar (&lt;code&gt;&amp;lt;div class="navbar"&amp;gt;&lt;/code&gt;) for search and user information.&lt;br&gt;
PHP Integration: There are some PHP snippets embedded within the HTML:&lt;br&gt;
&lt;code&gt;&amp;lt;h2&amp;gt;&amp;lt;?= ucfirst($_SESSION['full_name']) ?&amp;gt;&amp;lt;/h2&amp;gt;&lt;/code&gt;: This line likely displays the user's name retrieved from a session variable.

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbm2uzaqyf1t80hm29gse.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbm2uzaqyf1t80hm29gse.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7rub5kzijhia0318yzdb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7rub5kzijhia0318yzdb.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Et Voila ! , this is our "mini-tutorial" for our "mini-project"&lt;br&gt;
to get the full folders and files of our project you can acces to our gitHub : &lt;a href="https://github.com/ramo4040/Hackathon-OFPPT/tree/main" rel="noopener noreferrer"&gt;LinkToGithub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You've built a basic PHP authentication system!&lt;br&gt;
&lt;strong&gt;Key Security Considerations:&lt;/strong&gt;&lt;br&gt;
&lt;u&gt;Password Hashing: &lt;/u&gt;Always hash passwords using bcrypt (password_hash()) before storing them. Never store passwords in plain text.&lt;br&gt;
&lt;u&gt;Input Validation:&lt;/u&gt; Thoroughly validate and sanitize user input to prevent vulnerabilities like SQL injection and cross-site scripting (XSS).&lt;br&gt;
&lt;u&gt;Session Management:&lt;/u&gt; Implement secure session management practices to protect user data.&lt;br&gt;
This is a simple starting point. You can expand this system to include password reset functionality, email verification, and more complex authorization rule&lt;/p&gt;

</description>
      <category>php</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
