<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Indunil Peramuna</title>
    <description>The latest articles on DEV Community by Indunil Peramuna (@indunilperamuna).</description>
    <link>https://dev.to/indunilperamuna</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F989217%2F321d5b6d-dc2b-4cc7-a822-305862332d67.jpeg</url>
      <title>DEV Community: Indunil Peramuna</title>
      <link>https://dev.to/indunilperamuna</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/indunilperamuna"/>
    <language>en</language>
    <item>
      <title>The One-Line MySQL 8 Switch to Auto-Optimize Your Dedicated Database Infrastructure</title>
      <dc:creator>Indunil Peramuna</dc:creator>
      <pubDate>Fri, 05 Jun 2026 13:49:06 +0000</pubDate>
      <link>https://dev.to/indunilperamuna/the-one-line-mysql-8-switch-to-auto-optimize-your-dedicated-database-infrastructure-3j60</link>
      <guid>https://dev.to/indunilperamuna/the-one-line-mysql-8-switch-to-auto-optimize-your-dedicated-database-infrastructure-3j60</guid>
      <description>&lt;p&gt;As an application scales, managing the database layer transitions from an active development task to a pure infrastructure challenge. If you have ever opened a production MySQL &lt;code&gt;my.cnf&lt;/code&gt; configuration file, you have likely stared down the anxiety-inducing task of manually tuning memory allocations, redo logs, and system-level flush methods. &lt;/p&gt;

&lt;p&gt;Get it wrong, and you introduce artificial disk bottlenecks or trigger system lockups. Get it right, and your database handles high concurrency with ease.&lt;/p&gt;

&lt;p&gt;Fortunately, if your infrastructure strategy includes moving your database to its own hardware—such as a dedicated Write Primary node or a standalone Read Replica cluster—MySQL 8 introduced a feature that removes the trial-and-error entirely. &lt;/p&gt;

&lt;p&gt;By adding a single, powerful line to your config block, MySQL transforms into a self-tuning engine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;innodb_dedicated_server&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ON&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's do a deep architectural dive into what this switch does under the hood, the four heavy-hitting variables it auto-adjusts, how to prepare your configuration files, and the critical guardrails you must enforce.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Happens Under the Hood?
&lt;/h2&gt;

&lt;p&gt;When the MySQL daemon initializes with &lt;code&gt;innodb_dedicated_server = ON&lt;/code&gt;, it bypasses standard static defaults. Instead, it probes the underlying operating system at runtime to detect the &lt;strong&gt;total available physical RAM and CPU cores&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Using those metrics, it dynamically recalculates and tunes the four most critical components of the InnoDB storage engine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                  ┌──────────────────────────────────────────────┐
                  │        innodb_dedicated_server = ON          │
                  └──────────────────────┬───────────────────────┘
                                         │ (Probes Host Hardware)
                                         ▼
         ┌───────────────────────────────┴───────────────────────────────┐
         ▼                               ▼                               ▼
┌─────────────────┐             ┌─────────────────┐             ┌─────────────────┐
│   Buffer Pool   │             │  Flush Method   │             │    Redo Logs    │
│  Scales up to   │             │   Switches to   │             │    Optimizes    │
│   80% of RAM    │             │    O_DIRECT     │             │ Write Buffering │
└─────────────────┘             └─────────────────┘             └─────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the exact engineering breakdown of what it auto-adjusts:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;innodb_buffer_pool_size&lt;/code&gt; (The Memory Footprint)
&lt;/h3&gt;

&lt;p&gt;The buffer pool is the primary memory area where InnoDB caches table data and indexes. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Default Danger:&lt;/strong&gt; Out of the box, MySQL defaults this to a tiny &lt;strong&gt;128 MB&lt;/strong&gt;, which kills production performance instantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Auto-Tuned Reality:&lt;/strong&gt; It dynamically scales based on your machine's physical hardware capacity:

&lt;ul&gt;
&lt;li&gt;Server RAM &amp;lt; 1 GB: Stays at the baseline 128 MB.&lt;/li&gt;
&lt;li&gt;Server RAM &amp;lt;= 4 GB: Allocates &lt;strong&gt;50%&lt;/strong&gt; of total system RAM.&lt;/li&gt;
&lt;li&gt;Server RAM &amp;lt; 16 GB: Allocates &lt;strong&gt;75%&lt;/strong&gt; of total system RAM.&lt;/li&gt;
&lt;li&gt;Server RAM &amp;gt;= 16 GB: Aggressively claims &lt;strong&gt;80%&lt;/strong&gt; of total system RAM.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;code&gt;innodb_flush_method&lt;/code&gt; (Eliminating OS Overhead)
&lt;/h3&gt;

&lt;p&gt;On Linux systems, enabling the dedicated server flag forces the engine to use the &lt;strong&gt;&lt;code&gt;O_DIRECT&lt;/code&gt;&lt;/strong&gt; flush method.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why this is critical:&lt;/strong&gt; By default, the operating system attempts to cache database files in its own filesystem page cache, while MySQL is simultaneously caching them inside its own buffer pool. This "double caching" is highly inefficient and risks memory exhaustion. &lt;code&gt;O_DIRECT&lt;/code&gt; tells the engine to bypass the OS page cache completely, routing I/O throughput straight to disk and leaving memory management entirely to InnoDB.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;code&gt;innodb_log_file_size&lt;/code&gt; &amp;amp; &lt;code&gt;innodb_log_files_in_group&lt;/code&gt; (Redo Log Optimization)
&lt;/h3&gt;

&lt;p&gt;Redo logs record every single data modification before it is asynchronously flushed to the actual tablespace. If these logs are too small, the database chokes on heavy transaction bursts because it has to freeze operations to flush log buffers to disk. The auto-tuner dynamically scales the redo log sizes up to a calculated ratio of your total buffer pool size, maximizing write concurrency.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;code&gt;innodb_log_buffer_size&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This defines the memory buffer size that InnoDB utilizes before writing data out to the redo logs on disk. The auto-tuner scales this proportionally, ensuring massive or concurrent transactions don't instantly suffer from disk I/O latency bottlenecks.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ The Implementation Rule: Clean Your Config First
&lt;/h2&gt;

&lt;p&gt;Before you flip this switch, you must perform a clean-up of your existing configuration. &lt;strong&gt;This is where many production migrations fail.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have explicit, old lines defining any of these four values anywhere else in your &lt;code&gt;my.cnf&lt;/code&gt; or &lt;code&gt;mysqld.cnf&lt;/code&gt; files, MySQL will prioritize those hardcoded parameters. It will silently override the auto-tuner, completely defeating the purpose of the setting.&lt;/p&gt;

&lt;p&gt;Open your configuration file and &lt;strong&gt;delete or comment out (&lt;code&gt;#&lt;/code&gt;)&lt;/strong&gt; the following blocks if they exist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# =====================================================================
# REMOVE OR COMMENT THESE OUT TO LET DEDICATED SERVER TAKE CONTROL:
# =====================================================================
# innodb_buffer_pool_size = 2G
# innodb_log_file_size = 512M
# innodb_log_buffer_size = 16M
# innodb_flush_method = O_DIRECT
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the legacy parameters are scrubbed, append the magic line under your core server block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[mysqld]&lt;/span&gt;
&lt;span class="py"&gt;innodb_dedicated_server&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ON&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file and safely restart your database service to let it evaluate the environment and step up its tuning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚠️ The Architectural Guardrails (When NOT to use it)
&lt;/h2&gt;

&lt;p&gt;As senior engineers, we must focus on the trade-offs. The name of this feature is literal: &lt;strong&gt;&lt;code&gt;dedicated_server&lt;/code&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;You must only use this flag if the target server is a 100% dedicated database box.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do NOT turn this on if:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You run a compact "monolith" architecture where Nginx, PHP-FPM, Redis, and MySQL all co-exist on the same single VPS or bare-metal host.&lt;/li&gt;
&lt;li&gt;You are deploying inside a local development environment (e.g., standard Docker Compose setups or lightweight dev virtual machines).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Risk:&lt;/strong&gt; If your server has 32 GB of RAM, MySQL will cleanly claim 25.6 GB (80%) the moment it boots. If you have application workers like PHP-FPM or memory caches like Redis competing on that exact same operating system instance, the system will face instantaneous memory exhaustion. &lt;/p&gt;

&lt;p&gt;When the OS hits that wall, the Linux Kernel's &lt;strong&gt;Out-Of-Memory (OOM) Killer&lt;/strong&gt; will trigger, abruptly terminating random processes to protect the host machine. More often than not, it will kill your web workers or crash the database daemon itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;When scaling infrastructure out—moving from single instances to complex multi-node topologies like primary-replica splitting—reducing manual operational overhead is key. &lt;/p&gt;

&lt;p&gt;Leveraging &lt;code&gt;innodb_dedicated_server = ON&lt;/code&gt; allows your stateless database layers to automatically optimize themselves to match whatever compute tier you throw them on, freeing you up to focus on application architecture rather than micro-managing database configurations.&lt;/p&gt;

&lt;p&gt;Have you transitioned your production clusters to use MySQL's native auto-tuning? Let's talk shop and share experiences in the comments below! 👇&lt;/p&gt;

</description>
      <category>mysql</category>
      <category>devops</category>
      <category>database</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Supercharge Your PHP Apps with FrankenPHP Classic Mode</title>
      <dc:creator>Indunil Peramuna</dc:creator>
      <pubDate>Tue, 13 Jan 2026 13:31:17 +0000</pubDate>
      <link>https://dev.to/indunilperamuna/supercharge-your-php-apps-with-frankenphp-classic-mode-5gb5</link>
      <guid>https://dev.to/indunilperamuna/supercharge-your-php-apps-with-frankenphp-classic-mode-5gb5</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nmtf4in6lsicpb563su.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nmtf4in6lsicpb563su.png" alt="FrankenPHP Hero Image" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Supercharge Your PHP Apps with FrankenPHP Classic Mode
&lt;/h1&gt;

&lt;p&gt;PHP deployment hasn't seen a shift this exciting in years. FrankenPHP is here, and while everyone talks about "worker mode", &lt;strong&gt;Classic Mode&lt;/strong&gt; is the immediate upgrade your servers need.&lt;/p&gt;

&lt;p&gt;I've written a comprehensive guide on how to replace PHP-FPM with FrankenPHP behind Nginx.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Classic Mode?
&lt;/h2&gt;

&lt;p&gt;It allows FrankenPHP to act as a standard request handler, just faster and simpler than FPM. It integrates perfectly with your existing Nginx setups.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why it's better:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;103 Early Hints&lt;/strong&gt;: Speeds up perceived load times by sending assets before the page is ready.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Observability&lt;/strong&gt;: Detailed Prometheus metrics and structured logging out of the box.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Robustness&lt;/strong&gt;: Benefits from Go's memory safety for the server layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Static vs Dynamic (Glibc) Builds
&lt;/h2&gt;

&lt;p&gt;One of huge advantages of FrankenPHP is the &lt;strong&gt;static build&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Static&lt;/strong&gt;: Zero dependencies. Runs on Alpine, Debian, CentOS without needing libraries like &lt;code&gt;libpng&lt;/code&gt; installed. Perfect for containers.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Dynamic&lt;/strong&gt;: Uses system libraries. Better if you need specific system-patched versions of libs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Tool
&lt;/h2&gt;

&lt;p&gt;I also released an open-source tool, &lt;code&gt;frankenphp-classic-setup&lt;/code&gt;, which automates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Binary installation (smartly chooses &lt;strong&gt;Static&lt;/strong&gt; or &lt;strong&gt;Dynamic&lt;/strong&gt; based on need).&lt;/li&gt;
&lt;li&gt; Systemd service creation.&lt;/li&gt;
&lt;li&gt; Nginx configuration generation.&lt;/li&gt;
&lt;li&gt; CLI wrapper setup (use &lt;code&gt;fphp&lt;/code&gt; instead of &lt;code&gt;php&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Guide
&lt;/h2&gt;

&lt;p&gt;I cover the manual "hard way" to help you learn, and the automated "easy way" to get you into production fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual Steps Summary
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; Download &lt;code&gt;frankenphp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Set up a systemd service pointing to your doc root.&lt;/li&gt;
&lt;li&gt; Proxy Nginx to port 9000.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Automated Way
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/iperamuna/frankenphp-classic-setup.git
&lt;span class="nb"&gt;sudo&lt;/span&gt; ./setup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/iperamuna/frankenphp-classic-setup/blob/main/blog-post.md" rel="noopener noreferrer"&gt;Read the full technical breakdown and guide here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;About the Author&lt;/strong&gt;&lt;br&gt;
Indunil Peramuna is a software engineer passionate about optimizing modern web infrastructure.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  GitHub: &lt;a href="https://github.com/iperamuna" rel="noopener noreferrer"&gt;@iperamuna&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  LinkedIn: &lt;a href="https://www.linkedin.com/in/iperamuna/" rel="noopener noreferrer"&gt;indunilperamuna&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  Telegram: &lt;a href="https://t.me/iperamuna" rel="noopener noreferrer"&gt;@iperamuna&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  Discord: iperamuna&lt;/li&gt;
&lt;li&gt;  WhatsApp: +94777671771&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>webdev</category>
      <category>developertools</category>
      <category>devops</category>
    </item>
    <item>
      <title>Why HTML Fragment Caching is the Performance Game-Changer Your Laravel App Needs</title>
      <dc:creator>Indunil Peramuna</dc:creator>
      <pubDate>Thu, 16 Oct 2025 02:00:09 +0000</pubDate>
      <link>https://dev.to/indunilperamuna/why-html-fragment-caching-is-the-performance-game-changer-your-laravel-app-needs-11cf</link>
      <guid>https://dev.to/indunilperamuna/why-html-fragment-caching-is-the-performance-game-changer-your-laravel-app-needs-11cf</guid>
      <description>&lt;p&gt;&lt;em&gt;As a Senior Software Engineer who's spent years optimizing web applications, I've seen firsthand how the right caching strategy can transform user experience and reduce infrastructure costs. Today, I want to share insights about a critical but often overlooked caching technique: HTML Fragment Caching.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hidden Performance Bottleneck
&lt;/h2&gt;

&lt;p&gt;Picture this: Your Laravel application is serving a dashboard with multiple widgets - user statistics, product recommendations, recent orders, and activity feeds. Each widget requires database queries, data processing, and Blade template rendering. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem?&lt;/strong&gt; Even with Redis caching your database queries, you're still re-rendering the same HTML markup on every request. That's like caching the ingredients but cooking the meal fresh every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Traditional Caching Approach (And Why It Falls Short)
&lt;/h2&gt;

&lt;p&gt;Most developers stop at caching database results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This caches the data, but not the rendered HTML&lt;/span&gt;
&lt;span class="nv"&gt;$products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'products:featured'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;featured&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'category'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// This still runs on every request&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'dashboard.products'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;compact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'products'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The issue:&lt;/strong&gt; You're caching the data, but the expensive Blade rendering, HTML generation, and string concatenation still happen on every request. In high-traffic applications, this can mean thousands of unnecessary CPU cycles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter HTML Fragment Caching
&lt;/h2&gt;

&lt;p&gt;HTML Fragment Caching takes a different approach - it caches the final rendered HTML output, not just the data. This means:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Zero database queries&lt;/strong&gt; on cache hits&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Zero Blade rendering&lt;/strong&gt; on cache hits&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Zero string processing&lt;/strong&gt; on cache hits&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Instant HTML delivery&lt;/strong&gt; to users  &lt;/p&gt;
&lt;h2&gt;
  
  
  Real-World Impact
&lt;/h2&gt;

&lt;p&gt;In a recent project, implementing HTML fragment caching reduced average response times from 800ms to 120ms for dashboard pages. That's an &lt;strong&gt;85% performance improvement&lt;/strong&gt; with zero code changes to business logic.&lt;/p&gt;

&lt;p&gt;Here's what the transformation looks like:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before (Traditional Caching):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request → Database Query (cached) → Data Processing → Blade Rendering → HTML Output
Time: ~800ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (HTML Fragment Caching):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request → Cached HTML Output
Time: ~120ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Introducing Laravel HTML Fragment Cache
&lt;/h2&gt;

&lt;p&gt;As an open source contributor, I've been working on a package that makes HTML fragment caching dead simple in Laravel applications. Here's why it's different:&lt;/p&gt;

&lt;h3&gt;
  
  
  🎯 &lt;strong&gt;Universal Cache Support&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Works with Redis, Memcached, Database, File, Array, DynamoDB, and Octane - no vendor lock-in.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 &lt;strong&gt;Developer-Friendly&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simple facade usage&lt;/span&gt;
&lt;span class="nv"&gt;$html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FragmentCache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;rememberHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"customer:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$customer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'components.products-widget'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s1"&gt;'products'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$customer&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;products&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;featured&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'6 hours'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🎨 &lt;strong&gt;Blade Directive Support&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@fragmentCache('products:featured')
    &amp;lt;div class="featured-products"&amp;gt;
        @foreach($featuredProducts as $product)
            &amp;lt;div class="product"&amp;gt;{{ $product-&amp;gt;name }}&amp;lt;/div&amp;gt;
        @endforeach
    &amp;lt;/div&amp;gt;
@endFragmentCache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🚀 &lt;strong&gt;Livewire Integration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Perfect for caching expensive Livewire component rendering with a simple trait:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductDashboard&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;CachesRenderedHtml&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;renderCached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Expensive operations only run on cache miss&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'livewire.product-dashboard'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Business Case for HTML Fragment Caching
&lt;/h2&gt;

&lt;h3&gt;
  
  
  💰 &lt;strong&gt;Cost Reduction&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduced server load:&lt;/strong&gt; Less CPU usage means smaller server instances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lower database costs:&lt;/strong&gt; Fewer queries mean less database load&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CDN efficiency:&lt;/strong&gt; Cached HTML can be served from edge locations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📈 &lt;strong&gt;User Experience&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Faster page loads:&lt;/strong&gt; Users see content instantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better SEO:&lt;/strong&gt; Google rewards fast-loading pages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher conversion rates:&lt;/strong&gt; Every 100ms improvement can increase conversions by 1%&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🛠️ &lt;strong&gt;Developer Experience&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero refactoring:&lt;/strong&gt; Works with existing code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy debugging:&lt;/strong&gt; Can be disabled per environment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible invalidation:&lt;/strong&gt; Cache specific fragments when data changes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to Use HTML Fragment Caching
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Perfect for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dashboard widgets and components&lt;/li&gt;
&lt;li&gt;Product listings and catalogs&lt;/li&gt;
&lt;li&gt;User-specific content (with proper identifiers)&lt;/li&gt;
&lt;li&gt;API responses that return HTML&lt;/li&gt;
&lt;li&gt;Expensive report generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Not ideal for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Highly dynamic, user-specific content&lt;/li&gt;
&lt;li&gt;Real-time data that changes frequently&lt;/li&gt;
&lt;li&gt;Content that's already cached at the CDN level&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;The package is designed to be production-ready with comprehensive documentation, tests, and examples. It follows Laravel conventions and integrates seamlessly with existing applications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require iperamuna/laravel-html-fragment-cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Open Source Philosophy
&lt;/h2&gt;

&lt;p&gt;As someone who contributes to open source projects, I believe in building tools that solve real problems for developers. This package emerged from solving performance challenges in production applications, and I'm excited to share it with the Laravel community.&lt;/p&gt;

&lt;p&gt;The source code is available on GitHub with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Comprehensive test coverage&lt;/li&gt;
&lt;li&gt;✅ Detailed documentation&lt;/li&gt;
&lt;li&gt;✅ Real-world examples&lt;/li&gt;
&lt;li&gt;✅ CI/CD pipeline&lt;/li&gt;
&lt;li&gt;✅ MIT license&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HTML Fragment Caching&lt;/strong&gt; can provide massive performance improvements with minimal code changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache the output, not just the data&lt;/strong&gt; - this is often the missing piece in performance optimization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose the right tool&lt;/strong&gt; - make sure your caching solution works with your existing infrastructure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure the impact&lt;/strong&gt; - always benchmark before and after implementing caching strategies&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What's Your Experience?
&lt;/h2&gt;

&lt;p&gt;I'd love to hear about your caching strategies and performance optimization experiences. What challenges have you faced with caching in your applications? Have you tried HTML fragment caching before?&lt;/p&gt;

&lt;p&gt;Let's discuss in the comments below! 👇&lt;/p&gt;




&lt;h2&gt;
  
  
  🔗 &lt;strong&gt;Share This Article&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you found this article helpful, please consider sharing it with your network:&lt;/p&gt;

&lt;p&gt;• 📘 &lt;a href="https://www.facebook.com/sharer/sharer.php?u=https://dev.to/indunilperamuna/why-html-fragment-caching-is-the-performance-game-changer-your-laravel-app-needs-11cf"&gt;Facebook&lt;/a&gt; • 💼 &lt;a href="https://www.linkedin.com/sharing/share-offsite/?url=https://dev.to/indunilperamuna/why-html-fragment-caching-is-the-performance-game-changer-your-laravel-app-needs-11cf"&gt;LinkedIn&lt;/a&gt; • 🐦 &lt;a href="https://twitter.com/intent/tweet?text=Check%20out%20this%20article%20about%20HTML%20Fragment%20Caching%20in%20Laravel&amp;amp;url=https://dev.to/indunilperamuna/why-html-fragment-caching-is-the-performance-game-changer-your-laravel-app-needs-11cf"&gt;Twitter&lt;/a&gt; • 💬 &lt;a href="https://wa.me/?text=Check%20out%20this%20article%20about%20HTML%20Fragment%20Caching%20in%20Laravel:%20https://dev.to/indunilperamuna/why-html-fragment-caching-is-the-performance-game-changer-your-laravel-app-needs-11cf"&gt;WhatsApp&lt;/a&gt; • 📋 &lt;a href="https://dev.to/indunilperamuna/why-html-fragment-caching-is-the-performance-game-changer-your-laravel-app-needs-11cf"&gt;&lt;code&gt;Copy link&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; #Laravel #PHP #WebDevelopment #Performance #Caching #OpenSource #SoftwareEngineering #WebOptimization&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/iperamuna/laravel-html-fragment-cache" rel="noopener noreferrer"&gt;iperamuna/laravel-html-fragment-cache&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Connect with me for more insights on web development, performance optimization, and open source contributions.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://facebook.com/ndunil.priyashan" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt; • &lt;a href="https://linkedin.com/in/iperamuna" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;  • &lt;a href="https://wa.me/+94777671771" rel="noopener noreferrer"&gt;WhatsApp&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>performance</category>
    </item>
    <item>
      <title>Enhancing Object-Oriented Design with Traits, Interfaces, and Abstract Classes</title>
      <dc:creator>Indunil Peramuna</dc:creator>
      <pubDate>Mon, 29 Jul 2024 18:15:18 +0000</pubDate>
      <link>https://dev.to/indunilperamuna/enhancing-object-oriented-design-with-traits-interfaces-and-abstract-classes-4647</link>
      <guid>https://dev.to/indunilperamuna/enhancing-object-oriented-design-with-traits-interfaces-and-abstract-classes-4647</guid>
      <description>&lt;p&gt;In object-oriented programming, maintaining a clean and modular design is crucial for creating scalable and maintainable applications. By leveraging design patterns and principles, developers can create code that is both flexible and easy to extend. This article explores how using traits, interfaces, and abstract classes can enhance your design, with a focus on Data Transfer Objects (DTOs) as a practical example.&lt;/p&gt;

&lt;h4&gt;
  
  
  Understanding the Basics: Traits, Interfaces, and Abstract Classes
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Traits&lt;/strong&gt;:&lt;br&gt;
Traits are a mechanism for code reuse in single inheritance languages like PHP. They allow you to define methods that can be used in multiple classes, promoting code reuse without requiring inheritance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interfaces&lt;/strong&gt;:&lt;br&gt;
Interfaces define a contract that classes must adhere to. They specify which methods a class must implement, ensuring consistency and allowing for polymorphism.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstract Classes&lt;/strong&gt;:&lt;br&gt;
Abstract classes provide a base class that other classes can extend. They can include abstract methods (which must be implemented by subclasses) and concrete methods (which can be used as-is or overridden).&lt;/p&gt;
&lt;h4&gt;
  
  
  Practical Example: Implementing Traits, Interfaces, and Abstract Classes in DTOs
&lt;/h4&gt;

&lt;p&gt;To illustrate how traits, interfaces, and abstract classes work together, let's use the example of Data Transfer Objects (DTOs). DTOs are used to transfer data between different layers of an application without including business logic. We'll create a flexible and maintainable DTO system by leveraging these object-oriented principles.&lt;/p&gt;
&lt;h5&gt;
  
  
  1. &lt;strong&gt;Defining the Abstract Base Class&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;The &lt;code&gt;BaseDTO&lt;/code&gt; abstract class provides common functionality for all DTOs, such as converting data to an array or JSON format and initialising from an array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;App/Dto/BaseDTO.php&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Dto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Abstract class BaseDTO
 * 
 * Provides common functionality for Data Transfer Objects (DTOs).
 */&lt;/span&gt;
&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseDTO&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * BaseDTO constructor.
     *
     * @param array $data Initial data to populate the DTO.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setFromArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Convert the DTO to an array.
     *
     * @return array The DTO as an associative array.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;get_object_vars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;array_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$properties&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$property&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$property&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Convert the DTO to a JSON string.
     *
     * @return string The DTO as a JSON string.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;toJson&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Set the DTO properties from an array.
     *
     * @param array $data The data to set on the DTO.
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;property_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  2. &lt;strong&gt;Creating Specific Interfaces&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Interfaces define the specific methods that our DTOs need to implement based on different data sources, such as models, APIs, and CSV files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;App/Contracts/Dto/SetFromModel.php&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * Interface SetFromModel
 * 
 * Defines a method for setting DTO properties from a model.
 */&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;SetFromModel&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Set DTO properties from a model.
     *
     * @param mixed $model The model to set properties from.
     * @return self
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;App/Contracts/Dto/SetFromAPI.php&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * Interface SetFromAPI
 * 
 * Defines a method for setting DTO properties from API data.
 */&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;SetFromAPI&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Set DTO properties from API data.
     *
     * @param array $data The API data to set properties from.
     * @return self
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;App/Contracts/Dto/SetFromCSV.php&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * Interface SetFromCSV
 * 
 * Defines a method for setting DTO properties from CSV data.
 */&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;SetFromCSV&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Set DTO properties from CSV data.
     *
     * @param array $data The CSV data to set properties from.
     * @return self
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromCSV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  3. &lt;strong&gt;Implementing Traits for Reusability&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Traits allow us to define reusable methods for setting data from various sources, making it easy to share functionality across different DTOs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;App/Traits/Dto/SetFromModelTrait.php&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Traits\Dto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;trait&lt;/span&gt; &lt;span class="nc"&gt;SetFromModelTrait&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;get_object_vars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;property_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;App/Traits/Dto/SetFromAPITrait.php&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Traits\Dto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Trait SetFromModelTrait
 * 
 * Provides a method for setting DTO properties from a model.
 */&lt;/span&gt;
&lt;span class="kd"&gt;trait&lt;/span&gt; &lt;span class="nc"&gt;SetFromModelTrait&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Set DTO properties from a model.
     *
     * @param mixed $model The model to set properties from.
     * @return self
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;get_object_vars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;property_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;App/Traits/Dto/SetFromCSVTrait.php&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Traits\Dto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Trait SetFromCSVTrait
 * 
 * Provides a method for setting DTO properties from CSV data.
 */&lt;/span&gt;
&lt;span class="kd"&gt;trait&lt;/span&gt; &lt;span class="nc"&gt;SetFromCSVTrait&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Set DTO properties from CSV data.
     *
     * @param array $data The CSV data to set properties from.
     * @return self
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromCSV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Assuming CSV data follows a specific structure&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;explode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  4. &lt;strong&gt;Implementing the Concrete DTO Class&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Finally, implement the concrete &lt;code&gt;PropertyDTO&lt;/code&gt; class that utilizes the abstract class, interfaces, and traits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\DTO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Contracts\SetFromModel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Contracts\SetFromAPI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Contracts\SetFromCSV&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\DTO\Traits\SetFromModelTrait&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\DTO\Traits\SetFromAPITrait&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\DTO\Traits\SetFromCSVTrait&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Class PropertyDTO
 * 
 * Represents a Property Data Transfer Object.
 */&lt;/span&gt;
&lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PropertyDTO&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseDTO&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;SetFromModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SetFromAPI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SetFromCSV&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;SetFromModelTrait&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SetFromAPITrait&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SetFromCSVTrait&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * @var string The name of the property.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * @var string The address of the property.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$address&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * @var float The price of the property.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="nv"&gt;$price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * @var ?string The subscription type of the property.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;?string&lt;/span&gt; &lt;span class="nv"&gt;$subscription&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * @var ?array The assets of the property.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;?array&lt;/span&gt; &lt;span class="nv"&gt;$assets&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Other specific methods can be added here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Best Practices for Using Traits, Interfaces, and Abstract Classes
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Encapsulation of Behavior&lt;/strong&gt;: Use traits to encapsulate common behavior that can be reused across multiple classes, reducing duplication and improving maintainability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Defining Clear Contracts&lt;/strong&gt;: Interfaces should define clear contracts for what methods a class must implement, ensuring consistency and allowing for easy swapping of implementations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Providing Base Functionality&lt;/strong&gt;: Abstract classes offer a base for shared functionality, allowing subclasses to extend and customize as needed while maintaining a common structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhancing Flexibility&lt;/strong&gt;: Combining these techniques allows for a flexible design where classes can implement only the necessary interfaces and use relevant traits, making it easier to extend and adapt your code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Maintaining Consistency&lt;/strong&gt;: By using abstract classes and traits, you ensure that your code remains consistent and follows a predictable pattern, which is crucial for long-term maintainability.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;Integrating traits, interfaces, and abstract classes into your design provides a powerful way to manage and structure your code. By applying these principles, you create a modular, maintainable, and scalable system that adheres to best practices in object-oriented programming. Whether you're working with DTOs or other components, leveraging these techniques helps ensure that your codebase remains clean and adaptable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Embracing object-oriented principles and patterns such as traits, interfaces, and abstract classes not only improves code quality but also enhances your ability to manage complex systems. By understanding and applying these concepts, you can build robust applications that are both flexible and maintainable.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Explore the Advantages of Data Transfer Objects (DTOs) and How PHP 8.2 Readonly Classes Can Elevate Your Laravel Code</title>
      <dc:creator>Indunil Peramuna</dc:creator>
      <pubDate>Mon, 29 Jul 2024 18:10:25 +0000</pubDate>
      <link>https://dev.to/indunilperamuna/explore-the-advantages-of-data-transfer-objects-dtos-and-how-php-82-readonly-classes-can-elevate-your-laravel-code-4fk0</link>
      <guid>https://dev.to/indunilperamuna/explore-the-advantages-of-data-transfer-objects-dtos-and-how-php-82-readonly-classes-can-elevate-your-laravel-code-4fk0</guid>
      <description>&lt;p&gt;In modern web application development, efficiently and securely managing and transferring data is crucial. One design pattern that significantly aids in this process is the Data Transfer Object (DTO). This post will delve into the advantages of using DTOs, particularly in a Laravel application, and show how PHP 8.2 readonly classes can further enhance their benefits.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Data Transfer Object (DTO)?
&lt;/h3&gt;

&lt;p&gt;A Data Transfer Object (DTO) is a simple object designed to carry data between processes or systems. Unlike typical models or entities, DTOs are free from business logic. They encapsulate data, providing a clear and structured way to transfer information between different layers of an application or between various systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  DTO Pattern
&lt;/h3&gt;

&lt;p&gt;The DTO pattern is utilized to transfer data across different subsystems within a software application. The main objectives of using DTOs are to minimize the number of method calls, aggregate the necessary data, and offer a structured approach to managing data transformations and validations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of Using DTOs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Separation of Concerns:&lt;/strong&gt; DTOs isolate business logic from data representation, resulting in cleaner, more maintainable code that’s easier to understand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Validation:&lt;/strong&gt; DTOs allow for validation of data before it's processed by other application layers, ensuring that only valid data is used.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistency:&lt;/strong&gt; By providing a consistent structure for data transfer, DTOs simplify the management and processing of data from various sources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security:&lt;/strong&gt; DTOs can safeguard your application against unauthorized data manipulation by controlling which data is accessible and modifiable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testing:&lt;/strong&gt; Since DTOs are straightforward objects without embedded business logic, they are simpler to mock and test.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Transformation:&lt;/strong&gt; DTOs facilitate the transformation of data into formats required by different application layers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Immutability:&lt;/strong&gt; DTOs often promote immutability, meaning once created, their state cannot change. This feature brings several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Predictability:&lt;/strong&gt; Immutable objects are predictable and easier to reason about, as their state remains constant post-creation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread-Safety:&lt;/strong&gt; Immutability inherently supports thread-safety, simplifying concurrent processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging:&lt;/strong&gt; Debugging is easier with immutable objects because their state is guaranteed to remain unchanged throughout their lifecycle.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  PHP 8.2 and Readonly Classes
&lt;/h3&gt;

&lt;p&gt;With PHP 8.2, the introduction of readonly classes enhances the use of DTOs. Readonly classes eliminate the need to explicitly define properties as readonly, simplifying your DTO implementations. Here’s how PHP 8.2’s readonly classes improve DTOs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Code:&lt;/strong&gt; Readonly classes automatically make properties immutable, reducing boilerplate code and improving clarity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Security:&lt;/strong&gt; By ensuring properties cannot be modified once set, readonly classes enhance data integrity and security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved Maintainability:&lt;/strong&gt; The use of readonly classes leads to cleaner, more maintainable code, as the immutability of data is enforced by the language itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Example: Using DTOs in a Property Management System
&lt;/h4&gt;

&lt;p&gt;Let's consider a property management system where properties can come from various sources such as an API and CSV imports. We can use DTOs to create the Property model, Subscriptions, Assets, etc., ensuring that the data is consistent and validated across the application.&lt;/p&gt;

&lt;h5&gt;
  
  
  Defining the PropertyDTO
&lt;/h5&gt;

&lt;p&gt;First, let's define a &lt;code&gt;PropertyDTO&lt;/code&gt; class:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;app/DTO/PropertyDTO.php&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\DTO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Class PropertyDTO
 *
 * Represents a Data Transfer Object for property data.
 */&lt;/span&gt;
&lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PropertyDTO&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractDTO&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * The name of the property.
     *
     * @var string
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The address of the property.
     *
     * @var string
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$address&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The price of the property.
     *
     * @var float
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="nv"&gt;$price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The subscription status of the property, if applicable.
     *
     * @var string|null
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;?string&lt;/span&gt; &lt;span class="nv"&gt;$subscription&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * The list of assets associated with the property.
     *
     * @var array|null
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;?array&lt;/span&gt; &lt;span class="nv"&gt;$assets&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Set the properties from a model instance.
     *
     * @param $model The model instance.
     * @return $this
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Set the properties from API data.
     *
     * @param array $data The API data.
     * @return $this
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'property_name'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'property_address'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'property_price'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'subscription'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'assets'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Set the properties from CSV data.
     *
     * @param array $data The CSV data.
     * @return $this
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromCSV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;explode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Using the PropertyDTO
&lt;/h5&gt;

&lt;p&gt;Here's how you can use the &lt;code&gt;PropertyDTO&lt;/code&gt; to handle properties from different sources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// From a Model&lt;/span&gt;
&lt;span class="nv"&gt;$model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Property&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$propertyDTO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PropertyDTO&lt;/span&gt;&lt;span class="p"&gt;([]))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setFromModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// From an API&lt;/span&gt;
&lt;span class="nv"&gt;$apiData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'property_name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Beautiful House'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'property_address'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'1234 Elm Street'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'property_price'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;450000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'subscription'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Premium'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'assets'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'pool'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'garden'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nv"&gt;$propertyDTO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PropertyDTO&lt;/span&gt;&lt;span class="p"&gt;([]))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setFromAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$apiData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// From a CSV&lt;/span&gt;
&lt;span class="nv"&gt;$csvData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Beautiful House'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'1234 Elm Street'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;450000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Premium'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'pool,garden'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nv"&gt;$propertyDTO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PropertyDTO&lt;/span&gt;&lt;span class="p"&gt;([]))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setFromCSV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$csvData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Convert to Array&lt;/span&gt;
&lt;span class="nv"&gt;$arrayData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$propertyDTO&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Convert to JSON&lt;/span&gt;
&lt;span class="nv"&gt;$jsonData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$propertyDTO&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toJson&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Data Transfer Objects (DTOs) offer numerous advantages in Laravel applications by ensuring data consistency, validation, and separation of concerns. By implementing DTOs, you can make your application more maintainable, secure, and easier to test. In a property management system, DTOs help in handling data from various sources like APIs and CSV imports efficiently, ensuring that your business logic remains clean and focused on processing validated data.&lt;/p&gt;

&lt;p&gt;Moreover, embracing immutability within DTOs enhances predictability, thread-safety, and simplifies debugging.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extending DTOs with Abstract Classes for Consistency
&lt;/h3&gt;

&lt;p&gt;To streamline the creation of DTOs and promote code reuse, we can use an abstract class or base class. This approach allows us to define common methods and properties in the abstract class and extend it for specific data sources.&lt;/p&gt;

&lt;h5&gt;
  
  
  Defining the AbstractDTO
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;app/DTO/AbstractDTO.php&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\DTO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * AbstractDTO
 *
 * An abstract base class for Data Transfer Objects (DTOs).
 * Provides common methods and properties for DTO implementations.
 */&lt;/span&gt;
&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AbstractDTO&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * AbstractDTO constructor.
     *
     * Initialises the DTO with data from an associative array.
     *
     * @param array $data The data array to initialize the DTO.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setFromArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Set the properties of the DTO from a model instance.
     *
     * @param $model The model instance from which to populate the DTO.
     * @return $this
     */&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Set the properties of the DTO from API data.
     *
     * @param array $data The data array from the API.
     * @return $this
     */&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Set the properties of the DTO from CSV data.
     *
     * @param array $data The data array from the CSV.
     * @return $this
     */&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromCSV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Convert the DTO to an associative array.
     *
     * @return array The DTO data as an associative array.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;get_object_vars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;array_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$properties&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$property&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$property&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Convert the DTO to a JSON string.
     *
     * @return string The DTO data as a JSON string.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;toJson&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Set the properties of the DTO from an associative array.
     *
     * @param array $data The data array to populate the DTO.
     */&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;setFromArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;property_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Using an abstract or base class for DTOs not only ensures consistency across different DTO implementations but also promotes code reuse and maintainability. By defining common methods and properties in an abstract class, you can create a structured and efficient way to manage data transfer within your application. This approach aligns well with the principles of clean code and helps in building scalable and robust applications.&lt;/p&gt;

&lt;p&gt;Here’s a revised phrase that includes a call to action:&lt;/p&gt;

&lt;p&gt;"By leveraging DTOs and abstract classes together, you can refine your Laravel application's design, improving how data is managed and ensuring a more organised and efficient data flow. If you want to further encapsulate and enhance your DTOs with traits and interfaces, &lt;a href="https://dev.to/indunilperamuna/enhancing-object-oriented-design-with-traits-interfaces-and-abstract-classes-4647"&gt;explore our guide on Enhancing Object-Oriented Design with Traits, Interfaces, and Abstract Classes&lt;/a&gt;."&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Laravel 9 with Inertia.js + Vite + Vue.js + Tailwind CSS from Laravel</title>
      <dc:creator>Indunil Peramuna</dc:creator>
      <pubDate>Tue, 13 Dec 2022 06:45:06 +0000</pubDate>
      <link>https://dev.to/indunilperamuna/laravel-9-with-inertiajs-vuejs-tailwind-css-from-laravel-3o57</link>
      <guid>https://dev.to/indunilperamuna/laravel-9-with-inertiajs-vuejs-tailwind-css-from-laravel-3o57</guid>
      <description>&lt;p&gt;Hello, Here I m writing a guide to setup a Laravel 9 Web App with Inertiajs and Vue3. Here i m not explaining the process much but the steps of getting the example app up and running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Setting up laravel 9 - Latest
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -s "https://laravel.build/example-app" | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;replace 'example-app' with your app name&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install VueJs - Latest
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install vue@next
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Installing Inertia.js in Laravel
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require inertiajs/inertia-laravel
php artisan inertia:middleware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HandleInertiaRequests.php will be created inside app/Http/Middleware. We'll just need to add this middleware to the web middleware group inside app/Http/Kernel.php:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'web' =&amp;gt; [
    // ...
    \App\Http\Middleware\HandleInertiaRequests::class,
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Coming next is the Inertia's client side. We're using Vue 3, so we'll install Inertia alongside with the Vue 3 adapter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installing Inertia.js in NPM
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @inertiajs/inertia @inertiajs/inertia-vue3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's throw in the Inertia's progress bar. This will be used as a loading indicator between page navigation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @inertiajs/progress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Ziggy
Inertia uses Laravel's routes, so we won't need to use a client side router, but to make use of Laravel's web.php routes, we have to pass them to the DOM somehow. The easiest way to do it to use Ziggy.
Let's install Ziggy:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require tightenco/ziggy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Ziggy Setup
Let's get back to Ziggy and generate the .js file that contains all of our routes. We'll gonna import this into our app.js a bit later.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan ziggy:generate resources/js/ziggy.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Installing Tailwind CSS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tailwind requires the least amount of effort. We just need to install &lt;code&gt;postcss&lt;/code&gt; and &lt;code&gt;autoprefixer&lt;/code&gt; too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -D tailwindcss postcss autoprefixer
npm i @tailwindcss/forms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create the tailwind config file...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx tailwindcss init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also have to add the Tailwind's directives to &lt;code&gt;resources/css/app.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@tailwind base;
@tailwind components;
@tailwind utilities;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Tailwind and PostCSS
Change the &lt;code&gt;tailwind.config.js&lt;/code&gt; with following
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    mode: "jit",
    purge: ['./resources/**/*.{js,jsx,ts,tsx,vue,blade.php}'],
    theme: {},
    variants: {},
    plugins: [],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the &lt;code&gt;postcss.config.js&lt;/code&gt; with following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    plugins: {
        tailwindcss: {},
        autoprefixer: {},
    },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up vite.config.js
&lt;/h2&gt;

&lt;p&gt;Following is the vite config with all the settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/js/app.js'],
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    resolve: {
        alias: {
            'ziggy': '/vendor/tightenco/ziggy/src/js',
            'ziggy-vue': '/vendor/tightenco/ziggy/src/js/vue'
        },
    },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Finally, let's deal with app.js
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createApp, h } from "vue";
import { createInertiaApp, Link, Head } from "@inertiajs/inertia-vue3";
import { InertiaProgress } from "@inertiajs/progress";
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';

import { ZiggyVue } from "ziggy-vue";
import { Ziggy } from "./ziggy";
import '../css/app.css';

InertiaProgress.init();

createInertiaApp({
    resolve: async (name) =&amp;gt; resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
    setup({ el, App, props, plugin }) {
        createApp({ render: () =&amp;gt; h(App, props) })
            .use(plugin)
            .use(ZiggyVue, Ziggy)
            .component("Link", Link)
            .component("Head", Head)
            .mixin({ methods: { route } })
            .mount(el);
    },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup your Views
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;app.blade.php&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create file called app.blade.php inside your &lt;code&gt;/resources/views&lt;/code&gt; folder and basically it will act as a bootstrap for vue + inertiajs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="{{ str_replace('_', '-', app()-&amp;gt;getLocale()) }}"&amp;gt;

&amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;

    @routes
    @vite('resources/js/app.js')
    @inertiaHead
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
@inertia
&amp;lt;/body&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Vue Pages
You will have to create a folder inside your &lt;code&gt;/resources/js&lt;/code&gt; called &lt;code&gt;Pages&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;sample welcome.vue&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;head title="Homepage Title"&amp;gt;&amp;lt;/head&amp;gt;
    &amp;lt;h1&amp;gt;Homepage &amp;lt;/h1&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building your app
&lt;/h2&gt;

&lt;p&gt;Last thing we need to do is to change our package.json's scripts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "dev": "vite",
    "build": "vite build"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in order to build you will have to firstly generate the ziggy.js file by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// You can find this command in the previous guide
php artisan ziggy:generate resources/js/ziggy.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can run the dev or build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, make sure you clear your view cache because this might cause some issues after the migrations: &lt;code&gt;php artisan view:cache&lt;/code&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
