{"title":"Ramiz\u2019s blog about development","link":[{"@attributes":{"href":"https:\/\/kongulov.dev\/atom.xml","rel":"self"}},{"@attributes":{"href":"https:\/\/kongulov.dev\/"}}],"updated":"2026-01-21T21:27:27+04:00","id":"https:\/\/kongulov.dev","author":{"name":"Ramiz Kongulov","email":"ramiz.kongulov@gmail.com"},"entry":[{"title":"Configuring and Utilizing Multiple Databases in Laravel","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/configuring-and-utilizing-multiple-databases-in-laravel"}},"updated":"2024-04-29T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/configuring-and-utilizing-multiple-databases-in-laravel","content":"<p>In Laravel, managing multiple databases is a common requirement for complex applications where data is distributed across different databases.\nWhether you need to interact with multiple databases for sharding, legacy systems, or simply for better organization, Laravel provides a convenient way to handle multiple database connections out of the box.\nn this guide, we\u2019ll explore how to configure and utilize multiple database connections in Laravel, along with practical examples to demonstrate various scenarios.<\/p>\n\n<p>Before diving into the usage, let\u2019s set up multiple database connections in Laravel.\nLaravel\u2019s database configuration is stored in the <code class=\"language-plaintext highlighter-rouge\">config\/database.php<\/code> file.\nInside this file, you\u2019ll find an array of database connections. To add a new connection, simply define a new array with the connection details.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"s1\">'connections'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">[<\/span>\n    <span class=\"s1\">'mysql'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">[<\/span>\n        <span class=\"s1\">'driver'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">'mysql'<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'host'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">env<\/span><span class=\"p\">(<\/span><span class=\"s1\">'DB_HOST'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'127.0.0.1'<\/span><span class=\"p\">),<\/span>\n        <span class=\"s1\">'port'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">env<\/span><span class=\"p\">(<\/span><span class=\"s1\">'DB_PORT'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'3306'<\/span><span class=\"p\">),<\/span>\n        <span class=\"s1\">'database'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">env<\/span><span class=\"p\">(<\/span><span class=\"s1\">'DB_DATABASE'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'forge'<\/span><span class=\"p\">),<\/span>\n        <span class=\"s1\">'username'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">env<\/span><span class=\"p\">(<\/span><span class=\"s1\">'DB_USERNAME'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'forge'<\/span><span class=\"p\">),<\/span>\n        <span class=\"s1\">'password'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">env<\/span><span class=\"p\">(<\/span><span class=\"s1\">'DB_PASSWORD'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">''<\/span><span class=\"p\">),<\/span>\n        <span class=\"s1\">'charset'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">'utf8mb4'<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'collation'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">'utf8mb4_unicode_ci'<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'prefix'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">''<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'strict'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'engine'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"kc\">null<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">],<\/span>\n\n    <span class=\"s1\">'second_db'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">[<\/span>\n        <span class=\"s1\">'driver'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">'mysql'<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'host'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">env<\/span><span class=\"p\">(<\/span><span class=\"s1\">'SECOND_DB_HOST'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'127.0.0.1'<\/span><span class=\"p\">),<\/span>\n        <span class=\"s1\">'port'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">env<\/span><span class=\"p\">(<\/span><span class=\"s1\">'SECOND_DB_PORT'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'3306'<\/span><span class=\"p\">),<\/span>\n        <span class=\"s1\">'database'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">env<\/span><span class=\"p\">(<\/span><span class=\"s1\">'SECOND_DB_DATABASE'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'forge'<\/span><span class=\"p\">),<\/span>\n        <span class=\"s1\">'username'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">env<\/span><span class=\"p\">(<\/span><span class=\"s1\">'SECOND_DB_USERNAME'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'forge'<\/span><span class=\"p\">),<\/span>\n        <span class=\"s1\">'password'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">env<\/span><span class=\"p\">(<\/span><span class=\"s1\">'SECOND_DB_PASSWORD'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">''<\/span><span class=\"p\">),<\/span>\n        <span class=\"s1\">'charset'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">'utf8mb4'<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'collation'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">'utf8mb4_unicode_ci'<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'prefix'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">''<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'strict'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'engine'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"kc\">null<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">],<\/span>\n<span class=\"p\">],<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>We\u2019ve added a new database connection named <code class=\"language-plaintext highlighter-rouge\">second_db<\/code> here. Ensure you\u2019ve updated the environment variables in your <code class=\"language-plaintext highlighter-rouge\">.env<\/code> file accordingly.<\/p>\n\n<p>Once you\u2019ve set up the database connections, you can utilize them throughout your application.\nLaravel\u2019s Eloquent ORM provides a convenient way to interact with databases.<\/p>\n\n<h2>1. Model Setup<\/h2>\n\n<p>When defining Eloquent models that use a different database connection, specify the <code class=\"language-plaintext highlighter-rouge\">$connection<\/code> property.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Models<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Database\\Eloquent\\Model<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">SecondModel<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Model<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">protected<\/span> <span class=\"nv\">$connection<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'second_db'<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h2>2. Querying Data<\/h2>\n\n<p>When querying data from a specific database connection, you can use the <code class=\"language-plaintext highlighter-rouge\">on<\/code> method on the Eloquent query builder.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nv\">$users<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">App\\Models\\SecondModel<\/span><span class=\"o\">::<\/span><span class=\"nf\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">'second_db'<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">get<\/span><span class=\"p\">();<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h2>3. Raw SQL Queries<\/h2>\n\n<p>You can execute raw SQL queries on a specific connection using the <code class=\"language-plaintext highlighter-rouge\">DB::connection()<\/code> method.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nv\">$users<\/span> <span class=\"o\">=<\/span> <span class=\"no\">DB<\/span><span class=\"o\">::<\/span><span class=\"nf\">connection<\/span><span class=\"p\">(<\/span><span class=\"s1\">'second_db'<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">select<\/span><span class=\"p\">(<\/span><span class=\"s1\">'select * from table_name'<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h2>Conclusion<\/h2>\n\n<p>Managing multiple databases in Laravel provides flexibility and scalability to your applications.\nBy following the steps outlined in this guide, you can seamlessly configure and utilize multiple database connections in your Laravel projects.\nWhether it\u2019s for distributed data storage, legacy integrations, or other requirements, Laravel\u2019s robust database management capabilities make handling multiple databases a breeze.<\/p>\n\n"},{"title":"Building Efficient Applications with MySQL Stored Procedures","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/building-efficient-applications-with-mysql-stored-procedures"}},"updated":"2023-09-22T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/building-efficient-applications-with-mysql-stored-procedures","content":"<p>MySQL stored procedure is a powerful database function that allows you to store and execute a set of SQL statements in the database,\nsimilar to functions in programming. The storage process can greatly improve the performance, security and maintainability of the database.\nThis article will introduce the use of MySQL stored procedures in detail.<\/p>\n\n<h2>What is a MySQL stored procedure?<\/h2>\n\n<p>MySQL stored procedures are a set of precompiled SQL statements that are stored in the database with a name and can be called and executed at any time.\nStored procedures can accept input arguments, perform a series of operations, and return results.\nThese characteristics make stored procedures an ideal tool for handling complex queries, data manipulation, and transaction management.<\/p>\n\n<h2>Create a stored procedure<\/h2>\n\n<p>To create a MySQL stored procedure, you use <code class=\"language-plaintext highlighter-rouge\">CREATE PROCEDURE<\/code> statements. Here is a simple example:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">DELIMITER<\/span> <span class=\"o\">\/\/<\/span>\n<span class=\"k\">CREATE<\/span> <span class=\"k\">PROCEDURE<\/span> <span class=\"n\">GetUser<\/span><span class=\"p\">(<\/span><span class=\"k\">IN<\/span> <span class=\"n\">user_id<\/span> <span class=\"nb\">INT<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">BEGIN<\/span>\n    <span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">id<\/span> <span class=\"o\">=<\/span> <span class=\"n\">user_id<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">END<\/span> <span class=\"o\">\/\/<\/span>\n<span class=\"k\">DELIMITER<\/span> <span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<ul>\n  <li><code class=\"language-plaintext highlighter-rouge\">DELIMITER<\/code> Used to define the separator. Because the stored procedure contains multiple SQL statements, a separator different from the semicolon is required.<\/li>\n  <li><code class=\"language-plaintext highlighter-rouge\">CREATE PROCEDURE<\/code> Create a stored procedure that accepts an <code class=\"language-plaintext highlighter-rouge\">user_id<\/code> input argument named and contains a set of SQL statements between <code class=\"language-plaintext highlighter-rouge\">BEGIN<\/code> and <code class=\"language-plaintext highlighter-rouge\">END<\/code><\/li>\n<\/ul>\n\n<h2>Call stored procedure<\/h2>\n\n<p>Once the stored procedure is created, you can <code class=\"language-plaintext highlighter-rouge\">CALL<\/code> execute it using the statement:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">CALL<\/span> <span class=\"n\">GetUser<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>This will call the stored procedure named and pass it <code class=\"language-plaintext highlighter-rouge\">GetUser<\/code> the arguments <code class=\"language-plaintext highlighter-rouge\">1<\/code><\/p>\n\n<h2>Arguments to stored procedure<\/h2>\n\n<p>Stored procedures can accept arguments, which can be input arguments, output arguments, or input\/output arguments.\nIn the above example, <code class=\"language-plaintext highlighter-rouge\">user_id<\/code> it is an input argument because it is used to pass values to the stored procedure.\nYou can define different types of arguments using the following syntax:<\/p>\n\n<ul>\n  <li><code class=\"language-plaintext highlighter-rouge\">IN<\/code>: Indicates that the argument is an input argument and can be used to pass values to the stored procedure.<\/li>\n  <li><code class=\"language-plaintext highlighter-rouge\">OUT<\/code>: Indicates that the argument is an output argument and can be used to return a value from a stored procedure.<\/li>\n  <li><code class=\"language-plaintext highlighter-rouge\">INOUT<\/code>: Indicates that the argument is an input\/output argument and can be used to pass values and return values from stored procedures.<\/li>\n<\/ul>\n\n<h2>Stored procedure logic<\/h2>\n\n<p>The body of the stored procedure is contained <code class=\"language-plaintext highlighter-rouge\">BEGIN<\/code> between <code class=\"language-plaintext highlighter-rouge\">END<\/code> and and can contain various SQL statements,\nsuch as <code class=\"language-plaintext highlighter-rouge\">SELECT<\/code>, <code class=\"language-plaintext highlighter-rouge\">INSERT<\/code>, <code class=\"language-plaintext highlighter-rouge\">UPDATE<\/code>, <code class=\"language-plaintext highlighter-rouge\">DELETE<\/code>, <code class=\"language-plaintext highlighter-rouge\">IF<\/code> statement, <code class=\"language-plaintext highlighter-rouge\">LOOP<\/code> statement, etc.\nThis allows you to perform complex logic in stored procedures, such as transaction processing, conditional judgments, and loop operations.<\/p>\n\n<h2>Advantages of the storage process<\/h2>\n\n<p>Using stored procedures has the following advantages:<\/p>\n\n<ol>\n  <li><strong>Performance Optimization<\/strong>: Stored procedures are generally faster than individual SQL statements because they are compiled and cached on the database server, reducing communication overhead.<\/li>\n  <li><strong>Security<\/strong>: Stored procedures can be used to encapsulate sensitive operations, thereby improving the security of the database. The user only needs to call the stored procedure without directly accessing the table.<\/li>\n  <li><strong>Maintainability<\/strong>: Stored procedures allow commonly used business logic to be encapsulated in one place, reducing program code redundancy and making it easier to maintain.<\/li>\n  <li><strong>Transaction management<\/strong>: Stored procedures can be used to manage complex transaction logic to ensure data consistency and integrity.<\/li>\n  <li><strong>Reduce network latency<\/strong>: The storage process is executed on the database server, which can reduce network communication with the user.<\/li>\n<\/ol>\n\n<h2>Disadvantages of storage process<\/h2>\n\n<p>While the storage process has many advantages, there are also some disadvantages:<\/p>\n\n<ol>\n  <li><strong>Complexity<\/strong>: Writing and maintaining complex stored procedures can become difficult, especially for developers who are unfamiliar with stored procedures.<\/li>\n  <li><strong>Portability<\/strong>: The syntax and functionality of stored procedures vary between database systems and may not be portable enough.<\/li>\n  <li><strong>Difficult to debug<\/strong>: Debugging stored procedures can be more challenging than debugging application code because they execute in a database.<\/li>\n<\/ol>\n\n<h2>Modify and delete stored procedures<\/h2>\n\n<p>To modify a stored procedure, you use <code class=\"language-plaintext highlighter-rouge\">ALTER PROCEDURE<\/code> statements. To delete a stored procedure, you can use <code class=\"language-plaintext highlighter-rouge\">DROP PROCEDURE<\/code> the statement.<\/p>\n\n<p>These commands allow you to update the logic of a stored procedure or delete a stored procedure that is no longer needed.<\/p>\n\n<h2>Conclusion<\/h2>\n\n<p>MySQL stored procedures are a powerful tool that can improve the performance and security of the database,\nbut they also need to be used with caution to ensure good code quality and maintainability.\nStored procedures are often used to encapsulate complex business logic, optimize queries, and provide better database management and security.\nWhether you are processing large-scale data or performing complex transactions, stored procedures are a powerful tool for MySQL database management.<\/p>\n"},{"title":"Simplifying data structures with ENUM in Laravel","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/simplifying-data-structures-with-enum-in-laravel"}},"updated":"2023-06-28T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/simplifying-data-structures-with-enum-in-laravel","content":"<p>In modern web development, handling data structures efficiently is a crucial aspect of creating robust applications.\nENUM (Enumerated Type) is a powerful feature in PHP that enables developers to define a set of named constants, making code more readable, maintainable, and less prone to errors.\nIn this blog post, we will explore ENUM in PHP and discuss how it can be integrated into Laravel, one of the most popular PHP frameworks.<\/p>\n\n<p>Laravel, with its elegant syntax and powerful features, provides built-in support for ENUM.\nHere\u2019s a step-by-step guide on how to utilize ENUM in Laravel:<\/p>\n\n<h2>Create the ENUM Class:<\/h2>\n\n<p>Inside the <code class=\"language-plaintext highlighter-rouge\">app\/Enums<\/code> directory, create a new PHP file, e.g., <code class=\"language-plaintext highlighter-rouge\">StatusEnum.php<\/code>.\nThis file will contain the ENUM constants and their associated values:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Enums<\/span><span class=\"p\">;<\/span>\n\n<span class=\"n\">enum<\/span> <span class=\"nc\">StatusEnum<\/span><span class=\"o\">:<\/span> <span class=\"n\">string<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">case<\/span> <span class=\"nc\">Pending<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'pending'<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">case<\/span> <span class=\"nc\">Active<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'active'<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">case<\/span> <span class=\"nc\">Inactive<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'inactive'<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Here, we\u2019ve defined three constants: <code class=\"language-plaintext highlighter-rouge\">ACTIVE<\/code>, <code class=\"language-plaintext highlighter-rouge\">INACTIVE<\/code>, and <code class=\"language-plaintext highlighter-rouge\">PENDING<\/code>, representing different statuses.<\/p>\n\n<p>To make it even more convenient to work with ENUMs, we will use the <a href=\"https:\/\/github.com\/kongulov\/interact-with-enum\" ratget=\"_blank\">kongulov\/interact-with-enum<\/a> package with the <code class=\"language-plaintext highlighter-rouge\">InteractWithEnum<\/code> trait, which contains useful methods for working with ENUMs<\/p>\n\n<p>Install the package via Composer:<\/p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\"># Install interact-with-enum<\/span>\ncomposer require kongulov\/interact-with-enum\n<\/code><\/pre><\/div><\/div>\n\n<p>And use it in all our ENUMs to make it look like this<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Enums<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kn\">use<\/span> <span class=\"nc\">Kongulov\\Traits\\InteractWithEnum<\/span><span class=\"p\">;<\/span>\n\n<span class=\"n\">enum<\/span> <span class=\"nc\">StatusEnum<\/span><span class=\"o\">:<\/span> <span class=\"n\">string<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kn\">use<\/span> <span class=\"nc\">InteractWithEnum<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"k\">case<\/span> <span class=\"nc\">Pending<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'pending'<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">case<\/span> <span class=\"nc\">Active<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'active'<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">case<\/span> <span class=\"nc\">Inactive<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'inactive'<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h2>Using ENUM in Code:<\/h2>\n\n<p>Once you\u2019ve created the ENUM class, you can leverage it in your code. Here are a few examples:<\/p>\n\n<h3>Model Definition<\/h3>\n\n<p>In your Eloquent models, you can specify the ENUM field and its associated ENUM class using the $casts attribute:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Models<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Database\\Eloquent\\Model<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Enums\\StatusEnum<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">User<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Model<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ ...<\/span>\n    <span class=\"k\">protected<\/span> <span class=\"nv\">$fillable<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span>\n        <span class=\"s1\">'name'<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'email'<\/span><span class=\"p\">,<\/span>\n        <span class=\"s1\">'status'<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">];<\/span>\n\n    <span class=\"k\">protected<\/span> <span class=\"nv\">$casts<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span>\n        <span class=\"s1\">'status'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nc\">StatusEnum<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">];<\/span>\n    <span class=\"c1\">\/\/ ...<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>By setting the status field\u2019s cast type to <code class=\"language-plaintext highlighter-rouge\">StatusEnum<\/code>, Laravel will automatically handle the conversion between the ENUM value and its corresponding constant.<\/p>\n\n<h3>Database Migrations<\/h3>\n\n<p>In your database migration files, you can define ENUM columns using the <code class=\"language-plaintext highlighter-rouge\">-&gt;enum()<\/code> method:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n\n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Database\\Migrations\\Migration<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Database\\Schema\\Blueprint<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Support\\Facades\\Schema<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Enums\\StatusEnum<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">CreateUsersTable<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Migration<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">up<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nc\">Schema<\/span><span class=\"o\">::<\/span><span class=\"nf\">create<\/span><span class=\"p\">(<\/span><span class=\"s1\">'users'<\/span><span class=\"p\">,<\/span> <span class=\"k\">function<\/span> <span class=\"p\">(<\/span><span class=\"kt\">Blueprint<\/span> <span class=\"nv\">$table<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"c1\">\/\/ ...<\/span>\n            <span class=\"nv\">$table<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">enum<\/span><span class=\"p\">(<\/span><span class=\"s1\">'status'<\/span><span class=\"p\">,<\/span> <span class=\"nc\">StatusEnum<\/span><span class=\"o\">::<\/span><span class=\"nf\">values<\/span><span class=\"p\">())<\/span><span class=\"o\">-&gt;<\/span><span class=\"k\">default<\/span><span class=\"p\">(<\/span><span class=\"nc\">StatusEnum<\/span><span class=\"o\">::<\/span><span class=\"nc\">Pending<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">value<\/span><span class=\"p\">);<\/span>\n            <span class=\"c1\">\/\/ ...<\/span>\n        <span class=\"p\">});<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"c1\">\/\/ ...<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Here, we\u2019ve created a status column in the users table, using the ENUM constants defined in <code class=\"language-plaintext highlighter-rouge\">StatusEnum<\/code>.<\/p>\n\n<h3>Using ENUM in Validation:<\/h3>\n\n<p>Laravel\u2019s validation rules allow you to validate ENUM values easily. Here\u2019s an example:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Http\\Requests<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Foundation\\Http\\FormRequest<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Validation\\Rules\\Enum<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Enums\\StatusEnum<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">UpdateUserRequest<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">FormRequest<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">rules<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"p\">[<\/span>\n            <span class=\"s1\">'status'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">[<\/span><span class=\"s1\">'required'<\/span><span class=\"p\">,<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Enum<\/span><span class=\"p\">(<\/span><span class=\"nc\">StatusEnum<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">)],<\/span>\n        <span class=\"p\">];<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>In this example, we\u2019ve defined a validation rule for the <code class=\"language-plaintext highlighter-rouge\">status<\/code> field, ensuring that it is required and can only contain one of the ENUM constants defined in <code class=\"language-plaintext highlighter-rouge\">StatusEnum<\/code>.<\/p>\n\n<h2>Conclusion<\/h2>\n\n<p>ENUMs in Laravel provide an elegant solution for handling fixed sets of values, improving code readability and maintaining data integrity.\nBy creating an ENUM class, you can define constants representing different values and easily use them throughout your application.\nWhether it\u2019s in database migrations, models, or validation, ENUMs offer a robust way to manage and validate your data effectively.\nImplement ENUMs in your Laravel projects and experience the benefits of streamlined code and enhanced data structure management.<\/p>\n"},{"title":"Install and Configure Supervisor for Laravel Queue","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/install-and-configure-supervisor-for-laravel-queue"}},"updated":"2023-04-07T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/install-and-configure-supervisor-for-laravel-queue","content":"<p>Supervisor is a process control system for Linux that allows you to monitor and control processes on your server.\nIt is particularly useful for managing long-running processes, such as Laravel queues, which can run for hours or even days at a time.\nIn this post, we will go through the process of installing and using Supervisor with Laravel queue<\/p>\n\n<h2>1. Install Supervisor<\/h2>\n\n<p>The first step is to install Supervisor on your server. This can typically be done using your server\u2019s package manager.\nFor example, on Ubuntu, you can install Supervisor using the following command:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">sudo<\/span> <span class=\"n\">apt<\/span><span class=\"o\">-<\/span><span class=\"n\">get<\/span> <span class=\"n\">install<\/span> <span class=\"n\">supervisor<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Once Supervisor is installed, you can start and stop it using the following commands:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">sudo<\/span> <span class=\"n\">systemctl<\/span> <span class=\"n\">start<\/span> <span class=\"n\">supervisor<\/span>\n<span class=\"n\">sudo<\/span> <span class=\"n\">systemctl<\/span> <span class=\"n\">stop<\/span> <span class=\"n\">supervisor<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h2>2. Configure Supervisor<\/h2>\n\n<p>The next step is to configure Supervisor to manage your Laravel queue processes.\nSupervisor uses configuration files to define the processes it should manage.\nThese files are typically stored in the <code class=\"language-plaintext highlighter-rouge\">\/etc\/supervisor\/conf.d\/<\/code> directory.<\/p>\n\n<p>Create a new configuration file for your Laravel queue using the following command:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">sudo<\/span> <span class=\"n\">nano<\/span> <span class=\"o\">\/<\/span><span class=\"n\">etc<\/span><span class=\"o\">\/<\/span><span class=\"n\">supervisor<\/span><span class=\"o\">\/<\/span><span class=\"n\">conf<\/span><span class=\"mf\">.<\/span><span class=\"n\">d<\/span><span class=\"o\">\/<\/span><span class=\"n\">laravel<\/span><span class=\"o\">-<\/span><span class=\"n\">queue<\/span><span class=\"mf\">.<\/span><span class=\"n\">conf<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>In this file, you will need to define the command that Supervisor should use to start your Laravel queue.\nHere is an example configuration file:<\/p>\n\n<div class=\"language-ini highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nn\">[program:laravel-queue]<\/span>\n<span class=\"py\">process_name<\/span><span class=\"p\">=<\/span><span class=\"s\">%(program_name)s_%(process_num)02d<\/span>\n<span class=\"py\">command<\/span><span class=\"p\">=<\/span><span class=\"s\">php \/path\/to\/artisan queue:work --queue=default --sleep=3 --tries=3 --max-time=3600<\/span>\n<span class=\"py\">autostart<\/span><span class=\"p\">=<\/span><span class=\"s\">true<\/span>\n<span class=\"py\">autorestart<\/span><span class=\"p\">=<\/span><span class=\"s\">true<\/span>\n<span class=\"py\">stopasgroup<\/span><span class=\"p\">=<\/span><span class=\"s\">true<\/span>\n<span class=\"py\">killasgroup<\/span><span class=\"p\">=<\/span><span class=\"s\">true<\/span>\n<span class=\"py\">user<\/span><span class=\"p\">=<\/span><span class=\"s\">www-data<\/span>\n<span class=\"py\">numprocs<\/span><span class=\"p\">=<\/span><span class=\"s\">8<\/span>\n<span class=\"py\">redirect_stderr<\/span><span class=\"p\">=<\/span><span class=\"s\">true<\/span>\n<span class=\"py\">stdout_logfile<\/span><span class=\"p\">=<\/span><span class=\"s\">\/var\/log\/laravel-queue.log<\/span>\n\n<\/code><\/pre><\/div><\/div>\n\n<p>In this configuration file, we have defined a process called <code class=\"language-plaintext highlighter-rouge\">laravel-queue<\/code>, which will run the <code class=\"language-plaintext highlighter-rouge\">queue:work<\/code> command.\nWe have specified that the process should start automatically and restart if it crashes, and we have set the number of processes to run to 8.\nWe have also redirected the stderr output to a log file.<\/p>\n\n<p>Save and close the configuration file when you are done.<\/p>\n\n<h2>3. Reload Supervisor<\/h2>\n\n<p>Once you have created your configuration file, you will need to tell Supervisor to reload its configuration:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">sudo<\/span> <span class=\"n\">supervisorctl<\/span> <span class=\"n\">reread<\/span>\n<span class=\"n\">sudo<\/span> <span class=\"n\">supervisorctl<\/span> <span class=\"n\">update<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>This will read your new configuration file and add the <code class=\"language-plaintext highlighter-rouge\">laravel-queue<\/code> process to the list of processes that Supervisor should manage.<\/p>\n\n<h2>4. Start the Laravel Queue<\/h2>\n\n<p>With Supervisor configured, you can now start the Laravel queue using the following command:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">sudo<\/span> <span class=\"n\">supervisorctl<\/span> <span class=\"n\">start<\/span> <span class=\"n\">laravel<\/span><span class=\"o\">-<\/span><span class=\"n\">queue<\/span><span class=\"o\">:*<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>This will start all of the processes defined in your configuration file.<\/p>\n\n<h2>5. Monitor the Laravel Queue<\/h2>\n\n<p>This will display the status of all processes managed by Supervisor, including your Laravel queue processes.<\/p>\n\n<h2>Conclusion<\/h2>\n\n<p>In this post, we have gone through the process of installing and using Supervisor with Laravel queue.\nBy using Supervisor to manage your Laravel queue processes, you can ensure that they run reliably and continuously,\neven if they encounter errors or crashes. This can help to ensure that your application runs smoothly and efficiently,\neven under heavy load.<\/p>\n\n<p>You can read about how to create a queue in Laravel in the following article: <a href=\"https:\/\/kongulov.dev\/blog\/queues-in-laravel\">Queues in Laravel<\/a><\/p>\n"},{"title":"Understanding the Adapter Design Pattern in PHP","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/understanding-the-adapter-design-pattern-in-php"}},"updated":"2023-02-21T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/understanding-the-adapter-design-pattern-in-php","content":"<p>The Adapter pattern is a structural design pattern that allows two incompatible interfaces to work together.\nThis pattern is used to create a bridge between two incompatible interfaces by creating an intermediate adapter that can translate the interface of one object to another.\nThe Adapter pattern is useful when you need to use an existing class, but its interface doesn\u2019t match the one you need.<\/p>\n\n<p>Let\u2019s take a real-life example to understand the Adapter pattern better.\nSuppose you have a smartphone that uses a USB Type-C charging cable, and you want to charge it using an old charger that only has a Micro-USB port.\nTo connect your smartphone to the old charger, you need a Type-C to Micro-USB adapter.\nThis adapter acts as a bridge between the incompatible interfaces of your smartphone and the old charger, allowing them to work together.<\/p>\n\n<p>In software development, the Adapter pattern is commonly used in legacy codebases where you need to use existing code or libraries that have an incompatible interface with your application.\nBy creating an adapter, you can use the existing code without having to modify it.<\/p>\n\n<p>Let\u2019s take an example of a payment system to understand how the Adapter pattern works in PHP.<\/p>\n\n<p>Suppose you are building an e-commerce website that needs to accept payments from multiple payment gateways, such as <code class=\"language-plaintext highlighter-rouge\">PayPal<\/code> and <code class=\"language-plaintext highlighter-rouge\">Stripe<\/code>.\nEach payment gateway has its own API and interface for processing payments.\nTo make it easier to integrate these payment gateways into your website, you can create an adapter for each payment gateway that translates its API into a common interface that your website can use.<\/p>\n\n<p>Let\u2019s imagine that we have 2 classes of payment gateways <code class=\"language-plaintext highlighter-rouge\">PayPalGateway<\/code> and <code class=\"language-plaintext highlighter-rouge\">StripeGateway<\/code>,  have their own payment processing interface, but they need to be adapted to our interface<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">PayPalGateway<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">sendPayment<\/span><span class=\"p\">(<\/span><span class=\"kt\">float<\/span> <span class=\"nv\">$amount<\/span><span class=\"p\">):<\/span> <span class=\"kt\">bool<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ Send payment using PayPal API<\/span>\n        <span class=\"k\">return<\/span> <span class=\"kc\">true<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">StripeGateway<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">charge<\/span><span class=\"p\">(<\/span><span class=\"kt\">float<\/span> <span class=\"nv\">$amount<\/span><span class=\"p\">):<\/span> <span class=\"kt\">bool<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ Charge payment using Stripe API<\/span>\n        <span class=\"k\">return<\/span> <span class=\"kc\">true<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>First, let\u2019s create the <code class=\"language-plaintext highlighter-rouge\">PaymentAdapterInterface<\/code> interface, which will define the general interface for processing payments.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">interface<\/span> <span class=\"nc\">PaymentAdapterInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">processPayment<\/span><span class=\"p\">(<\/span><span class=\"kt\">float<\/span> <span class=\"nv\">$amount<\/span><span class=\"p\">):<\/span> <span class=\"kt\">bool<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>To make these payment gateways compatible with our payment system,we have created two adapter classes <code class=\"language-plaintext highlighter-rouge\">PayPalAdapter<\/code> and <code class=\"language-plaintext highlighter-rouge\">StripeAdapter<\/code> that implement the <code class=\"language-plaintext highlighter-rouge\">PaymentAdapterInterface<\/code> and translate the API of the payment gateway to the common interface.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">PayPalAdapter<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">PaymentAdapterInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">private<\/span> <span class=\"nv\">$payPalGateway<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">PayPalGateway<\/span> <span class=\"nv\">$payPalGateway<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">payPalGateway<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$payPalGateway<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">processPayment<\/span><span class=\"p\">(<\/span><span class=\"kt\">float<\/span> <span class=\"nv\">$amount<\/span><span class=\"p\">):<\/span> <span class=\"kt\">bool<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">payPalGateway<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">sendPayment<\/span><span class=\"p\">(<\/span><span class=\"nv\">$amount<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">StripeAdapter<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">PaymentAdapterInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">private<\/span> <span class=\"nv\">$stripeGateway<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">StripeGateway<\/span> <span class=\"nv\">$stripeGateway<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">stripeGateway<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$stripeGateway<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">processPayment<\/span><span class=\"p\">(<\/span><span class=\"kt\">float<\/span> <span class=\"nv\">$amount<\/span><span class=\"p\">):<\/span> <span class=\"kt\">bool<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">stripeGateway<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">charge<\/span><span class=\"p\">(<\/span><span class=\"nv\">$amount<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Now we can use these adapters in our payment system to process payments from different payment gateways:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nv\">$payPalGateway<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">PayPalGateway<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$payPalAdapter<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">PayPalAdapter<\/span><span class=\"p\">(<\/span><span class=\"nv\">$payPalGateway<\/span><span class=\"p\">);<\/span>\n<span class=\"nv\">$payPalAdapter<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">processPayment<\/span><span class=\"p\">(<\/span><span class=\"mf\">100.00<\/span><span class=\"p\">);<\/span>\n\n<span class=\"nv\">$stripeGateway<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">StripeGateway<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$stripeAdapter<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">StripeAdapter<\/span><span class=\"p\">(<\/span><span class=\"nv\">$stripeGateway<\/span><span class=\"p\">);<\/span>\n<span class=\"nv\">$stripeAdapter<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">processPayment<\/span><span class=\"p\">(<\/span><span class=\"mf\">100.00<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Using an Adapter pattern, we can easily integrate various payment gateways into your system.<\/p>\n"},{"title":"Enhance Your PHP Code with Decorator Design Pattern","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/enhance-your-php-code-with-decorator-design-pattern"}},"updated":"2023-02-08T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/enhance-your-php-code-with-decorator-design-pattern","content":"<p>The Decorator Design Pattern is a design pattern that is used to extend the behavior of an object dynamically, without changing its class.\nIt is a structural pattern that can be used to add responsibilities to individual objects, instead of creating a new subclass.<\/p>\n\n<p>The Decorator design pattern can be implemented by creating an interface or abstract class that defines the basic methods that must be implemented by all concrete decorators.\nThe concrete decorators must inherit from the interface or abstract class and implement the necessary methods.\nTo use a decorator, an object of the decorated class is passed to the constructor of the concrete decorator.\nThe concrete decorator can then add or change the behavior of the decorated object.<\/p>\n\n<p>The Decorator Design Pattern can be useful in several different contexts.\nFor example, if you have a basic object, like a cup of coffee, and you want to add different types of flavors to it, such as whipped cream or chocolate syrup, the Decorator Design Pattern can be used.<\/p>\n\n<p>Let\u2019s consider an example to understand the Decorator Design Pattern.<\/p>\n\n<p>First, we create the <code class=\"language-plaintext highlighter-rouge\">Coffee<\/code> interface with two methods: <code class=\"language-plaintext highlighter-rouge\">getCost<\/code> and <code class=\"language-plaintext highlighter-rouge\">getDescription<\/code>.\nWe also create a <code class=\"language-plaintext highlighter-rouge\">SimpleCoffee<\/code> class that implements the <code class=\"language-plaintext highlighter-rouge\">Coffee<\/code> interface.\nThis class represents the basic functions of an object.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">interface<\/span> <span class=\"nc\">Coffee<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">getCost<\/span><span class=\"p\">():<\/span> <span class=\"kt\">int<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">getDescription<\/span><span class=\"p\">():<\/span> <span class=\"kt\">string<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">SimpleCoffee<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">Coffee<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">getCost<\/span><span class=\"p\">():<\/span> <span class=\"kt\">int<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"mi\">10<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">getDescription<\/span><span class=\"p\">():<\/span> <span class=\"kt\">string<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"s1\">'Simple Coffee'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>We then create an abstract <code class=\"language-plaintext highlighter-rouge\">CoffeeDecorator<\/code> class that implements the <code class=\"language-plaintext highlighter-rouge\">Coffee<\/code> interface and takes an instance of the <code class=\"language-plaintext highlighter-rouge\">Coffee<\/code> interface as a parameter.\nThis class is used as the base class for concrete decorator classes.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">abstract<\/span> <span class=\"kd\">class<\/span> <span class=\"nc\">CoffeeDecorator<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">Coffee<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">protected<\/span> <span class=\"nv\">$decoratedCoffee<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">Coffee<\/span> <span class=\"nv\">$decoratedCoffee<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">decoratedCoffee<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$decoratedCoffee<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Finally, we create two concrete decorator classes, <code class=\"language-plaintext highlighter-rouge\">MilkCoffee<\/code> and <code class=\"language-plaintext highlighter-rouge\">CreamCoffee<\/code>, which extend from the <code class=\"language-plaintext highlighter-rouge\">CoffeeDecorator<\/code> class.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">MilkCoffee<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">CoffeeDecorator<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">private<\/span> <span class=\"k\">const<\/span> <span class=\"no\">PRICE<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">2<\/span><span class=\"p\">;<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">getCost<\/span><span class=\"p\">():<\/span> <span class=\"kt\">int<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">decoratedCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getCost<\/span><span class=\"p\">()<\/span> <span class=\"o\">+<\/span> <span class=\"k\">self<\/span><span class=\"o\">::<\/span><span class=\"no\">PRICE<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">getDescription<\/span><span class=\"p\">():<\/span> <span class=\"kt\">string<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">decoratedCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getDescription<\/span><span class=\"p\">()<\/span> <span class=\"mf\">.<\/span> <span class=\"s1\">', milk'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">CreamCoffee<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">CoffeeDecorator<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">private<\/span> <span class=\"k\">const<\/span> <span class=\"no\">PRICE<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">5<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">getCost<\/span><span class=\"p\">():<\/span> <span class=\"kt\">int<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">decoratedCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getCost<\/span><span class=\"p\">()<\/span> <span class=\"o\">+<\/span> <span class=\"k\">self<\/span><span class=\"o\">::<\/span><span class=\"no\">PRICE<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">getDescription<\/span><span class=\"p\">():<\/span> <span class=\"kt\">string<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">decoratedCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getDescription<\/span><span class=\"p\">()<\/span> <span class=\"mf\">.<\/span> <span class=\"s1\">', cream'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Now let\u2019s look at an example of calling classes<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">\/\/ Order simple coffee<\/span>\n<span class=\"nv\">$simpleCoffee<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">SimpleCoffee<\/span><span class=\"p\">();<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$simpleCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getCost<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: 10<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$simpleCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getDescription<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: Simple Coffee<\/span>\n\n<span class=\"c1\">\/\/ Order coffee with milk<\/span>\n<span class=\"nv\">$milkCoffee<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">MilkCoffee<\/span><span class=\"p\">(<\/span><span class=\"nv\">$simpleCoffee<\/span><span class=\"p\">);<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$milkCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getCost<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: 12 (SimpleCoffee cost + MilkCoffee cost)<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$milkCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getDescription<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: Simple Coffee, milk<\/span>\n\n<span class=\"c1\">\/\/ Order coffee with cream<\/span>\n<span class=\"nv\">$creamCoffee<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">CreamCoffee<\/span><span class=\"p\">(<\/span><span class=\"nv\">$simpleCoffee<\/span><span class=\"p\">);<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$creamCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getCost<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: 15 (SimpleCoffee cost + CreamCoffee cost)<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$creamCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getDescription<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: Simple Coffee, cream<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>What if we want to order coffee with milk and cream?\nThen we need to wrap one order in both decorators<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">\/\/ Order simple coffee<\/span>\n<span class=\"nv\">$simpleCoffee<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">SimpleCoffee<\/span><span class=\"p\">();<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$simpleCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getCost<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: 10<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$simpleCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getDescription<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: Simple Coffee<\/span>\n\n<span class=\"c1\">\/\/ Order coffee with milk<\/span>\n<span class=\"nv\">$milkCoffee<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">MilkCoffee<\/span><span class=\"p\">(<\/span><span class=\"nv\">$simpleCoffee<\/span><span class=\"p\">);<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$milkCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getCost<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: 12 (SimpleCoffee cost + MilkCoffee cost)<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$milkCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getDescription<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: Simple Coffee, milk<\/span>\n\n<span class=\"c1\">\/\/ Order coffee with milk and cream<\/span>\n<span class=\"c1\">\/\/ We create CreamCoffee from $milkCoffee because it contains both coffee and milk<\/span>\n<span class=\"nv\">$mixCoffee<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">CreamCoffee<\/span><span class=\"p\">(<\/span><span class=\"nv\">$milkCoffee<\/span><span class=\"p\">);<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$mixCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getCost<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: 17 (SimpleCoffee cost + MilkCoffee cost + CreamCoffee cost)<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$mixCoffee<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getDescription<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ output: Simple Coffee, milk, cream<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Advantages of using the Decorator Design Pattern:<\/p>\n\n<ul>\n  <li>The Decorator design pattern allows you to extend the functionalities of existing objects in a flexible and easy-to-maintain way.<\/li>\n  <li>It allows you to add new behaviors and responsibilities to an object dynamically, without affecting the behavior of other objects from the same class.<\/li>\n  <li>The Decorator design pattern is a good alternative to inheritance when you want to add new functionalities to an object, but do not want to modify the source code of the original object.<\/li>\n  <li>It allows you to keep the implementation of the original object separate from the implementation of the new functionalities.<\/li>\n<\/ul>\n"},{"title":"Mastering the Strategy Design Pattern in PHP","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/mastering-the-strategy-design-pattern-in-php"}},"updated":"2023-01-25T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/mastering-the-strategy-design-pattern-in-php","content":"<p>The strategy design pattern is a behavioral design pattern that allows an object to change its behavior based on a given context.\nThe pattern involves separating an object\u2019s behavior into different strategies and allowing the object to switch between these strategies at runtime.\nThis allows for greater flexibility and maintainability in the code, as the behavior of the object can be changed without modifying the object itself.<\/p>\n\n<p>In PHP, the strategy design pattern can be implemented by creating an interface or abstract class that defines the behavior that all strategies must have.\nConcrete classes are then created that implement this interface or extend the abstract class, providing the specific implementation for each strategy.<\/p>\n\n<p>To illustrate this pattern, let\u2019s consider an example of a shopping cart that can calculate the total cost of the items in it.\nDifferent strategies can be used to calculate the total cost, such as using a discount code, calculating shipping costs, or applying taxes.<\/p>\n\n<p>First, we can create an interface for the strategy, which defines the methods that all strategies must implement.\nIn this example, the strategy interface is called <code class=\"language-plaintext highlighter-rouge\">CalculateTotalCostStrategy<\/code> and it has only one method <code class=\"language-plaintext highlighter-rouge\">calculate()<\/code>:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">interface<\/span> <span class=\"nc\">CalculateTotalCostStrategy<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">calculate<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$items<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>We can then create concrete classes that implement this strategy.\nFor example, one concrete strategy can be called <code class=\"language-plaintext highlighter-rouge\">DiscountCodeStrategy<\/code>, which applies a discount code to the total cost:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">DiscountCodeStrategy<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">CalculateTotalCostStrategy<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">calculate<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$items<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nv\">$discount<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">10<\/span><span class=\"p\">;<\/span>\n        <span class=\"c1\">\/\/ logic to apply discount code<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nb\">array_sum<\/span><span class=\"p\">(<\/span><span class=\"nv\">$items<\/span><span class=\"p\">)<\/span> <span class=\"o\">-<\/span> <span class=\"nv\">$discount<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Another concrete strategy can be called <code class=\"language-plaintext highlighter-rouge\">ShippingCostStrategy<\/code>, which calculates shipping costs for the items:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">ShippingCostStrategy<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">CalculateTotalCostStrategy<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">calculate<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$items<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nv\">$shippingCost<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">10<\/span><span class=\"p\">;<\/span>\n        <span class=\"c1\">\/\/ logic to calculate shipping costs<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nb\">array_sum<\/span><span class=\"p\">(<\/span><span class=\"nv\">$items<\/span><span class=\"p\">)<\/span> <span class=\"o\">+<\/span> <span class=\"nv\">$shippingCost<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>We can also create a context class, which is the class that will change its behavior based on the strategy selected.\nThe context class will have a property <code class=\"language-plaintext highlighter-rouge\">strategy<\/code> that will hold the current strategy.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">ShoppingCart<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">private<\/span> <span class=\"nv\">$strategy<\/span><span class=\"p\">;<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">CalculateTotalCostStrategy<\/span> <span class=\"nv\">$strategy<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">strategy<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$strategy<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">calculateTotalCost<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$items<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">strategy<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">calculate<\/span><span class=\"p\">(<\/span><span class=\"nv\">$items<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Once the context class, interface and the concrete strategies are defined, we can use them to create the objects and switch between strategies at runtime.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nv\">$items<\/span> <span class=\"o\">=<\/span> <span class=\"k\">array<\/span><span class=\"p\">(<\/span><span class=\"mi\">10<\/span><span class=\"p\">,<\/span> <span class=\"mi\">20<\/span><span class=\"p\">,<\/span> <span class=\"mi\">30<\/span><span class=\"p\">);<\/span>\n\n<span class=\"nv\">$shoppingCart<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">ShoppingCart<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"nc\">DiscountCodeStrategy<\/span><span class=\"p\">());<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$shoppingCart<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">calculateTotalCost<\/span><span class=\"p\">(<\/span><span class=\"nv\">$items<\/span><span class=\"p\">);<\/span>\n<span class=\"c1\">\/\/ output: 50 (total cost of items - discount)<\/span>\n\n<span class=\"nv\">$shoppingCart<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">ShoppingCart<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"nc\">ShippingCostStrategy<\/span><span class=\"p\">());<\/span>\n<span class=\"k\">echo<\/span> <span class=\"nv\">$shoppingCart<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">calculateTotalCost<\/span><span class=\"p\">(<\/span><span class=\"nv\">$items<\/span><span class=\"p\">);<\/span>\n<span class=\"c1\">\/\/ output: 70 (total cost of items + shipping cost)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>This is a simple example of how the strategy pattern can be implemented<\/p>\n"},{"title":"Abstract Factory Pattern in PHP","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/abstract-factory-pattern-in-php"}},"updated":"2023-01-12T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/abstract-factory-pattern-in-php","content":"<p>The Abstract Factory pattern is a design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes.\nIt allows for the creation of objects that follow a certain pattern, without the need to specify the exact class of the object to be created.<\/p>\n\n<p>The Abstract Factory pattern can be implemented in PHP using interfaces and abstract classes.\nThe interface or abstract class defines a set of methods that must be implemented by concrete factory classes, which are responsible for creating the actual objects.<\/p>\n\n<p>First, consider an example with an interface:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">interface<\/span> <span class=\"nc\">CarFactory<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createCar<\/span><span class=\"p\">():<\/span> <span class=\"kt\">Car<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createTruck<\/span><span class=\"p\">():<\/span> <span class=\"kt\">Truck<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<span class=\"kd\">interface<\/span> <span class=\"nc\">Car<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"kd\">class<\/span> <span class=\"nc\">Sedan<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">Car<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"kd\">class<\/span> <span class=\"nc\">SUV<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">Car<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"kd\">interface<\/span> <span class=\"nc\">Truck<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"kd\">class<\/span> <span class=\"nc\">PickupTruck<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">Truck<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"kd\">class<\/span> <span class=\"nc\">BoxTruck<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">Truck<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">FamilyCarFactory<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">CarFactory<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createCar<\/span><span class=\"p\">():<\/span> <span class=\"kt\">Sedan<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Sedan<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createTruck<\/span><span class=\"p\">():<\/span> <span class=\"kt\">PickupTruck<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">PickupTruck<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">LuxuryCarFactory<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">CarFactory<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createCar<\/span><span class=\"p\">():<\/span> <span class=\"kt\">SUV<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">SUV<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createTruck<\/span><span class=\"p\">():<\/span> <span class=\"kt\">BoxTruck<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">BoxTruck<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"nv\">$familyCarFactory<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">FamilyCarFactory<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$sedan<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$familyCarFactory<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">createCar<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$pickupTruck<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$familyCarFactory<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">createTruck<\/span><span class=\"p\">();<\/span>\n\n<span class=\"nv\">$luxuryCarFactory<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">LuxuryCarFactory<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$suv<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$luxuryCarFactory<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">createCar<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$boxTruck<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$luxuryCarFactory<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">createTruck<\/span><span class=\"p\">();<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>In this example, <code class=\"language-plaintext highlighter-rouge\">CarFactory<\/code> is an interface with two methods <code class=\"language-plaintext highlighter-rouge\">createCar()<\/code> and <code class=\"language-plaintext highlighter-rouge\">createTruck()<\/code> that need to be implemented by concrete factories.\nThese methods will create an object of a certain class that implements the <code class=\"language-plaintext highlighter-rouge\">Car<\/code> and <code class=\"language-plaintext highlighter-rouge\">Truck<\/code> interface respectively.<\/p>\n\n<p>The main benefit of using the Abstract Factory pattern in this scenario is that it allows for a separation of concerns between the classes that create objects and the classes that use them.\nThe <code class=\"language-plaintext highlighter-rouge\">CarFactory<\/code> interface defines the contract for creating cars and trucks, while the concrete factory classes are responsible for creating the actual objects.<\/p>\n\n<p>By using this pattern, we can easily swap out the concrete factory classes to create different types of cars and trucks, without having to modify the code that uses them.\nFor example, we can have different implementations of the <code class=\"language-plaintext highlighter-rouge\">CarFactory<\/code> such as <code class=\"language-plaintext highlighter-rouge\">FamilyCarFactory<\/code> and <code class=\"language-plaintext highlighter-rouge\">LuxuryCarFactory<\/code>,\nwhere <code class=\"language-plaintext highlighter-rouge\">FamilyCarFactory<\/code> can create <code class=\"language-plaintext highlighter-rouge\">Sedan<\/code> and <code class=\"language-plaintext highlighter-rouge\">PickupTruck<\/code> and <code class=\"language-plaintext highlighter-rouge\">LuxuryCarFactory<\/code> can create <code class=\"language-plaintext highlighter-rouge\">SUV<\/code> and <code class=\"language-plaintext highlighter-rouge\">BoxTruck<\/code>.<\/p>\n\n<p>We could also use an abstract factory to create different car factories that creates different type of fuel-based cars such as electric cars factory,\npetrol cars factory and diesel cars factory. This way we can create a whole family of related objects based on a certain category with a single factory class.<\/p>\n\n<p>Now consider an example using an abstract class:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">abstract<\/span> <span class=\"kd\">class<\/span> <span class=\"nc\">CarFactory<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">abstract<\/span> <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createCar<\/span><span class=\"p\">():<\/span> <span class=\"kt\">Car<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">abstract<\/span> <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createTruck<\/span><span class=\"p\">():<\/span> <span class=\"kt\">Truck<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"k\">abstract<\/span> <span class=\"kd\">class<\/span> <span class=\"nc\">Car<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">abstract<\/span> <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">drive<\/span><span class=\"p\">();<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"k\">abstract<\/span> <span class=\"kd\">class<\/span> <span class=\"nc\">Truck<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">abstract<\/span> <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">load<\/span><span class=\"p\">();<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">ElectricCar<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Car<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">drive<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ code to drive electric car<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<span class=\"kd\">class<\/span> <span class=\"nc\">PetrolCar<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Car<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">drive<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ code to drive petrol car<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<span class=\"kd\">class<\/span> <span class=\"nc\">ElectricTruck<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Truck<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">load<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ code to load electric truck<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<span class=\"kd\">class<\/span> <span class=\"nc\">PetrolTruck<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Truck<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">load<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ code to load petrol truck<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">ElectricCarFactory<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">CarFactory<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createCar<\/span><span class=\"p\">():<\/span> <span class=\"kt\">ElectricCar<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">ElectricCar<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createTruck<\/span><span class=\"p\">():<\/span> <span class=\"kt\">ElectricTruck<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">ElectricTruck<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<span class=\"kd\">class<\/span> <span class=\"nc\">PetrolCarFactory<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">CarFactory<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createCar<\/span><span class=\"p\">():<\/span> <span class=\"kt\">PetrolCar<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">PetrolCar<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createTruck<\/span><span class=\"p\">():<\/span> <span class=\"kt\">PetrolTruck<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">PetrolTruck<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"nv\">$electricCarFactory<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">ElectricCarFactory<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$electricCar<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$electricCarFactory<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">createCar<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$electricCar<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">drive<\/span><span class=\"p\">();<\/span>\n\n<span class=\"nv\">$petrolCarFactory<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">PetrolCarFactory<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$petrolCar<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$petrolCarFactory<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">createCar<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$petrolCar<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">drive<\/span><span class=\"p\">();<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>In this example, the <code class=\"language-plaintext highlighter-rouge\">CarFactory<\/code> abstract class defines two methods, <code class=\"language-plaintext highlighter-rouge\">createCar()<\/code> and <code class=\"language-plaintext highlighter-rouge\">createTruck()<\/code>, that must be implemented by concrete factory classes.\nThe <code class=\"language-plaintext highlighter-rouge\">ElectricCarFactory<\/code> and <code class=\"language-plaintext highlighter-rouge\">PetrolCarFactory<\/code> classes implement these methods and return new objects of the <code class=\"language-plaintext highlighter-rouge\">ElectricCar<\/code>, <code class=\"language-plaintext highlighter-rouge\">PetrolCar<\/code>, <code class=\"language-plaintext highlighter-rouge\">ElectricTruck<\/code> and <code class=\"language-plaintext highlighter-rouge\">PetrolTruck<\/code> classes.<\/p>\n\n<p>You can see that the abstract class of CarFactory defines the contract and structure of the factory, while the concrete factory classes are responsible for creating the actual objects of the Car and Truck.<\/p>\n\n<p>Using abstract classes also provides an opportunity for sharing common functionality between concrete factories. The abstract class can provide a default implementation for some of the methods, which can be overridden by the concrete classes if needed.<\/p>\n\n<p>In summary, The Abstract Factory pattern is a powerful tool that allows for the creation of families of related objects in a flexible and maintainable way.\nBy using interfaces and abstract classes to define the creation methods, the concrete classes can be easily swapped out.\nUsing an abstract class allows for providing a default implementation and share common functionality between concrete factories.<\/p>\n"},{"title":"Queues in Laravel","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/queues-in-laravel"}},"updated":"2022-11-14T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/queues-in-laravel","content":"<p>Sometimes individual processes take a long time to complete, such as sending email, payment gateway, etc.\nWhen you send an email for verification, it takes time.\nIf you don\u2019t want to make the user wait, then you need to use queues.\nThis will make your service fast for the user.<\/p>\n\n<p>To work with queues in Laravel, it is enough to know and be able to execute a few commands:<\/p>\n\n<ul>\n  <li>Create a queue handler: <code class=\"language-plaintext highlighter-rouge\">php artisan make:job ProcessSendingEmail<\/code><\/li>\n  <li>Send a new event to the queue: <code class=\"language-plaintext highlighter-rouge\">ProcessSendingEmail::dispatch($user);<\/code><\/li>\n  <li>And run the handler for all events: <code class=\"language-plaintext highlighter-rouge\">php artisan queue:work<\/code><\/li>\n<\/ul>\n\n<p>As simple as possible, right? Let\u2019s now look in more detail.<\/p>\n\n<h2>Principle of operation<\/h2>\n\n<p>The principle of operation of queues consists of two main components:<\/p>\n\n<ul>\n  <li>queue servers;<\/li>\n  <li>handler;<\/li>\n<\/ul>\n\n<p>The queue server keeps a list of messages (or tasks, job queue) that the main application sends to it.\nA task is simply information about what needs to be done and how.<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/queues-in-laravel\/image1.jpeg\" alt=\"Sending code to the queue handler\" \/>\n<\/div>\n\n<p>A handler (or worker) is a part of the main program that works with the queue in the opposite direction.\nIt receives new messages from the queue and performs the appropriate actions.<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/queues-in-laravel\/image2.jpeg\" alt=\"Code handle\" \/>\n<\/div>\n\n<h2>Example<\/h2>\n\n<p>Let\u2019s imagine a simple registration form with one email field and a \u201cRegister\u201d button.\nBy clicking on the button, we send the data to the server and check if we have a user with such an email in the database or not,\nif so, we will send a message to the form that the user already exists, and if not,\nwe will send him an email to the specified email to confirm it.\nTo send an email, we have 2 options:<\/p>\n\n<ul>\n  <li>send synchronously within a single request;<\/li>\n  <li>add a task to send an email to the queue;<\/li>\n<\/ul>\n\n<p>In fact, there is no right answer, you need to look at the specific situation.\nIf you have a small project, you have several people registering per hour and it is non-critical if they wait 5-10 seconds for a request to be processed,\nthen the first option with synchronous sending of a letter suits you. But in most cases it is better to use a queue.\nTo do this, let\u2019s go back to the beginning of the article and follow a couple of simple steps:<\/p>\n\n<h3>1. Create a queue handler<\/h3>\n\n<p>Execute the command<\/p>\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">php<\/span> <span class=\"n\">artisan<\/span> <span class=\"n\">make<\/span><span class=\"o\">:<\/span><span class=\"n\">job<\/span> <span class=\"nc\">ProcessSendingEmail<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>All default handlers are created in <code class=\"language-plaintext highlighter-rouge\">app\/Jobs<\/code>.\nOpen the created <code class=\"language-plaintext highlighter-rouge\">app\/Jobs\/ProcessSendingEmail.php<\/code> file and update the handle function:<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">handle<\/span><span class=\"p\">(<\/span><span class=\"kt\">User<\/span> <span class=\"nv\">$user<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"nc\">Mail<\/span><span class=\"o\">::<\/span><span class=\"nf\">send<\/span><span class=\"p\">(<\/span>\n        <span class=\"s1\">'mail.confirm-registration'<\/span><span class=\"p\">,<\/span>\n        <span class=\"p\">[<\/span>\n            <span class=\"s1\">'html'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">'Confirm your email using the link - https:\/\/kongulov.dev'<\/span>\n        <span class=\"p\">],<\/span>\n        <span class=\"k\">function<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$message<\/span><span class=\"p\">)<\/span> <span class=\"k\">use<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$user<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"nv\">$message<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">to<\/span><span class=\"p\">(<\/span><span class=\"nv\">$user<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">email<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">subject<\/span><span class=\"p\">(<\/span><span class=\"s1\">'Confirmation of registration'<\/span><span class=\"p\">);<\/span>\n        <span class=\"p\">}<\/span>\n    <span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Now our handler receives the user model and sends him a letter using the standard Mail package in Laravel,\nyou can familiarize yourself with its capabilities in the <a href=\"https:\/\/laravel.com\/docs\/9.x\/mail\" target=\"_blank\">documentation<\/a>.<\/p>\n\n<h3>2. Send a new event to the queue<\/h3>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">register<\/span><span class=\"p\">(<\/span><span class=\"kt\">Request<\/span> <span class=\"nv\">$request<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ .... code<\/span>\n    <span class=\"nc\">ProcessSendingEmail<\/span><span class=\"o\">::<\/span><span class=\"nf\">dispatch<\/span><span class=\"p\">(<\/span><span class=\"nv\">$user<\/span><span class=\"p\">);<\/span>\n    <span class=\"c1\">\/\/ .... code<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>After calling the <code class=\"language-plaintext highlighter-rouge\">dispatch<\/code> function, a new event will immediately fly to our queue,\nand we just have to run our queue handler and wait for the letter to be sent to the user.<\/p>\n\n<h3>3. Run the handler for all events in the console with the command<\/h3>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">php<\/span> <span class=\"n\">artisan<\/span> <span class=\"n\">queue<\/span><span class=\"o\">:<\/span><span class=\"n\">work<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>After the handler is launched, all our events will be processed one by one, and if we had 100 letters to send in the queue,\nthen the last letter will obviously not be sent soon and will be approximately like in the first picture, when everyone is waiting in line.<\/p>\n\n<p>Luckily, we can solve this problem very easily by running multiple handlers with <a href=\"https:\/\/kongulov.dev\/blog\/install-and-configure-supervisor-for-laravel-queue\">Supervisor<\/a> and our emails will be sent in parallel.\nOf course, we must be careful with the choice of the number of handlers,\nbecause each will occupy the resources of our server and the optimal number must be selected from our capabilities,\nbut remember that the more handlers, the faster all our messages will be processed.<\/p>\n\n"},{"title":"Events and Listeners in Laravel","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/events-and-listeners-in-laravel"}},"updated":"2022-10-18T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/events-and-listeners-in-laravel","content":"<p>Laravel Events provides a simple implementation of the Observer pattern, allowing you to subscribe to and monitor various events that occur in your application.\nEvent classes are usually stored in the <code class=\"language-plaintext highlighter-rouge\">app\/Events<\/code> directory and their listeners in <code class=\"language-plaintext highlighter-rouge\">app\/Listeners<\/code>.<\/p>\n\n<p>The advantage of this pattern is to separate the different logic in your application.\nIn this case, one event can have many independent listeners.\nFor example, you want to be notified every time that you have a new registered user on the site.\nTo do this, you do not need to make changes to the user registration class or extend it in any way.\nIt is enough to create a class of an independent event listener \u201cRegistration\u201d (subscribe to the event), inside which the notification logic will be implemented.<\/p>\n\n<h2>What is an Event?<\/h2>\n\n<p>Events are the ways we hook into our application\u2019s activity, it\u2019s just a way to observe the activity, such as login, you can create a class to monitor the login activity, when the user logs in, the event class can perform some functions.<\/p>\n\n<h2>What is a Listener?<\/h2>\n\n<p>A listener is a class that listens to the events they are associated with and performs a task, that is, they perform the given task for the event.\nLet me illustrate. You might want to send a welcome email to a new user of your application and assign a role to the user based on the information provided during registration, etc.\nYou wouldn\u2019t want to do all of this in the <code class=\"language-plaintext highlighter-rouge\">RegisterController<\/code> because we are violating the first SOLID (<a href=\"https:\/\/kongulov.dev\/blog\/solid-single-responsibility-principle\" target=\"_blank\">Single Responsibility Principle<\/a>).\nWhen the Controller will perform more than one task, the RegisterController should only perform the actions of registering a new user.\nThus, the event must be held during the registration process, which includes assigning a role, sending an email, etc.\nThey are individual listeners within the event.<\/p>\n\n<h2>Creating Event and Listener class<\/h2>\n\n<p>To create an event class, use the artisan command <code class=\"language-plaintext highlighter-rouge\">make:event<\/code><\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">php<\/span> <span class=\"n\">artisan<\/span> <span class=\"n\">make<\/span><span class=\"o\">:<\/span><span class=\"n\">event<\/span> <span class=\"nc\">Register<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>This command will create a new class in your application\u2019s <code class=\"language-plaintext highlighter-rouge\">app\\Events<\/code> folder, and that\u2019s all you need to create an event class.<\/p>\n\n<p>To create a listener class, use the artisan command <code class=\"language-plaintext highlighter-rouge\">make:listener<\/code><\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">php<\/span> <span class=\"n\">artisan<\/span> <span class=\"n\">make<\/span><span class=\"o\">:<\/span><span class=\"n\">listener<\/span> <span class=\"nc\">SendWelcomeEmail<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>This command, just like creating an event, will create a new class in your application\u2019s <code class=\"language-plaintext highlighter-rouge\">app\\Listeners<\/code> folder, which is all you need to create a listener class.<\/p>\n\n<h2>Registering Event and Listener class<\/h2>\n\n<p>In order for our events and listeners to work, we must register them in the <code class=\"language-plaintext highlighter-rouge\">App\\Providers\\EventServiceProvider<\/code> class, which was already set up for us during the installation of our Laravel project.<\/p>\n\n<p>looking into the <code class=\"language-plaintext highlighter-rouge\">App\\Providers\\EventServiceProvider<\/code> class you will see the <code class=\"language-plaintext highlighter-rouge\">$listen<\/code> array in which we will register our events and listeners.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Providers<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">EventServiceProvider<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">ServiceProvider<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">protected<\/span> <span class=\"nv\">$listen<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span>\n        <span class=\"nc\">Register<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">[<\/span>\n            <span class=\"nc\">SendWelcomeEmail<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n        <span class=\"p\">],<\/span>\n    <span class=\"p\">];<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Let\u2019s take a look at our <code class=\"language-plaintext highlighter-rouge\">Register<\/code> event and pass our new user into it<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n \n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Events<\/span><span class=\"p\">;<\/span>\n \n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Models\\User<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Broadcasting\\InteractsWithSockets<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Foundation\\Events\\Dispatchable<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Queue\\SerializesModels<\/span><span class=\"p\">;<\/span>\n \n<span class=\"kd\">class<\/span> <span class=\"nc\">Register<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"kn\">use<\/span> <span class=\"nc\">Dispatchable<\/span><span class=\"p\">,<\/span> <span class=\"nc\">InteractsWithSockets<\/span><span class=\"p\">,<\/span> <span class=\"nc\">SerializesModels<\/span><span class=\"p\">;<\/span>\n \n    <span class=\"cd\">\/**\n     * The order instance.\n     *\n     * @var \\App\\Models\\User\n     *\/<\/span>\n    <span class=\"k\">public<\/span> <span class=\"nv\">$user<\/span><span class=\"p\">;<\/span>\n \n    <span class=\"cd\">\/**\n     * Create a new event instance.\n     *\n     * @param  \\App\\Models\\User  $user\n     * @return void\n     *\/<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">User<\/span> <span class=\"nv\">$user<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">user<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$user<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>And now let\u2019s look at our listener <code class=\"language-plaintext highlighter-rouge\">SendWelcomeEmail<\/code> where all the logic of sending email will be<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n \n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Listeners<\/span><span class=\"p\">;<\/span>\n \n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Events\\Register<\/span><span class=\"p\">;<\/span>\n \n<span class=\"kd\">class<\/span> <span class=\"nc\">SendWelcomeEmail<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"cd\">\/**\n     * Create the event listener.\n     *\n     * @return void\n     *\/<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/<\/span>\n    <span class=\"p\">}<\/span>\n \n    <span class=\"cd\">\/**\n     * Handle the event.\n     *\n     * @param  \\App\\Events\\Register  $event\n     * @return void\n     *\/<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">handle<\/span><span class=\"p\">(<\/span><span class=\"kt\">Register<\/span> <span class=\"nv\">$event<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ Access the user using $event-&gt;user...<\/span>\n        <span class=\"c1\">\/\/ email sending logic for $event-&gt;user-&gt;email<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h2>Dispatching an event<\/h2>\n\n<p>At the time of this writing, I was aware of two methods for dispatching your event and triggering listeners:<\/p>\n\n<ul>\n  <li>event(new EventClass()); \/\/ event(new Register($user));<\/li>\n  <li>EventClass::dispatch(); \/\/ Register::dispatch($user);<\/li>\n<\/ul>\n\n<p>You should note that public properties declared on the event class can be accessed on the listener class that is associated with it.<\/p>\n"},{"title":"Database transactions in Laravel","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/database-transactions-in-laravel"}},"updated":"2022-10-03T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/database-transactions-in-laravel","content":"<p>In web development, data integrity and accuracy are important.\nTherefore, we need to be sure that we are writing code that securely stores, updates, and deletes data in our databases.\nIn this article, we\u2019ll take a look at what database transactions are, why they\u2019re important, and how to get started using them in Laravel.\nWe will also look at typical problems associated with third-party services and database transactions.<\/p>\n\n<h2>What are database transactions<\/h2>\n\n<p>Before we get started with transactions in Laravel, let\u2019s take a look at what they are and how they are useful.<\/p>\n\n<p>A transaction is an archive for database queries. It protects your data thanks to the all-or-nothing principle.<\/p>\n\n<p>Let\u2019s say you transfer money from one account to another. In the application, it looks like several operations<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">UPDATE<\/span> <span class=\"nv\">`wallets`<\/span> <span class=\"k\">SET<\/span> <span class=\"nv\">`amount`<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">`amount`<\/span> <span class=\"o\">-<\/span> <span class=\"mi\">100<\/span> <span class=\"k\">WHERE<\/span> <span class=\"nv\">`id`<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">UPDATE<\/span> <span class=\"nv\">`wallets`<\/span> <span class=\"k\">SET<\/span> <span class=\"nv\">`amount`<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">`amount`<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">100<\/span> <span class=\"k\">WHERE<\/span> <span class=\"nv\">`id`<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">2<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>What if one request succeeds and the other fails? Then the integrity of the data will be violated.\nTo avoid such situations, the DBMS introduced the concept of a transaction - an atomic impact on data.\nThat is, the transfer of the database from one holistic state to another.\nIn other words, we include several requests in the transaction, which must all be executed, but if at least one is not executed, then all the requests included in the transaction will not be executed.\nThis is the all-or-nothing principle.<\/p>\n\n<h2>Using database transactions in Laravel<\/h2>\n\n<p>Now that we have an idea about transactions, let\u2019s look at how to use them in Laravel.<\/p>\n\n<p>First, let\u2019s see what we have in the <code class=\"language-plaintext highlighter-rouge\">wallets<\/code> table<\/p>\n\n<pre>\n| id | amount |\n|----|--------|\n| 1  | 1000   |\n| 2  | 0      |\n<\/pre>\n<p><br \/>\nI intentionally made a mistake in the <code class=\"language-plaintext highlighter-rouge\">transfer<\/code> method to see the consequences of a data violation.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">transfer<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"nc\">Wallet<\/span><span class=\"o\">::<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">decrement<\/span><span class=\"p\">(<\/span><span class=\"s1\">'amount'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">100<\/span><span class=\"p\">);<\/span>\n    <span class=\"nc\">Wallet<\/span><span class=\"o\">::<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id_'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">increment<\/span><span class=\"p\">(<\/span><span class=\"s1\">'amount'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">100<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>After executing the code, check the database<\/p>\n\n<pre>\n| id | amount |\n|----|--------|\n| 1  | 900    |\n| 2  | 0      |\n<\/pre>\n<p><br \/>\nThe first request passed, but the second one failed.\nAnd in the end: the funds from the first account were gone, but they did not come to the second one.\nData integrity has been violated. To prevent this from happening, you need to use transactions.<\/p>\n\n<p>It\u2019s very easy to get started with transactions in Laravel thanks to the <code class=\"language-plaintext highlighter-rouge\">transaction()<\/code> method, which we can access from the <code class=\"language-plaintext highlighter-rouge\">DB<\/code> facade.\nBased on the previous code example, let\u2019s look at how to use transactions in Laravel.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kn\">use<\/span> <span class=\"no\">Illuminate\\Support\\Facades\\DB<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">transfer<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"no\">DB<\/span><span class=\"o\">::<\/span><span class=\"nf\">transaction<\/span><span class=\"p\">(<\/span><span class=\"k\">function<\/span><span class=\"p\">(){<\/span>\n        <span class=\"nc\">Wallet<\/span><span class=\"o\">::<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">decrement<\/span><span class=\"p\">(<\/span><span class=\"s1\">'amount'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">100<\/span><span class=\"p\">);<\/span>\n        <span class=\"nc\">Wallet<\/span><span class=\"o\">::<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id_'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">increment<\/span><span class=\"p\">(<\/span><span class=\"s1\">'amount'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">100<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ &lt;-- left an error<\/span>\n    <span class=\"p\">});<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Let\u2019s run the code.\nBut now both requests are in a transaction. Therefore, no query should be executed.<\/p>\n\n<pre>\n| id | amount |\n|----|--------|\n| 1  | 1000   |\n| 2  | 0      |\n<\/pre>\n<p><br \/>\nAn error occurred while executing the second request.\nBecause of this, the transaction as a whole failed. The amounts on the wallets have not changed.<\/p>\n\n<p>Let\u2019s fix the <code class=\"language-plaintext highlighter-rouge\">transfer<\/code> method and run the code<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kn\">use<\/span> <span class=\"no\">Illuminate\\Support\\Facades\\DB<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">transfer<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"no\">DB<\/span><span class=\"o\">::<\/span><span class=\"nf\">transaction<\/span><span class=\"p\">(<\/span><span class=\"k\">function<\/span><span class=\"p\">(){<\/span>\n        <span class=\"nc\">Wallet<\/span><span class=\"o\">::<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">decrement<\/span><span class=\"p\">(<\/span><span class=\"s1\">'amount'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">100<\/span><span class=\"p\">);<\/span>\n        <span class=\"nc\">Wallet<\/span><span class=\"o\">::<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">increment<\/span><span class=\"p\">(<\/span><span class=\"s1\">'amount'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">100<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">});<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>After executing the code, check the database<\/p>\n\n<pre>\n| id | amount |\n|----|--------|\n| 1  | 900    |\n| 2  | 100    |\n<\/pre>\n<p><br \/>\nAll requests were completed without errors, so the transaction was successful.\nThe amounts on the wallets have changed.<\/p>\n\n<p>This was a simple example using a closure.\nBut what if you have third-party services whose response is important and should affect an event in the code?\nBecause not all services return exceptions, some just return a boolean.\nTo do this, Laravel has several methods for manually processing transactions.<\/p>\n\n<ul>\n  <li><code class=\"language-plaintext highlighter-rouge\">DB::beginTransaction()<\/code> \u2013 for defining a transaction<\/li>\n  <li><code class=\"language-plaintext highlighter-rouge\">DB::commit()<\/code> \u2013 to execute all queries after <code class=\"language-plaintext highlighter-rouge\">DB::beginTransaction()<\/code><\/li>\n  <li><code class=\"language-plaintext highlighter-rouge\">DB::rollBack()<\/code> \u2013 to cancel all requests after <code class=\"language-plaintext highlighter-rouge\">DB::beginTransaction()<\/code><\/li>\n<\/ul>\n\n<p>Let\u2019s consider them with an example.\nWe have a wallet with a balance of $100, and we have a card with a balance of $50, we want to use both balances to transfer $150 to another wallet.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kn\">use<\/span> <span class=\"nc\">App\\Services\\ThirdPartyService<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"no\">Illuminate\\Support\\Facades\\DB<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">private<\/span> <span class=\"kt\">ThirdPartyService<\/span> <span class=\"nv\">$thirdPartyService<\/span><span class=\"p\">;<\/span>\n    \n<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">ThirdPartyService<\/span> <span class=\"nv\">$thirdPartyService<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">thirdPartyService<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$thirdPartyService<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n    \n<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">transfer<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"no\">DB<\/span><span class=\"o\">::<\/span><span class=\"nf\">transaction<\/span><span class=\"p\">(<\/span><span class=\"k\">function<\/span><span class=\"p\">(){<\/span>\n        <span class=\"nc\">Wallet<\/span><span class=\"o\">::<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">decrement<\/span><span class=\"p\">(<\/span><span class=\"s1\">'amount'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">100<\/span><span class=\"p\">);<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">thirdPartyService<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">withdrawal<\/span><span class=\"p\">(<\/span><span class=\"mi\">50<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ &lt;-- returns false<\/span>\n        <span class=\"nc\">Wallet<\/span><span class=\"o\">::<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">increment<\/span><span class=\"p\">(<\/span><span class=\"s1\">'amount'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">150<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">});<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Data integrity has been violated.\nSince the service does not throw an exception so that the transaction is not completed, but only returns a false value and the code continues to work.\nAs a result, we replenish the balance by 150 without deducting 50 from the card<\/p>\n\n<p>Now we use the above methods to manually use transactions<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kn\">use<\/span> <span class=\"nc\">App\\Services\\ThirdPartyService<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"no\">Illuminate\\Support\\Facades\\DB<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">private<\/span> <span class=\"kt\">ThirdPartyService<\/span> <span class=\"nv\">$thirdPartyService<\/span><span class=\"p\">;<\/span>\n    \n<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">ThirdPartyService<\/span> <span class=\"nv\">$thirdPartyService<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">thirdPartyService<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$thirdPartyService<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n    \n<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">transfer<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"no\">DB<\/span><span class=\"o\">::<\/span><span class=\"nf\">beginTransaction<\/span><span class=\"p\">();<\/span>\n    \n    <span class=\"nc\">Wallet<\/span><span class=\"o\">::<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">decrement<\/span><span class=\"p\">(<\/span><span class=\"s1\">'amount'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">100<\/span><span class=\"p\">);<\/span>\n    \n    <span class=\"k\">if<\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">thirdPartyService<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">withdrawal<\/span><span class=\"p\">(<\/span><span class=\"mi\">50<\/span><span class=\"p\">))<\/span> <span class=\"p\">{<\/span>\n        <span class=\"no\">DB<\/span><span class=\"o\">::<\/span><span class=\"nf\">rollBack<\/span><span class=\"p\">();<\/span>\n        \n        <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n    \n    <span class=\"nc\">Wallet<\/span><span class=\"o\">::<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">increment<\/span><span class=\"p\">(<\/span><span class=\"s1\">'amount'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">150<\/span><span class=\"p\">);<\/span>\n    \n    <span class=\"no\">DB<\/span><span class=\"o\">::<\/span><span class=\"nf\">commit<\/span><span class=\"p\">();<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Thus, if a third-party service returns <code class=\"language-plaintext highlighter-rouge\">false<\/code> to us, then by calling <code class=\"language-plaintext highlighter-rouge\">DB::rollBack()<\/code> we will prevent the execution of requests and preserve the integrity of the data<\/p>\n"},{"title":"Repository Pattern in Laravel - PHP Design Pattern","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/repository-pattern-in-laravel-php-design-pattern"}},"updated":"2022-09-26T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/repository-pattern-in-laravel-php-design-pattern","content":"<p>Repositories are classes or components that contain the logic needed to access data sources.\nRepositories provide centralized functionality for accessing data, allowing better management and separation of the infrastructure or technology used to access data from the domain model.\nIf you\u2019re using an object-relational mapping (ORM) like the Laravel Framework, the code you need to implement is simplified thanks to Eloquent and strong typing.\nThis allows you to focus on the data persistence logic rather than the data access helper functions.<\/p>\n\n<p>Let\u2019s take an example in Laravel.<\/p>\n\n<p>We usually implement the repository pattern with an interface.\nAn interface can reduce dependencies between classes, and the implemented class will use the same functionality as the interface.<\/p>\n\n<p>And so let\u2019s create our <code class=\"language-plaintext highlighter-rouge\">PostRepositoryInterface<\/code> in the <code class=\"language-plaintext highlighter-rouge\">app\/Interfaces\/<\/code> folder<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Interfaces<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">interface<\/span> <span class=\"nc\">PostRepositoryInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">list<\/span><span class=\"p\">();<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">findById<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$postId<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">create<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$details<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">update<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$postId<\/span><span class=\"p\">,<\/span> <span class=\"kt\">array<\/span> <span class=\"nv\">$details<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">delete<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$postId<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>And now let\u2019s create the <code class=\"language-plaintext highlighter-rouge\">PostRepository<\/code> in the <code class=\"language-plaintext highlighter-rouge\">app\/Repositories<\/code> folder which will implements the <code class=\"language-plaintext highlighter-rouge\">PostRepositoryInterface<\/code><\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Repositories<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Interfaces\\PostRepositoryInterface<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Models\\Post<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">PostRepository<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">PostRepositoryInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">list<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nc\">Post<\/span><span class=\"o\">::<\/span><span class=\"nf\">all<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">findById<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$postId<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nc\">Post<\/span><span class=\"o\">::<\/span><span class=\"nf\">query<\/span><span class=\"p\">()<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">findOrFail<\/span><span class=\"p\">(<\/span><span class=\"nv\">$postId<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">create<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$details<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nc\">Post<\/span><span class=\"o\">::<\/span><span class=\"nf\">create<\/span><span class=\"p\">(<\/span><span class=\"nv\">$details<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">update<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$postId<\/span><span class=\"p\">,<\/span> <span class=\"kt\">array<\/span> <span class=\"nv\">$details<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nc\">Post<\/span><span class=\"o\">::<\/span><span class=\"nf\">query<\/span><span class=\"p\">()<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id'<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$postId<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">update<\/span><span class=\"p\">(<\/span><span class=\"nv\">$details<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">delete<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$postId<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nc\">Post<\/span><span class=\"o\">::<\/span><span class=\"nf\">query<\/span><span class=\"p\">()<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">where<\/span><span class=\"p\">(<\/span><span class=\"s1\">'id'<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$postId<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nb\">delete<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Next in our class, through dependency injection, we use our <code class=\"language-plaintext highlighter-rouge\">PostRepositoryInterface<\/code><\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Http\\Controllers\\Api<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Http\\Controllers\\Controller<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Http\\Requests\\Api\\PostCreateRequest<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Http\\Requests\\Api\\PostUpdateRequest<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Interfaces\\PostRepositoryInterface<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">PostController<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Controller<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">private<\/span> <span class=\"kt\">PostRepositoryInterface<\/span> <span class=\"nv\">$postRepository<\/span><span class=\"p\">;<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">PostRepositoryInterface<\/span> <span class=\"nv\">$postRepository<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">postRepository<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$postRepository<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">list<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">postRepository<\/span><span class=\"o\">-&gt;<\/span><span class=\"k\">list<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">findById<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$postId<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">postRepository<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">findById<\/span><span class=\"p\">(<\/span><span class=\"nv\">$postId<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">create<\/span><span class=\"p\">(<\/span><span class=\"kt\">PostCreateRequest<\/span> <span class=\"nv\">$request<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">postRepository<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">create<\/span><span class=\"p\">(<\/span><span class=\"nv\">$request<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">validated<\/span><span class=\"p\">());<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">update<\/span><span class=\"p\">(<\/span><span class=\"kt\">PostUpdateRequest<\/span> <span class=\"nv\">$request<\/span><span class=\"p\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"nv\">$postId<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">postRepository<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">update<\/span><span class=\"p\">(<\/span><span class=\"nv\">$postId<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$request<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">validated<\/span><span class=\"p\">());<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">delete<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$postId<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">postRepository<\/span><span class=\"o\">-&gt;<\/span><span class=\"nb\">delete<\/span><span class=\"p\">(<\/span><span class=\"nv\">$postId<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>But in order for <code class=\"language-plaintext highlighter-rouge\">PostRepositoryInterface<\/code> to refer to <code class=\"language-plaintext highlighter-rouge\">PostRepository<\/code> we need to bind the interface to the repository.<\/p>\n\n<p>Go to the command line and run the following command at the root of the application to create a <code class=\"language-plaintext highlighter-rouge\">RepositoryServiceProvider<\/code>.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">php<\/span> <span class=\"n\">artisan<\/span> <span class=\"n\">make<\/span><span class=\"o\">:<\/span><span class=\"n\">provider<\/span> <span class=\"nc\">RepositoryServiceProvider<\/span>\n<span class=\"c1\">\/\/ Provider created successfully.<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>And this command should create a file <code class=\"language-plaintext highlighter-rouge\">RepositoryServiceProvider.php<\/code> in the <code class=\"language-plaintext highlighter-rouge\">app\/Providers<\/code>.<\/p>\n\n<p>Inside the <code class=\"language-plaintext highlighter-rouge\">RepositoryServiceProvider<\/code> class, in the <code class=\"language-plaintext highlighter-rouge\">register()<\/code> method, we will bind the interface to the repository.\nWe will also bind all our other interfaces to repositories in this provider.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">RepositoryServiceProvider<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">ServiceProvider<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"cd\">\/**\n     * Register services.\n     *\n     * @return void\n     *\/<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">register<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">app<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">bind<\/span><span class=\"p\">(<\/span><span class=\"nc\">PostRepositoryInterface<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span> <span class=\"nc\">PostRepository<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">);<\/span>\n        <span class=\"c1\">\/\/ $this-&gt;app-&gt;bind(CommentRepositoryInterface::class, CommentRepository::class);<\/span>\n        <span class=\"c1\">\/\/ $this-&gt;app-&gt;bind(UserRepositoryInterface::class, UserRepository::class);<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>The last step is to register this service provider in our <code class=\"language-plaintext highlighter-rouge\">config\/app.php<\/code>.\nOpen this file and add to the <code class=\"language-plaintext highlighter-rouge\">providers<\/code> array our provider <code class=\"language-plaintext highlighter-rouge\">App\\Providers\\RepositoryServiceProvider::class<\/code><\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"s1\">'providers'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">[<\/span>\n    <span class=\"c1\">\/\/ ...other declared providers<\/span>\n    <span class=\"nc\">App\\Providers\\RepositoryServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">];<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>And it\u2019s all! Now our application knows what class it should use when we type objects by its interfaces.<\/p>\n\n<h2>Repository and ORM<\/h2>\n\n<p>Perhaps you have a question: why use a repository if I use an ORM?\nAfter all, ORM can work with data, operating with business objects.<\/p>\n\n<p>However, there may be many cases where data storage is something more complex or specific than just an ORM.\nAnd then such a data layer is encapsulated using the repository pattern:<\/p>\n<ul>\n  <li>Working through interfaces, you can create multiple repository implementations. For example, MySql for data and a file system for storing images.<\/li>\n  <li>Centralizing the data access logic makes the code easier to maintain. For example, you may have some complex query that you need to call from somewhere else in your code.<\/li>\n  <li>Don\u2019t Repeat Yourself (DRY): This technique reduces code duplication.<\/li>\n  <li>Independence of business logic from the storage method.<\/li>\n<\/ul>\n\n<h2>Conclusion<\/h2>\n\n<p>After we implemented the Repository Pattern, our code became more structured, more readable, and,\nimportantly, easier to develop and more reusable in the future.<\/p>\n"},{"title":"PHP Exceptions: Try Catch for Error Handling","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/php-exceptions-try-catch-for-error-handling"}},"updated":"2022-09-12T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/php-exceptions-try-catch-for-error-handling","content":"<p>PHP 5 introduced us to a new error model that is still evolving today.\nThis model allows you to throw and catch exceptions in your application - it\u2019s a better way to handle errors than older versions of PHP.\nAll exceptions are instances of the <code class=\"language-plaintext highlighter-rouge\">Exception<\/code> base class, which we can extend to introduce our own custom exceptions.<\/p>\n\n<p>It is important to note here that exception handling is different from error handling.\nWhen handling errors, we can use the <code class=\"language-plaintext highlighter-rouge\">set_error_handler<\/code> function to set our custom error handling function so that whenever an error is fired, it will call our error handling function.\nThis way you can manage errors. However, as a rule, some kinds of errors are not recovered and stop the program execution.<\/p>\n\n<p>On the other hand, exceptions are something that is deliberately thrown by code and is expected to be caught at some point in your application.\nSo we can say that exceptions are recoverable and not certain errors that are not recoverable.\nIf the exception being thrown is somewhere in your application, program execution continues from where the exception was caught.\nAnd an exception that doesn\u2019t hit anywhere in your application results in an error that stops the program from running.<\/p>\n\n<h2>Exception handling flow<\/h2>\n\n<p>Let\u2019s take a look at the following diagram, which shows the general control flow of exception handling.<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/php-exceptions-try-catch-for-error-handling.png\" alt=\"Exception handling in a try catch finally block\" \/>\n<\/div>\n\n<p>Exceptions can be thrown and caught using <code class=\"language-plaintext highlighter-rouge\">try<\/code> and <code class=\"language-plaintext highlighter-rouge\">catch<\/code> blocks.\nYou are responsible for throwing exceptions if something happens that is not expected.\nLet\u2019s take a quick look at the main flow of exception handling as shown in the following pseudocode.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">\/\/ code before the try-catch block<\/span>\n \n<span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ code<\/span>\n \n  <span class=\"c1\">\/\/ if something is not as expected<\/span>\n      <span class=\"c1\">\/\/ throw exception using the \"throw\" keyword<\/span>\n \n  <span class=\"c1\">\/\/ code, it won't be executed if the above exception is thrown<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">catch<\/span> <span class=\"p\">(<\/span><span class=\"nc\">Exception<\/span> <span class=\"nv\">$e<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ exception is raised and it'll be handled here<\/span>\n  <span class=\"c1\">\/\/ $e-&gt;getMessage() contains the error message<\/span>\n<span class=\"p\">}<\/span>\n \n<span class=\"c1\">\/\/ code after the try-catch block, will always be executed<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Most of the time, when you\u2019re dealing with exceptions, you end up using a pattern, as shown in the snippet above.\nYou can also use a <code class=\"language-plaintext highlighter-rouge\">finally<\/code> block along with <code class=\"language-plaintext highlighter-rouge\">try<\/code> and <code class=\"language-plaintext highlighter-rouge\">catch<\/code> blocks, but we\u2019ll get to that later in this article.<\/p>\n\n<p>The <code class=\"language-plaintext highlighter-rouge\">try<\/code> block is the one used when you suspect that your code may be throwing an exception.\nYou should always wrap such code using <code class=\"language-plaintext highlighter-rouge\">try<\/code> and <code class=\"language-plaintext highlighter-rouge\">catch<\/code>.<\/p>\n\n<h2>Throwing an exception<\/h2>\n\n<p>The exception can be thrown by the function you are calling, or you can use the throw keyword to manually throw the exception.\nFor example, you can validate some input before performing any operation and <code class=\"language-plaintext highlighter-rouge\">throw<\/code> an exception if the input is invalid.<\/p>\n\n<p>The important thing to note here is that if you throw an exception, but you haven\u2019t defined a <code class=\"language-plaintext highlighter-rouge\">catch<\/code> block that should handle that exception, it will result in a fatal error.\nTherefore, you need to make sure that you always define a <code class=\"language-plaintext highlighter-rouge\">catch<\/code> block if you are throwing exceptions in your application.<\/p>\n\n<p>When an exception is caught in a <code class=\"language-plaintext highlighter-rouge\">catch<\/code> block, the <code class=\"language-plaintext highlighter-rouge\">Exception<\/code> object contains the error message that was thrown using the <code class=\"language-plaintext highlighter-rouge\">throw<\/code> keyword.\nThe variable <code class=\"language-plaintext highlighter-rouge\">$e<\/code> in the example above is an instance of the <code class=\"language-plaintext highlighter-rouge\">Exception<\/code> class, so it has access to all the methods of that class.\nIn this block, you must define your own exception handling logic - what exactly do you want to do with the error you catch.<\/p>\n\n<p>In the next section, we\u2019ll take a real world example to understand how exception handling works.<\/p>\n\n<h2>Example from a real project<\/h2>\n\n<p>In this section, we\u2019ll build a real-life example to demonstrate PHP\u2019s exception handling.<\/p>\n\n<p>Let\u2019s say you\u2019ve created an application that loads the application\u2019s configuration from a <code class=\"language-plaintext highlighter-rouge\">config.php<\/code> file.\nNow it\u2019s important that the <code class=\"language-plaintext highlighter-rouge\">config.php<\/code> file is present when your application boots up. So your application cannot run if the <code class=\"language-plaintext highlighter-rouge\">config.php<\/code> file is missing.\nSo this is the ideal case to throw an exception and tell the user that they need to fix the problem.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ init bootstrapping phase<\/span>\n \n    <span class=\"nv\">$config_file_path<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"config.php\"<\/span><span class=\"p\">;<\/span>\n \n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nb\">file_exists<\/span><span class=\"p\">(<\/span><span class=\"nv\">$config_file_path<\/span><span class=\"p\">))<\/span>\n    <span class=\"p\">{<\/span>\n      <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Exception<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"Configuration file not found.\"<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n  \n    <span class=\"c1\">\/\/ continue execution of the bootstrapping phase<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">catch<\/span> <span class=\"p\">(<\/span><span class=\"nc\">Exception<\/span> <span class=\"nv\">$e<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">echo<\/span> <span class=\"nv\">$e<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getMessage<\/span><span class=\"p\">();<\/span>\n    <span class=\"k\">die<\/span><span class=\"p\">();<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>As you can see in the example above, we check for the existence of a <code class=\"language-plaintext highlighter-rouge\">config.php<\/code> file at the start of the bootstrap phase.\nIf the <code class=\"language-plaintext highlighter-rouge\">config.php<\/code> file is found, execution continues normally. On the other hand, we will throw an exception if the <code class=\"language-plaintext highlighter-rouge\">config.php<\/code> file does not exist.\nAlso, we would like to stop execution if there is an exception!<\/p>\n\n<p>This is how you can use exceptions in your applications.\nYou should throw exceptions for exceptional use cases - you should not unnecessarily throw exceptions for errors such as invalid user credentials,\nincorrect directory access permissions, etc. that you often expect. They are better handled by general error messages in the normal application\u2019s thread of execution.<\/p>\n\n<p>So this was an example of exception handling using the default <code class=\"language-plaintext highlighter-rouge\">Exception<\/code> class.\nIn the next section, we\u2019ll look at how you can extend the main <code class=\"language-plaintext highlighter-rouge\">Exception<\/code> class and create your own custom exceptions in your application.<\/p>\n\n<h2>How to create custom exceptions<\/h2>\n\n<p>In this section, we will discuss how you can create custom exceptions in your applications.\nIn fact, we\u2019ll extend the example we just discussed in the previous section to demonstrate custom exceptions.<\/p>\n\n<p>In the previous example, we chose a configuration exception using the default <code class=\"language-plaintext highlighter-rouge\">Exception<\/code> class.\nThis is fine if you just want to deal with the error message.\nHowever, sometimes you want to do a little more depending on the type of exception being thrown.\nThis is why custom exclusions are useful.<\/p>\n\n<p>Let\u2019s move on to the previous example as shown in the following snippet.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">ConfigFileNotFoundException<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Exception<\/span> <span class=\"p\">{}<\/span>\n \n<span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ init bootstrapping phase<\/span>\n \n    <span class=\"nv\">$config_file_path<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"config.php\"<\/span><span class=\"p\">;<\/span>\n \n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nb\">file_exists<\/span><span class=\"p\">(<\/span><span class=\"nv\">$config_file_path<\/span><span class=\"p\">))<\/span>\n    <span class=\"p\">{<\/span>\n      <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">ConfigFileNotFoundException<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"Configuration file not found.\"<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n  \n    <span class=\"c1\">\/\/ continue execution of the bootstrapping phase<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">catch<\/span> <span class=\"p\">(<\/span><span class=\"nc\">ConfigFileNotFoundException<\/span> <span class=\"nv\">$e<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">echo<\/span> <span class=\"s2\">\"ConfigFileNotFoundException: \"<\/span><span class=\"mf\">.<\/span><span class=\"nv\">$e<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getMessage<\/span><span class=\"p\">();<\/span>\n    <span class=\"c1\">\/\/ other additional actions that you want to carry out for this exception<\/span>\n    <span class=\"k\">die<\/span><span class=\"p\">();<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">catch<\/span> <span class=\"p\">(<\/span><span class=\"nc\">Exception<\/span> <span class=\"nv\">$e<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">echo<\/span> <span class=\"nv\">$e<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getMessage<\/span><span class=\"p\">();<\/span>\n    <span class=\"k\">die<\/span><span class=\"p\">();<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>First, we have defined the <code class=\"language-plaintext highlighter-rouge\">ConfigFileNotFoundException<\/code> class, which extends the main <code class=\"language-plaintext highlighter-rouge\">Exception<\/code> class.\nIt now becomes our custom exception class and we can use it when we want to throw a <code class=\"language-plaintext highlighter-rouge\">ConfigFileNotFoundException<\/code> in our application.<\/p>\n\n<p>We then used the <code class=\"language-plaintext highlighter-rouge\">throw<\/code> keyword to throw a <code class=\"language-plaintext highlighter-rouge\">ConfigFileNotFoundException<\/code> in case the <code class=\"language-plaintext highlighter-rouge\">config.php<\/code> file does not exist.\nHowever, the important difference is in the <code class=\"language-plaintext highlighter-rouge\">catch<\/code> block.\nAs you can see, we have defined two <code class=\"language-plaintext highlighter-rouge\">catch<\/code> blocks, and each block is used to catch a different type of exception.<\/p>\n\n<p>The first one gets exceptions of type <code class=\"language-plaintext highlighter-rouge\">ConfigFileNotFoundException<\/code>.\nSo, if the exception being thrown is of type <code class=\"language-plaintext highlighter-rouge\">ConfigFileNotFoundException<\/code>, this block will be executed.\nIf the exception type does not match any particular <code class=\"language-plaintext highlighter-rouge\">catch<\/code> block, it will match the latter, which should catch all generic exception messages.<\/p>\n\n<h2>Finally block<\/h2>\n\n<p>In this section, we\u2019ll look at how you can use the <code class=\"language-plaintext highlighter-rouge\">finally<\/code> keyword along with <code class=\"language-plaintext highlighter-rouge\">try<\/code> and <code class=\"language-plaintext highlighter-rouge\">catch<\/code> blocks.\nSometimes you want to execute a piece of code regardless of whether an exception was thrown.\nThis is where you can use the <code class=\"language-plaintext highlighter-rouge\">finally<\/code> block, since the code you place in the <code class=\"language-plaintext highlighter-rouge\">finally<\/code> block will always be executed after the try and catch blocks have been executed,\nregardless of whether an exception was thrown.<\/p>\n\n<p>Let\u2019s try to understand this using the following example.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ code<\/span>\n \n  <span class=\"c1\">\/\/ if something is not as expected<\/span>\n      <span class=\"c1\">\/\/ throw exception using the \"throw\" keyword<\/span>\n \n  <span class=\"c1\">\/\/ code, it won't be executed if the above exception is thrown<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">catch<\/span> <span class=\"p\">(<\/span><span class=\"nc\">Exception<\/span> <span class=\"nv\">$e<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ exception is raised and it'll be handled here<\/span>\n  <span class=\"c1\">\/\/ $e-&gt;getMessage() contains the error message<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">finally<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ code, it'll always be executed<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>The code in the above example is almost the same with the only exception that we have added a <code class=\"language-plaintext highlighter-rouge\">finally<\/code> block after the <code class=\"language-plaintext highlighter-rouge\">catch<\/code> block.\nAnd, as we discussed, the code in this block will always be executed.<\/p>\n\n<p>The typical use cases we could come up with for using a <code class=\"language-plaintext highlighter-rouge\">finally<\/code> block are usually related to resource cleanup.\nFor example, if you opened a database connection or file on disk in a <code class=\"language-plaintext highlighter-rouge\">try<\/code> block, you can perform cleanup tasks such as closing the connection in a <code class=\"language-plaintext highlighter-rouge\">finally<\/code> block, as this is guaranteed.<\/p>\n\n<p>Exception handling is a key coding skill, and you should consider how exceptions will be handled as you develop your applications.\nThis will help you detect and recover from unexpected errors in your application. Hope this post inspires you to write better error handling code!<\/p>\n"},{"title":"What are indexes and how do they work","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/what-are-indexes-and-how-do-they-work"}},"updated":"2022-08-29T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/what-are-indexes-and-how-do-they-work","content":"<p>Indexes in MySQL are a great tool for optimizing SQL queries.\n<br \/>\nTo understand how they work, let\u2019s look at working with data without them.<\/p>\n\n<h2>1. Reading data from disk<\/h2>\n\n<p>What we see as files, the hard drive sees them as blocks.\nOne file usually occupies several blocks.\nEach block knows which block comes after it.\nThe file is divided into chunks and each chunk is stored in an empty block.<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image1.webp\" alt=\"Reading data from disk\" \/>\n<\/div>\n\n<p>When reading a file, we go through all the blocks in turn and assemble the file piece by piece.\nBlocks of the same file can be scattered across the disk (fragmentation).\nThen reading the file will slow down, as you will need to jump over different parts of the disk.<\/p>\n\n<p>When we look for something inside a file, we need to go through all the blocks in which it is stored.\nIf the file is very large, then the number of blocks will be significant.\nThe need to jump from block to block, which may be in different places, will greatly slow down the search for data.<\/p>\n\n<h2>2. Finding data in MySQL<\/h2>\n\n<p>MySQL tables are regular files. Let\u2019s execute a query like this:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">age<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">29<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>MySQL then opens a file that stores data from the <code class=\"language-plaintext highlighter-rouge\">users<\/code> table.\nAnd then it starts to sort through the entire file to find the necessary records.<\/p>\n\n<p>In addition, MySQL will compare the data in <code class=\"language-plaintext highlighter-rouge\">each row of the table<\/code> with the value in the query.\nLet\u2019s say you\u2019re working with a table that has 10 records.\nThen MySQL will read all 10 records, compare each of their <code class=\"language-plaintext highlighter-rouge\">age<\/code> column with the value 29, and select only the matching data:<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image2.webp\" alt=\"Finding data in MySQL\" \/>\n<\/div>\n\n<p>So there are two problems when reading data:<\/p>\n\n<ul>\n  <li>Low speed of reading files due to the location of blocks in different parts of the disk (fragmentation).<\/li>\n  <li>It requires a large number of comparison operations to find the desired data.<\/li>\n<\/ul>\n\n<h2>3. Data sorting<\/h2>\n\n<p>Let\u2019s imagine that we have sorted our 10 entries in descending order.\nThen, using the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Binary_search_algorithm\" target=\"_blank\" rel=\"noreferrer\">binary search algorithm<\/a>,\nwe could select the values we needed in a maximum of four operations:<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image3.webp\" alt=\"Data sorting\" \/>\n<\/div>\n\n<p>In addition to fewer comparison operations, we would save on reading unnecessary records.<\/p>\n\n<p>An index is a sorted set of values. In MySQL, indexes are always built on a particular column.\nFor example, we could build an index on the age column from the example.<\/p>\n\n<h2>4. Selecting Indexes in MySQL<\/h2>\n\n<p>In the simplest case, an index must be created for those columns that are present in the WHERE clause.<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image4.webp\" alt=\"Selecting Indexes in MySQL\" \/>\n<\/div>\n\n<p>Consider the query from the example:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">age<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">29<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>We need to create an index on the <code class=\"language-plaintext highlighter-rouge\">age<\/code> column:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">CREATE<\/span> <span class=\"k\">INDEX<\/span> <span class=\"n\">age<\/span> <span class=\"k\">ON<\/span> <span class=\"n\">users<\/span><span class=\"p\">(<\/span><span class=\"n\">age<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>After this operation, MySQL will start using the age index to perform similar queries.\nThe index will also be used for selections by ranges of values for this column:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">age<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">29<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 class=\"mb-0\">Sorting<\/h4>\n\n<p>For queries like this:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">ORDER<\/span> <span class=\"k\">BY<\/span> <span class=\"n\">register_date<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>The same rule applies \u2014 we create an index on the column by which sorting occurs:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">CREATE<\/span> <span class=\"k\">INDEX<\/span> <span class=\"n\">register_date<\/span> <span class=\"k\">ON<\/span> <span class=\"n\">users<\/span><span class=\"p\">(<\/span><span class=\"n\">register_date<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 class=\"mb-0\">Index storage internals<\/h4>\n\n<p>Imagine our table looks like this:<\/p>\n\n<pre>\n| id | name   | age |\n|----|--------|-----|\n| 1  | Den    | 29  |\n| 2  | Alyona | 15  |\n| 3  | Putin  | 89  |\n| 4  | Petro  | 12  |\n<\/pre>\n\n<p>After creating an index on the age column, MySQL will store all its values sorted.\n<br \/>\nIn addition, the relationship between the value in the index and the entry to which this value corresponds will be preserved.\nThe primary key is usually used for this:<\/p>\n\n<pre>\n| age | index |\n|-----|-------|\n| 12  | 4     |\n| 15  | 2     |\n| 29  | 1     |\n| 89  | 3     |\n<\/pre>\n\n<h4 class=\"mb-0\">Unique indexes<\/h4>\n\n<p>MySQL supports unique indexes. This is useful for columns whose values must be unique throughout the table.\nSuch indexes improve sampling efficiency for unique values. For example:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">email<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'example@example.com'<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>You need to create a unique index on the email column:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">CREATE<\/span> <span class=\"k\">UNIQUE<\/span> <span class=\"k\">INDEX<\/span> <span class=\"n\">email<\/span> <span class=\"k\">ON<\/span> <span class=\"n\">users<\/span><span class=\"p\">(<\/span><span class=\"n\">email<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Then, when searching for data, MySQL will stop after finding the first match. \nIn the case of a regular index, one more check (of the next value in the index) will be mandatory.<\/p>\n\n<h2>5. Composite Indexes<\/h2>\n\n<p>MySQL can only use one index per query (unless MySQL is able to combine select results across multiple indexes).\nTherefore, for queries that use multiple columns, composite indexes must be used.<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image5.webp\" alt=\"Composite Indexes\" \/>\n<\/div>\n\n<p>Consider this query:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">age<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">29<\/span> <span class=\"k\">AND<\/span> <span class=\"n\">gender<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'male'<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>We need to create a composite index on both columns:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">CREATE<\/span> <span class=\"k\">INDEX<\/span> <span class=\"n\">age_gender<\/span> <span class=\"k\">ON<\/span> <span class=\"n\">users<\/span><span class=\"p\">(<\/span><span class=\"n\">age<\/span><span class=\"p\">,<\/span> <span class=\"n\">gender<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h4 class=\"mb-0\">How a composite index works<\/h4>\n\n<p>To properly use composite indexes, you need to understand how they are stored.\nEverything works exactly the same as it would for a regular index.\nBut for values, the values of all incoming columns are used at once.\nFor a table with data like this:<\/p>\n\n<pre>\n| id | name   | age | gender |\n|----|--------|-----|--------|\n| 1  | Den    | 29  | male   |\n| 2  | Alyona | 15  | female |\n| 3  | Putin  | 89  | tsar   |\n| 4  | Petro  | 12  | male   |\n<\/pre>\n\n<p>the result of the composite index will be:<\/p>\n\n<pre>\n| age_gender | index |\n|------------|-------|\n| 12male     | 4     |\n| 15female   | 2     |\n| 29male     | 1     |\n| 89tsar     | 3     |\n<\/pre>\n\n<p>This means that the order of the columns in the index will play a big role.\nGenerally, columns that are used in <code class=\"language-plaintext highlighter-rouge\">WHERE<\/code> clauses should be placed at the beginning of the index.\nColumns from <code class=\"language-plaintext highlighter-rouge\">ORDER BY<\/code> - to the end.<\/p>\n\n<h4 class=\"mb-0\">Search by range<\/h4>\n\n<p>Imagine that our query will not use a comparison but a range search:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">age<\/span> <span class=\"o\">&lt;=<\/span> <span class=\"mi\">29<\/span> <span class=\"k\">AND<\/span> <span class=\"n\">gender<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'male'<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Then MySQL will not be able to use the full index because gender values will be different for different values of the age column.\nIn this case, the database will try to use part of the index (only age) to execute this query:<\/p>\n\n<pre>\n| age_gender | index |\n|------------|-------|\n| 12male     | 4     |\n| 15female   | 2     |\n| 29male     | 1     |\n| 89tsar     | 3     |\n<\/pre>\n\n<p>First, all data that matches the condition <code class=\"language-plaintext highlighter-rouge\">age &lt;= 29<\/code> will be filtered.\nThen, a search for the value <code class=\"language-plaintext highlighter-rouge\">\"male\"<\/code> will be performed without using an index.<\/p>\n\n<h4 class=\"mb-0\">Sorting<\/h4>\n\n<p>Composite indexes can also be used for sorting:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">gender<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'male'<\/span> <span class=\"k\">ORDER<\/span> <span class=\"k\">BY<\/span> <span class=\"n\">age<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>In this case, we will need to create the index in a different order because sorting (ORDER) occurs after filtering (WHERE):<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">CREATE<\/span> <span class=\"k\">INDEX<\/span> <span class=\"n\">gender_age<\/span> <span class=\"k\">ON<\/span> <span class=\"n\">users<\/span><span class=\"p\">(<\/span><span class=\"n\">gender<\/span><span class=\"p\">,<\/span> <span class=\"n\">age<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>This order of the columns in the index will allow you to filter by the first part of the index, and then sort the result by the second.<\/p>\n\n<p>There can be more columns in the index if required:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">gender<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'male'<\/span> <span class=\"k\">AND<\/span> <span class=\"n\">country<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'UA'<\/span> <span class=\"k\">ORDER<\/span> <span class=\"k\">BY<\/span> <span class=\"n\">age<\/span><span class=\"p\">,<\/span> <span class=\"n\">register_time<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>In this case, you should create an index like this:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">CREATE<\/span> <span class=\"k\">INDEX<\/span> <span class=\"n\">gender_country_age_register<\/span> <span class=\"k\">ON<\/span> <span class=\"n\">users<\/span><span class=\"p\">(<\/span><span class=\"n\">gender<\/span><span class=\"p\">,<\/span> <span class=\"n\">country<\/span><span class=\"p\">,<\/span> <span class=\"n\">age<\/span><span class=\"p\">,<\/span> <span class=\"n\">register_time<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<h2>6. Using EXPLAIN to analyze Indexes<\/h2>\n\n<p>The EXPLAIN statement will show index usage data for a particular query. For example<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">EXPLAIN<\/span> <span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">email<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'example@example.com'<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image6.png\" alt=\"Using EXPLAIN to analyze Indexes - image 1\" \/>\n<\/div>\n\n<p>The <code class=\"language-plaintext highlighter-rouge\">key<\/code> column shows the index used. The <code class=\"language-plaintext highlighter-rouge\">possible_keys<\/code> column shows all the indexes that can be used for this query.\nThe <code class=\"language-plaintext highlighter-rouge\">rows<\/code> column shows the number of records that the database had to read to execute this query (there are 336 records in the table).<\/p>\n\n<p>As you can see, no index is used in the example. After creating the index:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">EXPLAIN<\/span> <span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">email<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'example@example.com'<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image7.png\" alt=\"Using EXPLAIN to analyze Indexes - image 2\" \/>\n<\/div>\n\n<p>Only one entry was read because the index was used.<\/p>\n\n<h4 class=\"mb-0\">Checking the length of compound indexes<\/h4>\n\n<p>Explain will also help you determine if you are using a composite index correctly.\nLet\u2019s check the query from the example (with an index on the age and gender columns):<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">EXPLAIN<\/span> <span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">age<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">29<\/span> <span class=\"k\">AND<\/span> <span class=\"n\">gender<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'male'<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image8.png\" alt=\"Using EXPLAIN to analyze Indexes - image 3\" \/>\n<\/div>\n\n<p>The value of <code class=\"language-plaintext highlighter-rouge\">key_len<\/code> indicates the length of the index to use.\nIn our case, 24 bytes is the length of the entire index (5 bytes age + 19 bytes gender).<\/p>\n\n<p>If we change the exact comparison to a range search, we see that MySQL uses only part of the index:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">EXPLAIN<\/span> <span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">age<\/span> <span class=\"o\">&lt;=<\/span> <span class=\"mi\">29<\/span> <span class=\"k\">AND<\/span> <span class=\"n\">gender<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'male'<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image9.png\" alt=\"Using EXPLAIN to analyze Indexes - image 4\" \/>\n<\/div>\n\n<p>This indicates that the created index is not suitable for this query. If we create the correct index:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">Create<\/span> <span class=\"k\">index<\/span> <span class=\"n\">gender_age<\/span> <span class=\"k\">on<\/span> <span class=\"n\">users<\/span><span class=\"p\">(<\/span><span class=\"n\">gender<\/span><span class=\"p\">,<\/span> <span class=\"n\">age<\/span><span class=\"p\">);<\/span>\n<span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">EXPLAIN<\/span> <span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">age<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">29<\/span> <span class=\"k\">and<\/span> <span class=\"n\">gender<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'male'<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image10.png\" alt=\"Using EXPLAIN to analyze Indexes - image 5\" \/>\n<\/div>\n\n<p>In this case, MySQL uses the entire <code class=\"language-plaintext highlighter-rouge\">gender_age<\/code> index, because the order of the columns in it allows you to make this selection.<\/p>\n\n<h2>7. Index selectivity<\/h2>\n\n<p>Let\u2019s go back to the query:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">SELECT<\/span> <span class=\"o\">*<\/span> <span class=\"k\">FROM<\/span> <span class=\"n\">users<\/span> <span class=\"k\">WHERE<\/span> <span class=\"n\">age<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">29<\/span> <span class=\"k\">AND<\/span> <span class=\"n\">gender<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'male'<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>For such a query, you need to create a composite index. But how to choose the right sequence of columns in the index? Option two:<\/p>\n\n<ul>\n  <li>age, gender<\/li>\n  <li>gender, age<\/li>\n<\/ul>\n\n<p>Both will fit. But they will work with different efficiency.<\/p>\n\n<p>To understand this, consider the uniqueness of the values of each column and the number of corresponding entries in the table:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">select<\/span> <span class=\"n\">age<\/span><span class=\"p\">,<\/span> <span class=\"k\">count<\/span><span class=\"p\">(<\/span><span class=\"o\">*<\/span><span class=\"p\">)<\/span> <span class=\"k\">from<\/span> <span class=\"n\">users<\/span> <span class=\"k\">group<\/span> <span class=\"k\">by<\/span> <span class=\"n\">age<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<pre>\n+------+----------+\n| age  | count(*) |\n+------+----------+\n|   15 |      160 |\n|   16 |      250 |\n|        ...      |\n|   76 |      210 |\n|   85 |      230 |\n+------+----------+\n68 rows in set (0.00 sec)\n<\/pre>\n<p><br \/><\/p>\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">select<\/span> <span class=\"n\">gender<\/span><span class=\"p\">,<\/span> <span class=\"k\">count<\/span><span class=\"p\">(<\/span><span class=\"o\">*<\/span><span class=\"p\">)<\/span> <span class=\"k\">from<\/span> <span class=\"n\">users<\/span> <span class=\"k\">group<\/span> <span class=\"k\">by<\/span> <span class=\"n\">gender<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<pre>\n+--------+----------+\n| gender | count(*) |\n+--------+----------+\n| female |     8740 |\n| male   |     4500 |\n+--------+----------+\n2 rows in set (0.00 sec)\n<\/pre>\n\n<p>This information tells us the following:<\/p>\n<ul>\n  <li>Any value of the <code class=\"language-plaintext highlighter-rouge\">age<\/code> column usually contains about 200 entries.<\/li>\n  <li>Any value of the <code class=\"language-plaintext highlighter-rouge\">gender<\/code> column is about 6000 entries.<\/li>\n<\/ul>\n\n<p>If the <code class=\"language-plaintext highlighter-rouge\">age<\/code> column comes first in the index, then MySQL after the first part of the index will reduce the number of records to 200.\nIt remains to make a selection on them. If the <code class=\"language-plaintext highlighter-rouge\">gender<\/code> column comes first,\nthen the number of entries will be reduced to 6000 after the first part of the index.\nThat is, an order of magnitude more than in the case of <code class=\"language-plaintext highlighter-rouge\">age<\/code>.<\/p>\n\n<p>This means that the <code class=\"language-plaintext highlighter-rouge\">age_gender<\/code> index will perform better than <code class=\"language-plaintext highlighter-rouge\">gender_age<\/code>.<\/p>\n\n<p>The selectivity of a column is determined by the number of records in the table with the same values.\nWhen there are few records with the same value, selectivity is high. Such columns should be used first in composite indexes.<\/p>\n\n<h2>7. Primary Keys<\/h2>\n\n<p>A primary key is a special type of index that is an identifier for records in a table.\nIt is necessarily unique and is specified when creating tables:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">CREATE<\/span> <span class=\"k\">TABLE<\/span> <span class=\"nv\">`users`<\/span> <span class=\"p\">(<\/span>\n    <span class=\"nv\">`id`<\/span> <span class=\"nb\">int<\/span><span class=\"p\">(<\/span><span class=\"mi\">10<\/span><span class=\"p\">)<\/span> <span class=\"nb\">unsigned<\/span> <span class=\"k\">NOT<\/span> <span class=\"k\">NULL<\/span> <span class=\"n\">AUTO_INCREMENT<\/span><span class=\"p\">,<\/span>\n    <span class=\"nv\">`email`<\/span> <span class=\"nb\">varchar<\/span><span class=\"p\">(<\/span><span class=\"mi\">128<\/span><span class=\"p\">)<\/span> <span class=\"k\">NOT<\/span> <span class=\"k\">NULL<\/span><span class=\"p\">,<\/span>\n    <span class=\"nv\">`name`<\/span> <span class=\"nb\">varchar<\/span><span class=\"p\">(<\/span><span class=\"mi\">128<\/span><span class=\"p\">)<\/span> <span class=\"k\">NOT<\/span> <span class=\"k\">NULL<\/span><span class=\"p\">,<\/span>\n    <span class=\"k\">PRIMARY<\/span> <span class=\"k\">KEY<\/span> <span class=\"p\">(<\/span><span class=\"nv\">`id`<\/span><span class=\"p\">),<\/span>\n<span class=\"p\">)<\/span> <span class=\"n\">ENGINE<\/span><span class=\"o\">=<\/span><span class=\"n\">InnoDB<\/span> <span class=\"n\">AUTO_INCREMENT<\/span><span class=\"o\">=<\/span><span class=\"mi\">1<\/span> <span class=\"k\">DEFAULT<\/span> <span class=\"n\">CHARSET<\/span><span class=\"o\">=<\/span><span class=\"n\">utf8<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>When using InnoDB tables, always define primary keys. If there is no primary key, MySQL will still create a virtual private key.<\/p>\n\n<h4 class=\"mb-0\">Clustered indexes<\/h4>\n\n<p>Regular indexes are non-clustered. This means that the index itself only stores references to table entries.\nWhen working with an index, only the list of records (more precisely, the list of their primary keys) that match the query is determined.\nAfter that, another request occurs - to get the data of each record from this list.<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image11.webp\" alt=\"Primary Keys - image 1\" \/>\n<\/div>\n\n<p>Clustered indexes store entire record data, not references to them. When working with such an index, no additional data read operation is required.<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image12.webp\" alt=\"Primary Keys - image 2\" \/>\n<\/div>\n\n<p>Primary keys of InnoDB tables are clustered. Therefore, selections for them are very efficient.<\/p>\n\n<h4 class=\"mb-0\">Overhead<\/h4>\n\n<p>It is important to remember that indexes involve additional disk writes.\nEach time data is updated or added to the table, the data in the index is also written and updated.<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/what-are-indexes-and-how-do-they-work\/image13.webp\" alt=\"Primary Keys - image 3\" \/>\n<\/div>\n\n<p>Create only necessary indexes to avoid wasting server resources. Control index sizes for your tables:<\/p>\n\n<div class=\"language-sql highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">show<\/span> <span class=\"k\">table<\/span> <span class=\"n\">status<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<pre>\n+-------------------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+\n| Name              | Engine | Version | Row_format | Rows   | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time | Check_time | Collation       | Checksum | Create_options | Comment |\n+-------------------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+\n...\n| users             | InnoDB |      10 | Compact    |    314 |            208 |       65536 |               0 |        16384 |         0 |            355 | 2014-07-11 01:12:17 | NULL        | NULL       | utf8_general_ci |     NULL |                |         |\n+-------------------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+\n18 rows in set (0.06 sec)\n<\/pre>\n<p><br \/><\/p>\n<h2>When to create indexes?<\/h2>\n\n<ul>\n  <li>Indexes should be created as slow queries are discovered. Queries that run for more than 1 second are prime candidates for optimization.<\/li>\n  <li>Start creating indexes with the most frequent queries. A query that runs for a second, but 1000 times a day does more damage than a 10-second query that runs several times a day.<\/li>\n  <li>Do not create indexes on tables with fewer than a few thousand records. For such sizes, the gain from using the index will be almost imperceptible.<\/li>\n  <li>Do not create indexes ahead of time, such as in a development environment. Indexes should be set exclusively for the form and type of load of the operating system.<\/li>\n  <li>Remove unused indexes.<\/li>\n<\/ul>\n\n<h2>The most important<\/h2>\n\n<p>Allow sufficient time to analyze and organize indexes in MySQL (and other databases).\nThis can take much more time than designing the database structure.\nIt will be convenient to organize a test environment with a copy of real data and test different index structures there.<\/p>\n\n<p>Don\u2019t create indexes on every column in a query, MySQL doesn\u2019t work that way. Use unique indexes where necessary. Always set primary keys.<\/p>\n"},{"title":"D - Dependency Inversion Principle | SOLID","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/solid-dependency-inversion-principle"}},"updated":"2022-08-22T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/solid-dependency-inversion-principle","content":"<p>The Dependency Inversion Principle (DIP) is the fifth of the five basic principles of object-oriented programming and \ndesign, formulated by Robert Martin, known as Uncle Bob.\n<br \/><br \/>\nThe principle says that<\/p>\n<blockquote>\n  <p>High level modules should not depend on low level modules; both should depend on abstractions. Abstractions should not depend on details. Details should depend upon abstractions.<\/p>\n<\/blockquote>\n\n<p>The principle may seem complicated at first glance, but it is very easy to understand.\n<br \/>\nIt\u2019s better to see this with an example.<\/p>\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">EmailSender<\/span> <span class=\"p\">{<\/span>\n     <span class=\"k\">private<\/span> <span class=\"nv\">$emailProvider<\/span><span class=\"p\">;<\/span>\n \n     <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">Gmail<\/span> <span class=\"nv\">$emailProvider<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n         <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">semailProvider<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$emailProvider<\/span><span class=\"p\">;<\/span>\n     <span class=\"p\">}<\/span>\n     \n     <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">connect<\/span><span class=\"p\">(){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n<p><code class=\"language-plaintext highlighter-rouge\">Gmail<\/code> is a low-level module, and <code class=\"language-plaintext highlighter-rouge\">EmailSender<\/code> is a high-level one.\n<br \/>\nBut according to the definition of the principle, which says to separate abstractions from implementation,\nthis fragment violates it because the <code class=\"language-plaintext highlighter-rouge\">EmailSender<\/code> class depends on the <code class=\"language-plaintext highlighter-rouge\">Gmail<\/code> class.<\/p>\n\n<p>If you later need to replace the email sending provider, then you will have to change the <code class=\"language-plaintext highlighter-rouge\">EmailSender<\/code> class,\nwhich violates the principle of <a href=\"https:\/\/kongulov.dev\/blog\/solid-open-closed-principle\" target=\"_blank\">open\/closed(OCP)<\/a>.<\/p>\n\n<p>The <code class=\"language-plaintext highlighter-rouge\">EmailSender<\/code> class doesn\u2019t have to worry about the provider that is being used.\n<br \/>\nTo fix this, we need to allocate an interface so that low-level and high-level modules depend on abstraction.<\/p>\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">interface<\/span> <span class=\"nc\">EmailProviderInterface<\/span> <span class=\"p\">{<\/span>\n     <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">connect<\/span><span class=\"p\">();<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>The interface has a connect method, and the <code class=\"language-plaintext highlighter-rouge\">Gmail<\/code> class implements it.\nAlso, instead of checking the type to see whether the passed object belongs to the <code class=\"language-plaintext highlighter-rouge\">Gmail<\/code> class in the <code class=\"language-plaintext highlighter-rouge\">EmailSender<\/code> constructor,\nwe use the interface ownership check. And the <code class=\"language-plaintext highlighter-rouge\">EmailSender<\/code> class no longer worries about the type of provider that will be used,\nthe main thing is that there is a connection possibility and the <a href=\"https:\/\/kongulov.dev\/blog\/solid-open-closed-principle\" target=\"_blank\">OCP<\/a> principle is not violated.<\/p>\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">Gmail<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">EmailProviderInterface<\/span> <span class=\"p\">{<\/span>\n     <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">connect<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n         <span class=\"k\">return<\/span> <span class=\"s2\">\"Gmail connection\"<\/span><span class=\"p\">;<\/span>\n     <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n \n<span class=\"kd\">class<\/span> <span class=\"nc\">EmailSender<\/span> <span class=\"p\">{<\/span>\n     <span class=\"k\">private<\/span> <span class=\"nv\">$emailProvider<\/span><span class=\"p\">;<\/span>\n \n     <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">EmailProviderInterface<\/span> <span class=\"nv\">$emailProvider<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n         <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">semailProvider<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$emailProvider<\/span><span class=\"p\">;<\/span>\n     <span class=\"p\">}<\/span>\n     \n     <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">connect<\/span><span class=\"p\">(){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>Now both modules (low-level and high-level) depend on abstraction.<\/p>\n"},{"title":"I - Interface Segregation Principle | SOLID","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/solid-interface-segregation-principle"}},"updated":"2022-08-15T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/solid-interface-segregation-principle","content":"<p>The Interface Segregation Principle (ISP) is the fourth of the five basic principles of object-oriented programming and \ndesign, formulated by Robert Martin, known as Uncle Bob.\n<br \/><br \/>\nThe principle says that<\/p>\n<blockquote>\n  <p>Many client-specific interfaces are better than one general-purpose interface.<\/p>\n<\/blockquote>\n\n<p>This principle is very easy to understand, and following it is necessary so that classes that\nimplement an interface only know about the methods they use, which leads to a reduction in the amount of unused code.<\/p>\n\n<p>Here is an example from an online store.\n<br \/>\nAssume our products have a promotional code, a discount, a price, a condition, and so on.\n<br \/>\nIf it is clothing, then it is determined by what material it is made of, color, and size.\n<br \/>\nLet\u2019s describe the following interface.<\/p>\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">interface<\/span> <span class=\"nc\">ItemInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">applyDiscount<\/span><span class=\"p\">(<\/span><span class=\"nv\">$discount<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">applyPromocode<\/span><span class=\"p\">(<\/span><span class=\"nv\">$promocode<\/span><span class=\"p\">);<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setColor<\/span><span class=\"p\">(<\/span><span class=\"nv\">$color<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setSize<\/span><span class=\"p\">(<\/span><span class=\"nv\">$size<\/span><span class=\"p\">);<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setCondition<\/span><span class=\"p\">(<\/span><span class=\"nv\">$condition<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setPrice<\/span><span class=\"p\">(<\/span><span class=\"nv\">$price<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>This interface is bad because it includes too many methods.\nAnd what if our product category is not eligible for a discount or promotional code,\nor if it makes no sense to install the material from which it is made (for example, books)?\nThus, in order not to implement unused methods in each class,\nit is better to divide the interface into several small ones and implement the necessary interfaces with each specific class.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">interface<\/span> <span class=\"nc\">ItemInterface<\/span>\n<span class=\"p\">{<\/span>\n\t<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setCondition<\/span><span class=\"p\">(<\/span><span class=\"nv\">$condition<\/span><span class=\"p\">);<\/span>\n\t<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setPrice<\/span><span class=\"p\">(<\/span><span class=\"nv\">$price<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">interface<\/span> <span class=\"nc\">ClothesInterface<\/span>\n<span class=\"p\">{<\/span>\n\t<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setColor<\/span><span class=\"p\">(<\/span><span class=\"nv\">$color<\/span><span class=\"p\">);<\/span>\n\t<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setSize<\/span><span class=\"p\">(<\/span><span class=\"nv\">$size<\/span><span class=\"p\">);<\/span>\n\t<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setMaterial<\/span><span class=\"p\">(<\/span><span class=\"nv\">$material<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">interface<\/span> <span class=\"nc\">DiscountableInterface<\/span>\n<span class=\"p\">{<\/span>\n\t<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">applyDiscount<\/span><span class=\"p\">(<\/span><span class=\"nv\">$discount<\/span><span class=\"p\">);<\/span>\n\t<span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">applyPromocode<\/span><span class=\"p\">(<\/span><span class=\"nv\">$promocode<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">Book<\/span> <span class=\"n\">implemets<\/span> <span class=\"nc\">ItemInterface<\/span><span class=\"p\">,<\/span> <span class=\"nc\">DiscountableInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setCondition<\/span><span class=\"p\">(<\/span><span class=\"nv\">$condition<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setPrice<\/span><span class=\"p\">(<\/span><span class=\"nv\">$price<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">applyDiscount<\/span><span class=\"p\">(<\/span><span class=\"nv\">$discount<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">applyPromocode<\/span><span class=\"p\">(<\/span><span class=\"nv\">$promocode<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">KidsClothes<\/span> <span class=\"n\">implemets<\/span> <span class=\"nc\">ItemInterface<\/span><span class=\"p\">,<\/span> <span class=\"nc\">ClothesInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setCondition<\/span><span class=\"p\">(<\/span><span class=\"nv\">$condition<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setPrice<\/span><span class=\"p\">(<\/span><span class=\"nv\">$price<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setColor<\/span><span class=\"p\">(<\/span><span class=\"nv\">$color<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setSize<\/span><span class=\"p\">(<\/span><span class=\"nv\">$size<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">setMaterial<\/span><span class=\"p\">(<\/span><span class=\"nv\">$material<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n"},{"title":"L - Liskov Substitution Principle | SOLID","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/solid-liskov-substitution-principle"}},"updated":"2022-08-08T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/solid-liskov-substitution-principle","content":"<p>The Liskov Substitution Principle (LSP) is the third of the five basic principles of object-oriented programming and \ndesign, formulated by Robert Martin, known as Uncle Bob.\n<br \/><br \/>\nThe principle says that<\/p>\n<blockquote>\n  <p>Subclasses should be substitutable for their base classes.<\/p>\n<\/blockquote>\n\n<p>In simple terms, we can say that the behavior of inherited classes should not contradict the behavior specified by the base class,\nthat is, the behavior of extended classes must be expected as in the base class.<\/p>\n\n<p>This implies a ban on manipulating the data of the parent class and overriding the methods of the parent class with a change (but not an extension) of their functionality.\nIt was a revolutionary approach for its time and still remains one of the most powerful design principles.<\/p>\n\n<p>First, let\u2019s look at an example that violates the LSP principle.<\/p>\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">MediaPlayer<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">playAudio<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"s1\">'Playing audio...'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">playVideo<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"s1\">'Playing video...'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">VlcMediaPlayer<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">MediaPlayer<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">playAudio<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"s1\">'Playing audio...'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">playVideo<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"s1\">'Playing video...'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">WinampMediaPlayer<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">MediaPlayer<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">playAudio<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"s1\">'Playing audio...'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>The LSP principle states that classes should treat base class methods equally.\n<br \/>\nAnd <code class=\"language-plaintext highlighter-rouge\">WinampMediaPlayer<\/code> only supports audio playback and is incompatible with video playback, and therefore we will get an error<\/p>\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nv\">$vlc<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">VlcMediaPlayer<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$vlc<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">playAudio<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$vlc<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">playVideo<\/span><span class=\"p\">();<\/span>\n\n<span class=\"nv\">$winamp<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">WinampMediaPlayer<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$winamp<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">playAudio<\/span><span class=\"p\">();<\/span>\n<span class=\"nv\">$winamp<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">playVideo<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ There will be an error<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Now consider an example that does not violate the LSP principle<\/p>\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">MediaPlayer<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">playAudio<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"s1\">'Playing audio...'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">VideoMediaPlayer<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">MediaPlayer<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">playVideo<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"s1\">'Playing video...'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">VlcMediaPlayer<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">VideoMediaPlayer<\/span>\n<span class=\"p\">{<\/span>\n\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">WinampMediaPlayer<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">MediaPlayer<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">playAudio<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"s1\">'Playing audio...'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Now inherited classes do not violate the behavior of base classes, and therefore the LSP principle is not violated.<\/p>\n"},{"title":"O - Open-Closed Principle | SOLID","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/solid-open-closed-principle"}},"updated":"2022-08-01T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/solid-open-closed-principle","content":"<p>The Open-Closed Principle (OCP) is second of the five basic principles of object-oriented programming and \ndesign, formulated by Robert Martin, known as Uncle Bob.\n<br \/><br \/>\nThe principle says that<\/p>\n<blockquote>\n  <p>Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification<\/p>\n<\/blockquote>\n\n<p>This means that these entities can change their behavior without changing their source code.<\/p>\n\n<p>Following the principle of OCP is that software changes not by changing existing code, but by adding new code.\nThat is, the code originally created remains \u201cintact\u201d and stable, and new functionality is introduced either through\nimplementation inheritance, or through the use of abstract interfaces and polymorphism.<\/p>\n\n<p>Consider the <code class=\"language-plaintext highlighter-rouge\">OrderRepository<\/code> class as an example.<\/p>\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">OrderRepository<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">load<\/span><span class=\"p\">(<\/span><span class=\"nv\">$orderID<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nv\">$pdo<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">PDO<\/span><span class=\"p\">(<\/span>\n            <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">config<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getDsn<\/span><span class=\"p\">(),<\/span>\n            <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">config<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getDBUser<\/span><span class=\"p\">(),<\/span>\n            <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">config<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">getDBPassword<\/span><span class=\"p\">()<\/span>\n        <span class=\"p\">);<\/span>\n        <span class=\"nv\">$statement<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$pdo<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">prepare<\/span><span class=\"p\">(<\/span><span class=\"s1\">'SELECT * FROM `orders` WHERE id=:id'<\/span><span class=\"p\">);<\/span>\n        <span class=\"nv\">$statement<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">execute<\/span><span class=\"p\">([<\/span><span class=\"s1\">':id'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nv\">$orderID<\/span><span class=\"p\">]);<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$query<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">fetchObject<\/span><span class=\"p\">(<\/span><span class=\"s1\">'Order'<\/span><span class=\"p\">);<\/span>\t\n    <span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">save<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">update<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">delete<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>In this case, the storage is the DB database. But if we want to expand the functionality and upload our order data through a third-party server using the API, then what will need to be done for this?<\/p>\n\n<p>There are several options:<\/p>\n\n<p>First, you can directly change the methods of the <code class=\"language-plaintext highlighter-rouge\">OrderRepository<\/code> class, but this one does not follow the open\/closed principle, since the class is closed for modification, and making changes to an already well-functioning class is undesirable.<\/p>\n\n<p>Second, you can extend the <code class=\"language-plaintext highlighter-rouge\">OrderRepository<\/code> class and override all methods, but this is not the best solution.\nsince when adding a new method to <code class=\"language-plaintext highlighter-rouge\">OrderRepository<\/code> we will have to add similar methods in all extended classes.<\/p>\n\n<p>Therefore, to implement the open\/closed principle, it is better to apply the following solution:\n<br \/>\nCreate an <code class=\"language-plaintext highlighter-rouge\">OrderSourceInterface<\/code>, which will be implemented by the corresponding classes <code class=\"language-plaintext highlighter-rouge\">DBOrderSource<\/code>, <code class=\"language-plaintext highlighter-rouge\">ApiOrderSource<\/code>, and so on.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">OrderRepository<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">private<\/span> <span class=\"nv\">$source<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">OrderSourceInterface<\/span> <span class=\"nv\">$source<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">source<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$source<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">load<\/span><span class=\"p\">(<\/span><span class=\"nv\">$orderID<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">save<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">update<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">interface<\/span> <span class=\"nc\">OrderSourceInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">load<\/span><span class=\"p\">(<\/span><span class=\"nv\">$orderID<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">save<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">update<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">delete<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">DBOrderSource<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">OrderSourceInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">load<\/span><span class=\"p\">(<\/span><span class=\"nv\">$orderID<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">save<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">update<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">delete<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">ApiOrderSource<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">OrderSourceInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">load<\/span><span class=\"p\">(<\/span><span class=\"nv\">$orderID<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">save<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">update<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">delete<\/span><span class=\"p\">(<\/span><span class=\"nv\">$order<\/span><span class=\"p\">){<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Thus, we can change the source and, accordingly, the behavior for the <code class=\"language-plaintext highlighter-rouge\">OrderRepository<\/code> class by setting the class we need\nthat implements <code class=\"language-plaintext highlighter-rouge\">OrderSourceInterface<\/code>, without changing the <code class=\"language-plaintext highlighter-rouge\">OrderRepository<\/code> class.<\/p>\n"},{"title":"S - Single Responsibility Principle | SOLID","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/solid-single-responsibility-principle"}},"updated":"2022-07-25T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/solid-single-responsibility-principle","content":"<p>The Single Responsibility Principle (SRP) is the one of the five basic principles of object-oriented programming and design,\nformulated by Robert Martin, known as Uncle Bob.\n<br \/><br \/>\nThe principle says that<\/p>\n<blockquote>\n  <p>A class should be one, and only one, reason to change.<\/p>\n<\/blockquote>\n\n<p>In this article, I will try to explain this principle with a simple example.\n<br \/>\nWe have a User class where there is a CRUD of the user with his documents.<\/p>\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">User<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">list<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">get<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">create<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$data<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">update<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$data<\/span><span class=\"p\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">delete<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">documentList<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$userId<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">getDocument<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$userId<\/span><span class=\"p\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">createDocument<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$userId<\/span><span class=\"p\">,<\/span> <span class=\"kt\">array<\/span> <span class=\"nv\">$data<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">updateDocument<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$userId<\/span><span class=\"p\">,<\/span> <span class=\"kt\">array<\/span> <span class=\"nv\">$data<\/span><span class=\"p\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">deleteDocument<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$userId<\/span><span class=\"p\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n<p>This approach violates SRP since the class is responsible for two jobs: Working with users and working with documents.<\/p>\n\n<p>The problem can be solved by dividing the class into two separate classes.<\/p>\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class<\/span> <span class=\"nc\">User<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">list<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">get<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">create<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$data<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">update<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$data<\/span><span class=\"p\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">delete<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">UserDocument<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">private<\/span> <span class=\"nv\">$user<\/span><span class=\"p\">;<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">User<\/span> <span class=\"nv\">$user<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">user<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$user<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n    \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">list<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">get<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">create<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$data<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">update<\/span><span class=\"p\">(<\/span><span class=\"kt\">array<\/span> <span class=\"nv\">$data<\/span><span class=\"p\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">delete<\/span><span class=\"p\">(<\/span><span class=\"kt\">int<\/span> <span class=\"nv\">$id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Now the class does exactly one thing and has exactly one reason to change.<\/p>\n"},{"title":"How to register and use the Laravel service providers","link":{"@attributes":{"href":"https:\/\/kongulov.dev\/blog\/how-to-register-and-use-the-laravel-service-providers"}},"updated":"2022-07-18T00:00:00+04:00","id":"https:\/\/kongulov.dev\/blog\/how-to-register-and-use-the-laravel-service-providers","content":"<p>If you\u2019ve ever been familiar with the Laravel framework, it\u2019s unlikely that you haven\u2019t heard of service containers and service providers.\nIn fact, they are the backbone of the Laravel framework and do all the heavy lifting when you launch an instance of any Laravel application.<\/p>\n\n<p>In this article, we\u2019ll see what a service container is, and after that, we\u2019ll discuss service providers in detail.\nIn the course of this article, I\u2019ll also demonstrate how to create your own custom service provider in Laravel.\nWhen you create a service provider, you also need to register it with your Laravel application in order to use it, so we\u2019ll cover that as well.<\/p>\n\n<p>There are two important methods: boot and register, that your service provider can implement, and we\u2019ll discuss them in detail in the last section of this article.<\/p>\n\n<p>Before moving on to the discussion of the service provider, I will try to introduce the service container as it will be heavily used in your service provider implementation.<\/p>\n\n<div class=\"post-image\">\n    <img src=\"https:\/\/kongulov.dev\/assets\/images\/posts\/how-to-register-and-use-the-laravel-service-providers.png\" alt=\"How to register and use the Laravel service providers\" \/>\n<\/div>\n\n<h2>Understanding Service Containers and Service Providers<\/h2>\n<h3>What is a service container?<\/h3>\n\n<p>In the simplest terms, we can say that a container in Laravel is a box that contains the bindings of various components, and these are maintained as needed throughout the application.<\/p>\n\n<p>According to the official Laravel documentation:<\/p>\n<blockquote>\n  <p>The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection.<\/p>\n<\/blockquote>\n\n<p>This way, whenever you need to inline any bean or service, you can specify it in your constructor or method and it will be automatically inlined from the service container as it contains everything you need! Isn\u2019t that cool?\nThis saves you the hassle of manually laying out components and thus avoids hard coupling in your code.<\/p>\n\n<p>Let\u2019s look at a quick example to understand this.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">Class<\/span> <span class=\"nc\">SomeClass<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">__construct<\/span><span class=\"p\">(<\/span><span class=\"kt\">FooBar<\/span> <span class=\"nv\">$foobarObject<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ use $foobarObject object<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>As you can see, <code class=\"language-plaintext highlighter-rouge\">SomeClassneeds<\/code> an instance <code class=\"language-plaintext highlighter-rouge\">FooBarto<\/code> instantiate. So basically, it has a dependency that needs to be built in.\nLaravel does this automatically by looking at the container and injecting the appropriate dependency.<\/p>\n\n<p>And if you\u2019re wondering how Laravel knows which components or services to include in a container, the answer is a service provider.\nThe service provider tells Laravel to include various components in the service container.\nIn fact, this is called binding to service containers, and you need to do it through the service provider.<\/p>\n\n<p>Thus, the service provider registers all of the container\u2019s bindings, and this is done through the register method of the service provider\u2019s implementation.<\/p>\n\n<p>Another question that should immediately pop up is: how does Laravel know about the different service providers? Did you just say something?\nI just heard someone say that Laravel should figure this out automatically too! Oh, you\u2019re asking too much: Laravel is a framework, not a superhuman, is it?\nSo service providers are what you need to tell Laravel directly.<\/p>\n\n<p>Go ahead and see the contents of the file <code class=\"language-plaintext highlighter-rouge\">config\/app.php<\/code>.\nYou will find an array entry that lists all the service providers that will be loaded during the initial load of the Laravel application.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"s1\">'providers'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">[<\/span>\n    <span class=\"cm\">\/*\n     * Laravel Framework Service Providers...\n     *\/<\/span>\n    <span class=\"nc\">Illuminate\\Auth\\AuthServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">Illuminate\\Broadcasting\\BroadcastServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">Illuminate\\Bus\\BusServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"cm\">\/*...*\/<\/span>\n    <span class=\"nc\">Illuminate\\Translation\\TranslationServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">Illuminate\\Validation\\ValidationServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">Illuminate\\View\\ViewServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n\n    <span class=\"cm\">\/*\n     * Package Service Providers...\n     *\/<\/span>\n\n    <span class=\"cm\">\/*\n     * Application Service Providers...\n     *\/<\/span>\n    <span class=\"nc\">App\\Providers\\AppServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">App\\Providers\\AuthServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"c1\">\/\/ App\\Providers\\BroadcastServiceProvider::class,<\/span>\n    <span class=\"nc\">App\\Providers\\EventServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">App\\Providers\\RouteServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">],<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>So, this was the container at your disposal. In the next section, we\u2019ll focus on the service provider, which is the main topic of this article!<\/p>\n\n<h3>What is a service provider?<\/h3>\n\n<p>If the container is what allows you to define bindings and install dependencies, a service provider is where it all happens.<\/p>\n\n<p>Let\u2019s take a quick look at one of the major service providers to see what it does.\nOpen <span class=\"wb-bw\"><code class=\"language-plaintext highlighter-rouge\">filevender\/laravel\/framework\/src\/Illuminate\/Cache\/CacheServiceProvider.php<\/code><\/span><\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">register<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">app<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">singleton<\/span><span class=\"p\">(<\/span><span class=\"s1\">'cache'<\/span><span class=\"p\">,<\/span> <span class=\"k\">function<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$app<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">CacheManager<\/span><span class=\"p\">(<\/span><span class=\"nv\">$app<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">});<\/span>\n  \n    <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">app<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">singleton<\/span><span class=\"p\">(<\/span><span class=\"s1\">'cache.store'<\/span><span class=\"p\">,<\/span> <span class=\"k\">function<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$app<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nv\">$app<\/span><span class=\"p\">[<\/span><span class=\"s1\">'cache'<\/span><span class=\"p\">]<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">driver<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">});<\/span>\n  \n    <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">app<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">singleton<\/span><span class=\"p\">(<\/span><span class=\"s1\">'memcached.connector'<\/span><span class=\"p\">,<\/span> <span class=\"k\">function<\/span> <span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">MemcachedConnector<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">});<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>The important thing to note here is the method <code class=\"language-plaintext highlighter-rouge\">register<\/code> that allows you to define container bindings.\nAs you can see, there are three bindings for the <code class=\"language-plaintext highlighter-rouge\">cache<\/code>, <code class=\"language-plaintext highlighter-rouge\">cache.store<\/code> and <code class=\"language-plaintext highlighter-rouge\">memcached.connector<\/code>.<\/p>\n\n<p>Basically, we inform Laravel that whenever there is a need to allow a service to be retrieved <code class=\"language-plaintext highlighter-rouge\">cache<\/code>, it should return an instance of <code class=\"language-plaintext highlighter-rouge\">CacheManager<\/code>.\nSo we just add this match to the container, which can be accessed via <code class=\"language-plaintext highlighter-rouge\">$this-&gt;app<\/code>.<\/p>\n\n<p>This is the correct way to add any service to a Laravel container.\nIt also allows you to understand how Laravel goes through the register method of all service providers and populates the container!\nAs we mentioned earlier, it uses the list of service providers from the <code class=\"language-plaintext highlighter-rouge\">config\/app.php<\/code>.<\/p>\n\n<p>And it was a story about a service provider.\nIn the next section, we\u2019ll discuss how to create a custom service provider so that you can register your custom services with a Laravel container.<\/p>\n\n<h3>Creating your own service provider<\/h3>\n\n<p>Laravel already has a handy command line utility, <code class=\"language-plaintext highlighter-rouge\">artisan<\/code>, that allows you to generate template code so you don\u2019t have to create it from scratch.\nGo to the command line and run the following command at the root of the application to create a custom service provider.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">php<\/span> <span class=\"n\">artisan<\/span> <span class=\"n\">make<\/span><span class=\"o\">:<\/span><span class=\"n\">provider<\/span> <span class=\"nc\">DemoCustomServiceProvider<\/span>\n<span class=\"c1\">\/\/ Provider created successfully.<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>And this command should create a file <code class=\"language-plaintext highlighter-rouge\">DemoCustomServiceProvider.php<\/code> in the <code class=\"language-plaintext highlighter-rouge\">app\/Providers<\/code>.\nWhen we open the file, we will see the following code<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Providers<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Support\\ServiceProvider<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kd\">class<\/span> <span class=\"nc\">DemoCustomServiceProvider<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">ServiceProvider<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"cd\">\/**\n     * Bootstrap the application services.\n     *\n     * @return void\n     *\/<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">boot<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/<\/span>\n    <span class=\"p\">}<\/span>\n  \n    <span class=\"cd\">\/**\n     * Register the application services.\n     *\n     * @return void\n     *\/<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">register<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>As we discussed earlier, there are two methods, register and booy, that you will deal with most of the time when working with your custom service provider.<\/p>\n\n<p>The method <code class=\"language-plaintext highlighter-rouge\">register<\/code> is where you define all custom container bindings.\nOn the other hand, a method <code class=\"language-plaintext highlighter-rouge\">boot<\/code> is a place where you can use services already registered via the register method.\nIn the last section of this article, we will discuss these two methods in detail as we go through some practical examples to understand the use of both methods.<\/p>\n\n<h3>Register your custom service provider<\/h3>\n\n<p>Thus, you have created your own service provider. Wonderful!\nYou then need to tell Laravel about your custom service provider so that it can load it along with other providers during bootstrap.<\/p>\n\n<p>To register a service provider, you simply need to add an entry to the service provider array in the <code class=\"language-plaintext highlighter-rouge\">config\/app.php<\/code>.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"s1\">'providers'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">[<\/span>\n    <span class=\"cm\">\/*\n     * Laravel Framework Service Providers...\n     *\/<\/span>\n    <span class=\"nc\">Illuminate\\Auth\\AuthServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">Illuminate\\Broadcasting\\BroadcastServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">Illuminate\\Bus\\BusServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"cm\">\/*...*\/<\/span>\n    <span class=\"nc\">Illuminate\\Translation\\TranslationServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">Illuminate\\Validation\\ValidationServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">Illuminate\\View\\ViewServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n\n    <span class=\"cm\">\/*\n     * Package Service Providers...\n     *\/<\/span>\n\n    <span class=\"cm\">\/*\n     * Application Service Providers...\n     *\/<\/span>\n    <span class=\"nc\">App\\Providers\\AppServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">App\\Providers\\AuthServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"c1\">\/\/ App\\Providers\\BroadcastServiceProvider::class,<\/span>\n    <span class=\"nc\">App\\Providers\\EventServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">App\\Providers\\RouteServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span>\n    <span class=\"nc\">App\\Providers\\DemoCustomServiceProvider<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">,<\/span> <span class=\"c1\">\/\/ &lt;- Insert class here<\/span>\n<span class=\"p\">],<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>That\u2019s all! You have registered your service provider with the Laravel Schema! But the service provider we created is almost an empty template and is not used at the moment.\nIn the next section, we\u2019ll look at some practical examples to see what you can do with the register and boot methods.<\/p>\n\n<h3>Let's go through the register and boot methods<\/h3>\n\n<p>First, we\u2019ll take a look at the method <code class=\"language-plaintext highlighter-rouge\">register<\/code> to understand how you can use it.\n<span class=\"wb-bw\">Open the service provider file you created earlier <code class=\"language-plaintext highlighter-rouge\">app\/Providers\/DemoCustomServiceProvider.php<\/code> and replace the existing code with the following.<\/span><\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Providers<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Support\\ServiceProvider<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Library\\Services\\DemoOne<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kd\">class<\/span> <span class=\"nc\">DemoCustomServiceProvider<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">ServiceProvider<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">boot<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/*...*\/<\/span><span class=\"p\">}<\/span>\n  \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">register<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">app<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">bind<\/span><span class=\"p\">(<\/span><span class=\"s1\">'App\\Library\\Services\\DemoOne'<\/span><span class=\"p\">,<\/span> <span class=\"k\">function<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$app<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n          <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">DemoOne<\/span><span class=\"p\">();<\/span>\n        <span class=\"p\">});<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>There are two important points here:<\/p>\n\n<ul>\n  <li>We have imported <code class=\"language-plaintext highlighter-rouge\">App\\Library\\Services\\DemoOne<\/code> so that we can use it. The class <code class=\"language-plaintext highlighter-rouge\">DemoOne<\/code> hasn\u2019t been created yet, but we\u2019ll do that in a moment.<\/li>\n  <li>In the register method, we used the <code class=\"language-plaintext highlighter-rouge\">bind<\/code> service container method to add our service binding to the container. Thus, whenever a dependency needs to be resolved <code class=\"language-plaintext highlighter-rouge\">App\\Library\\Services\\DemoOne<\/code>, it invokes a closure that instantiates and returns a <code class=\"language-plaintext highlighter-rouge\">App\\Library\\Services\\DemoOne<\/code>.<\/li>\n<\/ul>\n\n<p>To do this, you just need to create a <code class=\"language-plaintext highlighter-rouge\">app\/Library\/Services\/DemoOne.php<\/code>.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Library\\Services<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kd\">class<\/span> <span class=\"nc\">DemoOne<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">doSomethingUseful<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n      <span class=\"k\">return<\/span> <span class=\"s1\">'Output from DemoOne'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>And here is the code somewhere in your controller where the dependency will be injected.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Http\\Controllers<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Http\\Controllers\\Controller<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Library\\Services\\DemoOne<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kd\">class<\/span> <span class=\"nc\">TestController<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Controller<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">index<\/span><span class=\"p\">(<\/span><span class=\"kt\">DemoOne<\/span> <span class=\"nv\">$customServiceInstance<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">echo<\/span> <span class=\"nv\">$customServiceInstance<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">doSomethingUseful<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>This is a very simple class binding example. In fact, in the above example,\nthere is no need to create a service provider and implement the register method as we did,\nsince Laravel can automatically resolve it using reflection.<\/p>\n\n<p>A very important note from the Laravel documentation:<\/p>\n\n<blockquote>\n  <p>There is no need to bind classes into the container if they do not depend on any interfaces.\nThe container does not need to be instructed on how to build these objects, since it can automatically resolve these objects using reflection.<\/p>\n<\/blockquote>\n\n<p>On the other hand, it would be very helpful if you would bind an interface to a specific implementation. Let\u2019s take an example to understand this.<\/p>\n\n<p>Let\u2019s create a very simple interface in\n<span class=\"wb-bw\"><code class=\"language-plaintext highlighter-rouge\">app\/Library\/Services\/Contracts\/CustomServiceInterface.php<\/code>.<\/span><\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Library\\Services\\Contracts<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kd\">Interface<\/span> <span class=\"nc\">CustomServiceInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">doSomethingUseful<\/span><span class=\"p\">();<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Next, let\u2019s create two implementations of this interface. Basically, we just need to create two classes that implement the <code class=\"language-plaintext highlighter-rouge\">CustomServiceInterface<\/code>.<\/p>\n\n<p>Create a class <code class=\"language-plaintext highlighter-rouge\">DemoOne<\/code> in <code class=\"language-plaintext highlighter-rouge\">app\/Library\/Services\/DemoOne.php<\/code>.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Library\\Services<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Library\\Services\\Contracts\\CustomServiceInterface<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kd\">class<\/span> <span class=\"nc\">DemoOne<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">CustomServiceInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">doSomethingUseful<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n      <span class=\"k\">return<\/span> <span class=\"s1\">'Output from DemoOne'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Likewise, <code class=\"language-plaintext highlighter-rouge\">DemoTwo<\/code> will be in <code class=\"language-plaintext highlighter-rouge\">App\/Library\/Services\/DemoTwo.php<\/code>.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Library\\Services<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Library\\Services\\Contracts\\CustomServiceInterface<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kd\">class<\/span> <span class=\"nc\">DemoTwo<\/span> <span class=\"kd\">implements<\/span> <span class=\"nc\">CustomServiceInterface<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">doSomethingUseful<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n      <span class=\"k\">return<\/span> <span class=\"s1\">'Output from DemoTwo'<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Now, instead of binding a class, we will bind an interface. Open again <code class=\"language-plaintext highlighter-rouge\">DemoCustomServiceProvider.php<\/code> and modify the code as shown below.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Providers<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kn\">use<\/span> <span class=\"nc\">Illuminate\\Support\\ServiceProvider<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Library\\Services\\DemoOne<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kd\">class<\/span> <span class=\"nc\">DemoCustomServiceProvider<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">ServiceProvider<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">boot<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n    <span class=\"p\">}<\/span>\n  \n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">register<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"nv\">$this<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">app<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">bind<\/span><span class=\"p\">(<\/span>\n            <span class=\"s1\">'App\\Library\\Services\\Contracts\\CustomServiceInterface'<\/span><span class=\"p\">,<\/span>\n            <span class=\"k\">function<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$app<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n                <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">DemoOne<\/span><span class=\"p\">();<\/span>\n            <span class=\"p\">}<\/span>\n        <span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p><span class=\"wb-bw\">\nIn this case, we have bound the interface <code class=\"language-plaintext highlighter-rouge\">App\\Library\\Services\\Contracts\\CustomServiceInterface<\/code> to the implementation <code class=\"language-plaintext highlighter-rouge\">DemoOne<\/code>.\nTherefore, whenever a dependency needs to be resolved <code class=\"language-plaintext highlighter-rouge\">App\\Library\\Services\\Contracts\\CustomServiceInterface<\/code>,\nan instance will be created and an object will be returned <code class=\"language-plaintext highlighter-rouge\">App\\Library\\Services\\DemoOne<\/code>.\nNow that makes sense, doesn\u2019t it?\n<\/span><\/p>\n\n<p>Let\u2019s quickly review the controller code.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"cp\">&lt;?php<\/span>\n<span class=\"kn\">namespace<\/span> <span class=\"nn\">App\\Http\\Controllers<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Http\\Controllers\\Controller<\/span><span class=\"p\">;<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Library\\Services\\Contracts\\CustomServiceInterface<\/span><span class=\"p\">;<\/span>\n  \n<span class=\"kd\">class<\/span> <span class=\"nc\">TestController<\/span> <span class=\"kd\">extends<\/span> <span class=\"nc\">Controller<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">index<\/span><span class=\"p\">(<\/span><span class=\"kt\">CustomServiceInterface<\/span> <span class=\"nv\">$customServiceInstance<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">{<\/span>\n        <span class=\"k\">echo<\/span> <span class=\"nv\">$customServiceInstance<\/span><span class=\"o\">-&gt;<\/span><span class=\"nf\">doSomethingUseful<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>As you may have guessed, <code class=\"language-plaintext highlighter-rouge\">$customServiceInstance<\/code> must be an instance of <code class=\"language-plaintext highlighter-rouge\">App\\Library\\Services\\DemoOne<\/code>!\nThe beauty of this approach is that you can easily replace the implementation <code class=\"language-plaintext highlighter-rouge\">DemoOne<\/code> with another class.<\/p>\n\n<p>Let\u2019s say you want to use an implementation <code class=\"language-plaintext highlighter-rouge\">DemoTwo<\/code> instead of <code class=\"language-plaintext highlighter-rouge\">DemoOne<\/code>. In this case,\nyou just need to make the following changes to the service provider <code class=\"language-plaintext highlighter-rouge\">DemoCustomServiceProvider.php<\/code>.<\/p>\n\n<p>Now let\u2019s make small changes to the code<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">\/\/ Find the following line:<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Library\\Services\\DemoOne<\/span><span class=\"p\">;<\/span>\n<span class=\"c1\">\/\/ And replace it with:<\/span>\n<span class=\"kn\">use<\/span> <span class=\"nc\">App\\Library\\Services\\DemoTwo<\/span><span class=\"p\">;<\/span>\n\n<span class=\"c1\">\/\/ Find this in a similar way:<\/span>\n<span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">DemoOne<\/span><span class=\"p\">();<\/span>\n<span class=\"c1\">\/\/ This should be replaced with:<\/span>\n<span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">DemoTwo<\/span><span class=\"p\">();<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>The same approach can be used if you want to replace any core implementation with your own.\nAnd it\u2019s not just the bind method that you could use to bind a service to a container;\nThe Laravel container provides various binding methods. Please see the official Laravel documentation for a complete reference.<\/p>\n\n<p>The next candidate is a method <code class=\"language-plaintext highlighter-rouge\">boot<\/code> that can be used to extend the functionality of Laravel\u2019s core.\nIn this method, you can access all services that have been registered using the register method on service providers.\nIn most cases, you want to register event listeners on this method that will fire when something happens.<\/p>\n\n<p>Let\u2019s look at a few examples that require the implementation of the boot method.<\/p>\n\n<p>You want to add your own form field validation tool to Laravel.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">boot<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"nc\">Validator<\/span><span class=\"o\">::<\/span><span class=\"nf\">extend<\/span><span class=\"p\">(<\/span><span class=\"s1\">'my_custom_validator'<\/span><span class=\"p\">,<\/span> <span class=\"k\">function<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$attribute<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$value<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$parameters<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$validator<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ validation logic goes here...<\/span>\n    <span class=\"p\">});<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>If you want to register a display builder, this is the perfect place to do it! In fact, you could say that the boot method is often used to add display builders!<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">boot<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"nc\">View<\/span><span class=\"o\">::<\/span><span class=\"nf\">composer<\/span><span class=\"p\">(<\/span>\n        <span class=\"s1\">'demo'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'App\\Http\\ViewComposers\\DemoComposer'<\/span>\n    <span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>Of course, you need to first import the facade <code class=\"language-plaintext highlighter-rouge\">Illuminate\\Support\\Facades\\View<\/code> in your service provider.<\/p>\n\n<p>In the same territory, you can share data across multiple views!<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">boot<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"nc\">View<\/span><span class=\"o\">::<\/span><span class=\"nf\">share<\/span><span class=\"p\">(<\/span><span class=\"s1\">'key'<\/span><span class=\"p\">,<\/span> <span class=\"s1\">'value'<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>It can also be used to define explicit model bindings.<\/p>\n\n<div class=\"language-php highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"n\">boot<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">{<\/span>\n    <span class=\"k\">parent<\/span><span class=\"o\">::<\/span><span class=\"nf\">boot<\/span><span class=\"p\">();<\/span>\n  \n    <span class=\"nc\">Route<\/span><span class=\"o\">::<\/span><span class=\"nf\">model<\/span><span class=\"p\">(<\/span><span class=\"s1\">'user'<\/span><span class=\"p\">,<\/span> <span class=\"nc\">App\\User<\/span><span class=\"o\">::<\/span><span class=\"n\">class<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/div><\/div>\n\n<p>These were a few examples to demonstrate the use of the boot method. The more you dive into Laravel, the more reasons you will find to implement it!<\/p>\n"}]}