<?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: Hamdi LAADHARI</title>
    <description>The latest articles on DEV Community by Hamdi LAADHARI (@hamdi_laadhari).</description>
    <link>https://dev.to/hamdi_laadhari</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%2F1377788%2F319892fa-dc63-4fdd-947d-e00f94681822.png</url>
      <title>DEV Community: Hamdi LAADHARI</title>
      <link>https://dev.to/hamdi_laadhari</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hamdi_laadhari"/>
    <language>en</language>
    <item>
      <title>🐍 The "Production-Ready" Miniconda Cheatsheet: From Homebrew to JupyterLab</title>
      <dc:creator>Hamdi LAADHARI</dc:creator>
      <pubDate>Wed, 06 May 2026 22:14:18 +0000</pubDate>
      <link>https://dev.to/hamdi_laadhari/the-production-ready-miniconda-cheatsheet-from-homebrew-to-jupyterlab-1aob</link>
      <guid>https://dev.to/hamdi_laadhari/the-production-ready-miniconda-cheatsheet-from-homebrew-to-jupyterlab-1aob</guid>
      <description>&lt;p&gt;As I started my journey into AI and Data Science, I quickly realized that managing Python environments can be a total headache. Between broken dependencies and 'it works on my machine' errors, I was spending more time troubleshooting my setup than actually writing code.&lt;/p&gt;

&lt;p&gt;I wanted a way to streamline my workflow and keep my machine clean, so I moved to a Miniconda + Homebrew setup on my Mac. To save myself (and hopefully you) from digging through endless documentation, I condensed the 'essential' commands into a single, high-density A4 infographic.&lt;/p&gt;

&lt;p&gt;This cheatsheet skips the legacy bloat and focuses on a production-first workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Clean Installation: Setting up via Homebrew for macOS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Environment Hygiene: Creating, cloning, and exporting environments so your projects stay isolated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jupyter Integration: Properly registering kernels so your notebooks actually see your installed packages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Workflow: A step-by-step checklist for starting any new project the right way.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you are a fellow student trying to organize your labs or a developer looking for a 'no-nonsense' reference, I hope this helps you spend less time in the terminal and more time building."&lt;/p&gt;

&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%2F8h5f6zyx12lgcr6s2bfp.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%2F8h5f6zyx12lgcr6s2bfp.png" alt=" " width="800" height="1132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  🐍 Miniconda Cheatsheet
&lt;/h1&gt;




&lt;h2&gt;
  
  
  📦 Installation (macOS via Homebrew)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Miniconda&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;miniconda

&lt;span class="c"&gt;# Init conda for zsh&lt;/span&gt;
conda init zsh

&lt;span class="c"&gt;# Reload shell&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc

&lt;span class="c"&gt;# Verify&lt;/span&gt;
conda &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🌍 Environment Management
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# List all environments&lt;/span&gt;
conda &lt;span class="nb"&gt;env &lt;/span&gt;list

&lt;span class="c"&gt;# Create a new environment&lt;/span&gt;
conda create &lt;span class="nt"&gt;--name&lt;/span&gt; myenv &lt;span class="nv"&gt;python&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.11

&lt;span class="c"&gt;# Activate an environment&lt;/span&gt;
conda activate myenv

&lt;span class="c"&gt;# Deactivate current environment&lt;/span&gt;
conda deactivate

&lt;span class="c"&gt;# Delete an environment&lt;/span&gt;
conda &lt;span class="nb"&gt;env &lt;/span&gt;remove &lt;span class="nt"&gt;--name&lt;/span&gt; myenv

&lt;span class="c"&gt;# Clone an environment&lt;/span&gt;
conda create &lt;span class="nt"&gt;--name&lt;/span&gt; newenv &lt;span class="nt"&gt;--clone&lt;/span&gt; myenv

&lt;span class="c"&gt;# Export environment to file (for sharing/backup)&lt;/span&gt;
conda &lt;span class="nb"&gt;env export&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; environment.yml

&lt;span class="c"&gt;# Recreate environment from file&lt;/span&gt;
conda &lt;span class="nb"&gt;env &lt;/span&gt;create &lt;span class="nt"&gt;-f&lt;/span&gt; environment.yml

&lt;span class="c"&gt;# Show info about current environment&lt;/span&gt;
conda info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📚 Package Management
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install a package&lt;/span&gt;
conda &lt;span class="nb"&gt;install &lt;/span&gt;numpy

&lt;span class="c"&gt;# Install a specific version&lt;/span&gt;
conda &lt;span class="nb"&gt;install &lt;/span&gt;&lt;span class="nv"&gt;numpy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.26

&lt;span class="c"&gt;# Install multiple packages at once&lt;/span&gt;
conda &lt;span class="nb"&gt;install &lt;/span&gt;numpy pandas matplotlib scikit-learn

&lt;span class="c"&gt;# Install from conda-forge channel (wider package selection)&lt;/span&gt;
conda &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; conda-forge jupyterlab

&lt;span class="c"&gt;# Install with pip — ONLY when package is not available on conda or conda-forge&lt;/span&gt;
&lt;span class="c"&gt;# Always check first: conda search -c conda-forge packagename&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;somepackage

&lt;span class="c"&gt;# Update a package&lt;/span&gt;
conda update numpy

&lt;span class="c"&gt;# Update all packages in active environment&lt;/span&gt;
conda update &lt;span class="nt"&gt;--all&lt;/span&gt;

&lt;span class="c"&gt;# Remove a package&lt;/span&gt;
conda remove numpy

&lt;span class="c"&gt;# List installed packages in active environment&lt;/span&gt;
conda list

&lt;span class="c"&gt;# Search for a package&lt;/span&gt;
conda search numpy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🚀 JupyterLab
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install JupyterLab&lt;/span&gt;
conda &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; conda-forge jupyterlab

&lt;span class="c"&gt;# Launch JupyterLab&lt;/span&gt;
jupyter-lab

&lt;span class="c"&gt;# Launch from a specific folder&lt;/span&gt;
jupyter-lab &lt;span class="nt"&gt;--notebook-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/projects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔌 Kernel Management
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# List available kernels&lt;/span&gt;
jupyter kernelspec list

&lt;span class="c"&gt;# Register current env as a Jupyter kernel&lt;/span&gt;
conda &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; conda-forge ipykernel
python &lt;span class="nt"&gt;-m&lt;/span&gt; ipykernel &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; myenv &lt;span class="nt"&gt;--display-name&lt;/span&gt; &lt;span class="s2"&gt;"Python (myenv)"&lt;/span&gt;

&lt;span class="c"&gt;# Remove a kernel&lt;/span&gt;
jupyter kernelspec remove myenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔧 Conda Maintenance
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Update conda itself&lt;/span&gt;
conda update conda

&lt;span class="c"&gt;# Clean unused packages and cache (frees disk space)&lt;/span&gt;
conda clean &lt;span class="nt"&gt;--all&lt;/span&gt;

&lt;span class="c"&gt;# Show conda configuration&lt;/span&gt;
conda config &lt;span class="nt"&gt;--show&lt;/span&gt;

&lt;span class="c"&gt;# Add conda-forge as default channel&lt;/span&gt;
conda config &lt;span class="nt"&gt;--add&lt;/span&gt; channels conda-forge
conda config &lt;span class="nt"&gt;--set&lt;/span&gt; channel_priority strict
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  💡 Typical Project Workflow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Create and activate a fresh environment&lt;/span&gt;
conda create &lt;span class="nt"&gt;--name&lt;/span&gt; myproject &lt;span class="nv"&gt;python&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.11
conda activate myproject

&lt;span class="c"&gt;# 2. Install packages (always prefer conda over pip inside conda envs)&lt;/span&gt;
conda &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; conda-forge jupyterlab numpy pandas matplotlib scikit-learn ipykernel

&lt;span class="c"&gt;# 3. Register as a Jupyter kernel&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; ipykernel &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; myproject &lt;span class="nt"&gt;--display-name&lt;/span&gt; &lt;span class="s2"&gt;"Python (myproject)"&lt;/span&gt;

&lt;span class="c"&gt;# 4. Launch JupyterLab&lt;/span&gt;
jupyter-lab

&lt;span class="c"&gt;# 5. When done, deactivate&lt;/span&gt;
conda deactivate

&lt;span class="c"&gt;# 6. Export environment for reproducibility&lt;/span&gt;
conda &lt;span class="nb"&gt;env export&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; environment.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🗂️ Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create env&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conda create --name myenv python=3.11&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Activate env&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conda activate myenv&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deactivate env&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conda deactivate&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete env&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conda env remove --name myenv&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install package&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conda install numpy&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove package&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conda remove numpy&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List packages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conda list&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List envs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conda env list&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Launch JupyterLab&lt;/td&gt;
&lt;td&gt;&lt;code&gt;jupyter-lab&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Export env&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conda env export &amp;gt; environment.yml&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update conda&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conda update conda&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clean cache&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conda clean --all&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>python</category>
      <category>machinelearning</category>
      <category>deeplearning</category>
      <category>datascience</category>
    </item>
    <item>
      <title>The Sunset of General-Purpose Apps: Why Bespoke Tools are the Future</title>
      <dc:creator>Hamdi LAADHARI</dc:creator>
      <pubDate>Thu, 25 Sep 2025 21:29:23 +0000</pubDate>
      <link>https://dev.to/hamdi_laadhari/the-sunset-of-general-purpose-apps-why-bespoke-tools-are-the-future-lip</link>
      <guid>https://dev.to/hamdi_laadhari/the-sunset-of-general-purpose-apps-why-bespoke-tools-are-the-future-lip</guid>
      <description>&lt;p&gt;For years, our digital lives have revolved around a constellation of applications. From project management suites to sophisticated photo editors, we've come to expect a tool for every task. But what if this paradigm is fundamentally flawed? What if the very apps we rely on are becoming obsolete, replaced by a new era of instantly generated, perfectly tailored solutions?&lt;/p&gt;

&lt;p&gt;I believe we're on the cusp of a significant shift: &lt;strong&gt;the majority of today's general-purpose applications are destined to disappear, or at least become niche utilities.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Inherent Flaw of the One-Size-Fits-Most App
&lt;/h2&gt;

&lt;p&gt;The core problem with most existing applications boils down to two critical points:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Imperfect Fit:&lt;/strong&gt; No matter how feature-rich, most apps are rarely a 100% match for &lt;em&gt;your specific needs&lt;/em&gt;. They come with a bloated set of features you'll never use, or, more frustratingly, they lack that one crucial function you desperately require. We contort our workflows to fit the app, rather than the app adapting to us.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Maintenance Burden:&lt;/strong&gt; Every application, whether it's a SaaS product or a self-hosted solution, carries a maintenance cost. This isn't just about financial subscriptions; it's about updates, bug fixes, learning new interfaces, and integrating with other imperfect tools. This collective burden saps productivity and innovation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Why bother with these compromises when you can, or soon will be able to, instantly create the precise tool you need for a punctual task?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rise of Instant, Tailored Solutions
&lt;/h2&gt;

&lt;p&gt;The emergence of powerful AI-driven development and content generation tools is flipping the script. Imagine a world where, instead of searching for an app, you simply describe your immediate need, and a functional tool is generated on the fly.&lt;/p&gt;

&lt;p&gt;Tools like Google's AI Studio Build, GitHub Copilot, ChatGPT Canvas, and even creative platforms like Figma Make (when viewed as a rapid design generation tool) hint at this future. These aren't just intelligent assistants; they are nascent developers and designers, capable of understanding intent and materializing it into functional output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros of this Bespoke Future:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Perfect Fit, Every Time:&lt;/strong&gt; You get exactly what you need, nothing more, nothing less. No extraneous features, no missing functionalities.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Zero Maintenance (for you):&lt;/strong&gt; The ephemeral nature of these generated tools means you use them for the task, and then they're gone (or easily regenerated/modified for the next task). The "maintenance" is handled by the underlying AI model.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Unprecedented Agility:&lt;/strong&gt; Respond to new challenges and opportunities with lightning speed. A sudden data analysis requirement? Generate a custom script. A unique content formatting need? Generate a specialized converter.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Empowerment:&lt;/strong&gt; This democratizes development, allowing anyone to be a "creator" of digital tools, regardless of coding expertise.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons and Challenges:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Reliance on AI:&lt;/strong&gt; The quality and reliability of generated tools will be entirely dependent on the AI's capabilities and the clarity of user prompts.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Security Concerns:&lt;/strong&gt; How do we ensure the generated code or tools are secure, especially when dealing with sensitive data?&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Ethical Implications:&lt;/strong&gt; Who is responsible when an AI-generated tool produces an incorrect or biased outcome?&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Vendor Lock-in (New Form):&lt;/strong&gt; While freeing us from traditional apps, we might become reliant on the specific AI platforms that do the generating.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The "Human Touch" Gap:&lt;/strong&gt; For truly complex, nuanced, or highly creative applications, human insight and iterative design might still be irreplaceable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Real-World Example: My Draft.js to HTML Viewer
&lt;/h2&gt;

&lt;p&gt;Let me illustrate this concept with a personal anecdote. In my current workflow, I utilize an LLM (Large Language Model) to generate content. My CMS, however, stores this content in Draft.js format – a rich text editor framework for React.&lt;/p&gt;

&lt;p&gt;During development, I found myself in a bind: I needed a rapid way to preview the Draft.js content as actual HTML. Why? Because the LLM's output sometimes required quick checks for formatting, structure, and overall presentation before being committed. There wasn't an off-the-shelf, simple tool that did &lt;em&gt;exactly&lt;/em&gt; this. Existing solutions were either full-blown editors or complex libraries to integrate.&lt;/p&gt;

&lt;p&gt;So, instead of searching for an imperfect app or spending hours building a robust, production-ready solution, I created precisely what I needed for my punctual task: &lt;a href="https://h4md1.fr/draft-to-html-previewer/" rel="noopener noreferrer"&gt;&lt;strong&gt;a simple Draft.js to HTML viewer.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My tool allows me to paste the raw Draft.js content state in JSON format into an editor on the left, and instantly renders the corresponding HTML on the right. It's not a commercial product; it's a bespoke utility born out of a specific, temporary need.&lt;/p&gt;

&lt;p&gt;This exemplifies the future: if I had a more advanced AI assistant, I could simply &lt;em&gt;tell&lt;/em&gt; it, "I need a web tool that takes Draft.js JSON on the left and shows rendered HTML on the right," and it would instantly generate that specific application for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Adapt or Be Replaced
&lt;/h2&gt;

&lt;p&gt;The era of meticulously crafted, all-encompassing applications might be drawing to a close. As AI and instant generation tools mature, the value will shift from owning a vast array of generic tools to the ability to define and conjure highly specific, temporary, and perfectly tailored solutions.&lt;/p&gt;

&lt;p&gt;Developers, product managers, and even end-users will need to adapt their thinking. The focus will move from "which app should I use?" to "what exact functionality do I need, and how can I instantly manifest it?"&lt;/p&gt;

&lt;p&gt;What are your thoughts? Are you ready for a world where apps are generated on demand, or do you see a continued need for the established giants? Share your perspective in the comments below!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Chrome Extension Network Interception: The Modern Way to Scrape Instagram (and Beyond)</title>
      <dc:creator>Hamdi LAADHARI</dc:creator>
      <pubDate>Fri, 13 Jun 2025 17:02:54 +0000</pubDate>
      <link>https://dev.to/hamdi_laadhari/chrome-extension-network-interception-the-modern-way-to-scrape-instagram-and-beyond-49bl</link>
      <guid>https://dev.to/hamdi_laadhari/chrome-extension-network-interception-the-modern-way-to-scrape-instagram-and-beyond-49bl</guid>
      <description>&lt;p&gt;&lt;em&gt;How to reliably extract data from Instagram (and similar sites) by intercepting network calls in a Chrome extension—robust, minimal, and production-ready.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Network Interception?
&lt;/h2&gt;

&lt;p&gt;Traditional DOM scraping is fragile: UI changes, dynamic loading, and anti-bot measures make it unreliable. Instead, intercepting network calls lets you capture the raw data the site uses—before it even hits the DOM.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Immune to UI/layout changes&lt;/li&gt;
&lt;li&gt;Access to complete, structured data&lt;/li&gt;
&lt;li&gt;Faster (no DOM parsing)&lt;/li&gt;
&lt;li&gt;Stealthier (less likely to trigger anti-bot)&lt;/li&gt;
&lt;li&gt;Works for any site using XHR/fetch APIs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─ Page Context (Script Injection) ─┐
│   Patch fetch/XHR, intercept API  │
│   Dispatch CustomEvent w/ data    │
└───────────────────────────────────┘
           │
           ▼
┌─ Content Script ──────────────────┐
│   Listen for events, forward data │
│   to background via messaging     │
└───────────────────────────────────┘
           │
           ▼
┌─ Background Script ───────────────┐
│   Process, deduplicate, store,    │
│   or forward to external API      │
└───────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Minimal, Robust Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Manifest Setup (MV3)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"manifest_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Instagram Network Interceptor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"scripting"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"storage"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"host_permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://*.instagram.com/*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"background"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"service_worker"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"background.js"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"content_scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"matches"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://*.instagram.com/*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"js"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"content.js"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"run_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"document_start"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"web_accessible_resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"public/page-interceptor.js"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"matches"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;all_urls&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Page Interceptor (public/page-interceptor.js)
&lt;/h3&gt;

&lt;p&gt;Runs in the page context, patches fetch/XHR, and dispatches a CustomEvent with the response data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__instaInterceptor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__instaInterceptor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalFetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;originalFetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&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="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cloned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cloned&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatchEvent&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;CustomEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;instaApi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&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;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ignore */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalXHROpen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalXHRSend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;originalXHROpen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_url&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatchEvent&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;CustomEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;instaApi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_method&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;originalXHRSend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arguments&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;
  
  
  3. Content Script (content.js)
&lt;/h3&gt;

&lt;p&gt;Injects the interceptor and relays events to the background script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Inject the page script&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public/page-interceptor.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;script&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/javascript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Listen for intercepted data&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;instaApi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;API_PAYLOAD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&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;
  
  
  4. Background Script (background.js)
&lt;/h3&gt;

&lt;p&gt;Processes, deduplicates, and stores or forwards the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;processedShortcodes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;API_PAYLOAD&lt;/span&gt;&lt;span class="dl"&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;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Example: extract Instagram post shortcode&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shortcode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extractShortcode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;processedShortcodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shortcode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;processedShortcodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shortcode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Store, process, or forward to external API here&lt;/span&gt;
        &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()]:&lt;/span&gt; &lt;span class="nx"&gt;json&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;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Non-JSON or irrelevant response&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;extractShortcode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Minimal example: adapt to your API structure&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;shortcode&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&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;
  
  
  Best Practices &amp;amp; Gotchas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Always clone() responses&lt;/strong&gt; before reading body.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deduplicate&lt;/strong&gt; by post ID/shortcode to avoid reprocessing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limit&lt;/strong&gt; if forwarding to external APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle CSP&lt;/strong&gt; by injecting a file, not inline code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Respect privacy and ToS&lt;/strong&gt;: only process public data, implement delays, and avoid logging sensitive info.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Extending to Other Platforms
&lt;/h2&gt;

&lt;p&gt;You can adapt the same pattern for Twitter, LinkedIn, etc., by changing the URL detection logic in the interceptor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isTargetApi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;instagram.com/graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;twitter.com/i/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;linkedin.com/voyager&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Network interception in the page context is the most robust, future-proof way to extract data from modern web apps. With a minimal Chrome extension, you can capture structured data directly from the source—no more brittle DOM scraping.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>extensions</category>
    </item>
    <item>
      <title>Understanding Composer Version Constraints: A Comprehensive Guide</title>
      <dc:creator>Hamdi LAADHARI</dc:creator>
      <pubDate>Thu, 24 Apr 2025 12:28:41 +0000</pubDate>
      <link>https://dev.to/hamdi_laadhari/understanding-composer-version-constraints-a-comprehensive-guide-3bj3</link>
      <guid>https://dev.to/hamdi_laadhari/understanding-composer-version-constraints-a-comprehensive-guide-3bj3</guid>
      <description>&lt;p&gt;When managing PHP dependencies with Composer, understanding version constraints is crucial for maintaining stable, secure, and compatible packages in your projects. This guide explores the different operators and patterns you can use to specify version requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Big Three: Caret, Tilde, and Asterisk
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Caret (&lt;code&gt;^&lt;/code&gt;) Constraint - The Recommended Default
&lt;/h3&gt;

&lt;p&gt;The caret constraint follows semantic versioning principles, allowing updates that maintain backward compatibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Behavior&lt;/strong&gt;: Allows updates to everything except the leftmost non-zero component&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;^1.2.3&lt;/code&gt; allows updates to any version from 1.2.3 to &amp;lt;2.0.0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;^0.3.2&lt;/code&gt; allows updates to any version from 0.3.2 to &amp;lt;0.4.0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;^0.0.5&lt;/code&gt; allows updates to any version from 0.0.5 to &amp;lt;0.0.6&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The caret is generally recommended for most dependencies as it provides a good balance between stability and receiving bug fixes and minor improvements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tilde (&lt;code&gt;~&lt;/code&gt;) Constraint - More Conservative
&lt;/h3&gt;

&lt;p&gt;The tilde constraint is more restrictive than caret and allows only for minor or patch version updates, depending on how it's used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Behavior&lt;/strong&gt;: Allows the last specified digit to increase&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;~1.2.3&lt;/code&gt; allows updates to any version from 1.2.3 to &amp;lt;1.3.0 (only patch updates)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;~1.2&lt;/code&gt; allows updates to any version from 1.2.0 to &amp;lt;1.3.0 (patch updates only)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;~1&lt;/code&gt; allows updates to any version from 1.0.0 to &amp;lt;2.0.0 (minor and patch updates)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use tilde when you want to be more cautious about updates, especially for packages with a history of breaking changes in minor versions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Asterisk (&lt;code&gt;*&lt;/code&gt;) Constraint - The Wildcard
&lt;/h3&gt;

&lt;p&gt;The asterisk represents a wildcard and can be used to allow any version in a specific position.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Behavior&lt;/strong&gt;: Matches any version in the position where it appears&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1.2.*&lt;/code&gt; allows any version from 1.2.0 to &amp;lt;1.3.0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1.*&lt;/code&gt; allows any version from 1.0.0 to &amp;lt;2.0.0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*&lt;/code&gt; allows any version (not recommended for production)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wildcards are convenient but should be used with caution, especially in production environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Version Constraints
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exact Version
&lt;/h3&gt;

&lt;p&gt;When you need a specific version with no flexibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"monolog/monolog"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.25.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful for packages where you've verified compatibility with exactly one version, but it means you won't automatically get bug fixes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Version Ranges
&lt;/h3&gt;

&lt;p&gt;Composer supports explicit version ranges using comparison operators:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"symfony/symfony"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;=4.0 &amp;lt;5.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows any version from 4.0.0 up to, but not including, 5.0.0.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hyphen Ranges
&lt;/h3&gt;

&lt;p&gt;A more concise way to specify inclusive ranges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"doctrine/orm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0.0 - 2.9.9"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is equivalent to &lt;code&gt;&amp;gt;=2.0.0 &amp;lt;=2.9.9&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stability Flags
&lt;/h3&gt;

&lt;p&gt;You can specify minimum stability for a particular package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"vendor/package"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0@dev"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"vendor/package"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0@stable"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"vendor/package"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev-master"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common stability flags include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@dev&lt;/code&gt;: Development versions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@alpha&lt;/code&gt;: Alpha releases&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@beta&lt;/code&gt;: Beta releases&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@RC&lt;/code&gt;: Release candidates&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@stable&lt;/code&gt;: Stable releases&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Minimum Stability Setting
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;minimum-stability&lt;/code&gt; setting in your &lt;code&gt;composer.json&lt;/code&gt; file defines the default minimum stability of packages that Composer will consider when resolving dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"minimum-stability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"require"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"vendor/package"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.0"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Possible values (from least to most stable):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;dev&lt;/code&gt;: Development snapshots and branches&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;alpha&lt;/code&gt;: Alpha releases&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;beta&lt;/code&gt;: Beta releases&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RC&lt;/code&gt;: Release candidates&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stable&lt;/code&gt;: Stable releases (default)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setting affects all packages, but you can override it for specific packages using stability flags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"minimum-stability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"require"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"stable/package"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Will&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;stable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;versions&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"new/feature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.0@beta"&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Will&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;allow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;beta&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;versions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;prefer-stable&lt;/code&gt; option can be used alongside &lt;code&gt;minimum-stability&lt;/code&gt; to prefer stable versions when available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"minimum-stability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prefer-stable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"require"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"vendor/package"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.0"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration will allow Composer to consider development versions but will prefer stable releases when they exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Version Aliases
&lt;/h3&gt;

&lt;p&gt;Aliases allow you to treat branches as if they were version numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"vendor/package"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev-master as 1.0.x-dev"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Real-World Examples
&lt;/h2&gt;

&lt;p&gt;Here's how you might use different constraints in a typical project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"require"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"php"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.4|^8.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Compatible&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;PHP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.4&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.0&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"symfony/framework-bundle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5.4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.4&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;but&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;less&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;than&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;6.0&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"doctrine/orm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~2.8.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.8&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mf"&gt;2.9&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"monolog/monolog"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.25.*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.25&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mf"&gt;1.26&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"twig/twig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.0 || ^3.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Either&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Twig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;.x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;.x&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"experimental/package"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev-main@dev"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Development&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;branch&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;For most dependencies&lt;/strong&gt;: Use the caret (&lt;code&gt;^&lt;/code&gt;) constraint to follow semantic versioning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For less stable packages&lt;/strong&gt;: Use the tilde (&lt;code&gt;~&lt;/code&gt;) constraint to limit updates to patch versions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid wildcards in production&lt;/strong&gt;: The asterisk (&lt;code&gt;*&lt;/code&gt;) is too permissive for production environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lock file is crucial&lt;/strong&gt;: Always commit your &lt;code&gt;composer.lock&lt;/code&gt; file to ensure all team members and environments use the same versions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regular updates&lt;/strong&gt;: Run &lt;code&gt;composer update&lt;/code&gt; regularly in development to catch compatibility issues early&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security updates&lt;/strong&gt;: Use &lt;code&gt;composer update --with-dependencies package/name&lt;/code&gt; to update a package and its dependencies for security patches&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Updating Dependencies: Constraints vs. Commands
&lt;/h3&gt;

&lt;p&gt;A common question is whether you should update your &lt;code&gt;composer.json&lt;/code&gt; constraints when you want to update a dependency. For example, is it better to use &lt;code&gt;~1.2.3&lt;/code&gt; or &lt;code&gt;1.2.*&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;The answer depends on your update strategy:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strategy 1: Flexible constraints + composer.lock&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use somewhat flexible constraints like &lt;code&gt;^1.2&lt;/code&gt; or &lt;code&gt;~1.2&lt;/code&gt; in your &lt;code&gt;composer.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;composer update&lt;/code&gt; periodically to get new compatible versions&lt;/li&gt;
&lt;li&gt;Let the &lt;code&gt;composer.lock&lt;/code&gt; file track the exact versions in use&lt;/li&gt;
&lt;li&gt;This approach requires less maintenance of the &lt;code&gt;composer.json&lt;/code&gt; file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Strategy 2: Explicit constraints + manual updates&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use more specific constraints like &lt;code&gt;~1.2.3&lt;/code&gt; (which is more precise than &lt;code&gt;1.2.*&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Manually update constraints in &lt;code&gt;composer.json&lt;/code&gt; when you want newer versions&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;composer update package/name&lt;/code&gt; after changing constraints&lt;/li&gt;
&lt;li&gt;This approach gives you more explicit control over when updates happen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Which is better?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first strategy is generally recommended because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It reduces maintenance overhead&lt;/li&gt;
&lt;li&gt;It still gives you control via the lock file&lt;/li&gt;
&lt;li&gt;You can run &lt;code&gt;composer update --dry-run&lt;/code&gt; to preview changes before applying them&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, the second strategy might be preferred in environments where:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You need strict control over dependency updates&lt;/li&gt;
&lt;li&gt;You have a formal review process for dependency changes&lt;/li&gt;
&lt;li&gt;You're working with mission-critical applications where every update must be explicitly approved&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In either case, the &lt;code&gt;composer.lock&lt;/code&gt; file is your safety net, ensuring that all environments use the exact same versions until you deliberately update them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preventing Unwanted Downgrades
&lt;/h3&gt;

&lt;p&gt;One important reason to use specific version constraints is to prevent unwanted downgrades. This can happen when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You update a package to a newer version with important security fixes&lt;/li&gt;
&lt;li&gt;Another package in your project depends on the same package but with a loose constraint&lt;/li&gt;
&lt;li&gt;When you run &lt;code&gt;composer update&lt;/code&gt;, you might unexpectedly downgrade to an older, vulnerable version&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's a real-world example with hotfix versions:&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Your project directly requires &lt;code&gt;symfony/http-foundation: "^4.4"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You specifically update to version 4.4.50 which contains a critical security fix: &lt;code&gt;composer update symfony/http-foundation&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Later, you run &lt;code&gt;composer update&lt;/code&gt; to update other packages&lt;/li&gt;
&lt;li&gt;Another package in your project requires &lt;code&gt;symfony/http-foundation: "&amp;gt;=4.4 &amp;lt;6.0"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Composer might downgrade you back to 4.4.30 (an older, vulnerable version) based on other constraints&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By using more specific constraints, you can prevent this downgrade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"require"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"symfony/http-foundation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.4.50"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Ensures&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;we&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;never&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;below&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.4&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;security&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fix)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"some/package"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.0"&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;might&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;also&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;depend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;symfony/http-foundation&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the explicit version constraint &lt;code&gt;^4.4.50&lt;/code&gt; ensures you'll never downgrade below the security patch level, while still allowing compatible updates (up to, but not including, 5.0.0).&lt;/p&gt;

&lt;p&gt;This is particularly important for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security patches and hotfixes&lt;/li&gt;
&lt;li&gt;Packages with known bugs in specific versions&lt;/li&gt;
&lt;li&gt;Ensuring consistent behavior across environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is another reason why the explicit constraint strategy can be valuable in certain scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Understanding Composer's version constraints helps you balance between stability and receiving updates. The caret (&lt;code&gt;^&lt;/code&gt;) constraint is usually the best default choice, but knowing when to use alternatives gives you fine-grained control over your project's dependencies.&lt;/p&gt;

&lt;p&gt;Remember that the &lt;code&gt;composer.lock&lt;/code&gt; file is just as important as your constraints—it ensures consistency across environments by locking the exact versions used.&lt;/p&gt;

&lt;p&gt;By mastering these version constraints, you'll be better equipped to maintain robust PHP applications with well-managed dependencies.&lt;/p&gt;

</description>
      <category>php</category>
      <category>programming</category>
      <category>symfony</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Understanding `self` vs `static` in PHP</title>
      <dc:creator>Hamdi LAADHARI</dc:creator>
      <pubDate>Wed, 23 Apr 2025 12:11:35 +0000</pubDate>
      <link>https://dev.to/hamdi_laadhari/understanding-self-vs-static-in-php-130n</link>
      <guid>https://dev.to/hamdi_laadhari/understanding-self-vs-static-in-php-130n</guid>
      <description>&lt;h1&gt;
  
  
  Understanding &lt;code&gt;self&lt;/code&gt; vs &lt;code&gt;static&lt;/code&gt; in PHP
&lt;/h1&gt;

&lt;p&gt;In PHP, the keywords &lt;code&gt;self&lt;/code&gt; and &lt;code&gt;static&lt;/code&gt; are both used to refer to class properties and methods. However, they behave differently, especially when it comes to inheritance and late static bindings. Understanding the distinction between these two keywords is crucial for effective object-oriented programming in PHP.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;code&gt;self&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;self&lt;/code&gt; keyword in PHP refers to the class in which it is used. It is resolved at compile time and always points to the class where it is defined, regardless of whether it is called from a parent class or a child class. This makes &lt;code&gt;self&lt;/code&gt; useful for accessing static properties and methods that are specific to the class where &lt;code&gt;self&lt;/code&gt; is used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of &lt;code&gt;self&lt;/code&gt;
&lt;/h3&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;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Animal'&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;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getName&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="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$name&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Dog'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Outputs: Animal&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;    &lt;span class="c1"&gt;// Outputs: Animal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, even though &lt;code&gt;Dog&lt;/code&gt; extends &lt;code&gt;Animal&lt;/code&gt; and overrides the &lt;code&gt;$name&lt;/code&gt; property, calling &lt;code&gt;Dog::getName()&lt;/code&gt; still returns &lt;code&gt;'Animal'&lt;/code&gt; because &lt;code&gt;self&lt;/code&gt; refers to the class where it is defined, which is &lt;code&gt;Animal&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;code&gt;static&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;static&lt;/code&gt; keyword, on the other hand, refers to the class that was called at runtime. This is known as "late static binding," which allows &lt;code&gt;static&lt;/code&gt; to adapt to the context in which it is called. This means that if a child class overrides a property or method, &lt;code&gt;static&lt;/code&gt; will refer to the child class's version.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of &lt;code&gt;static&lt;/code&gt;
&lt;/h3&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;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Animal'&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;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getName&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="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$name&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Dog'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Outputs: Animal&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;    &lt;span class="c1"&gt;// Outputs: Dog&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, calling &lt;code&gt;Dog::getName()&lt;/code&gt; returns &lt;code&gt;'Dog'&lt;/code&gt; because &lt;code&gt;static&lt;/code&gt; resolves to the class that was called at runtime, which is &lt;code&gt;Dog&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use &lt;code&gt;self&lt;/code&gt; vs &lt;code&gt;static&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;self&lt;/code&gt;&lt;/strong&gt; when you want to ensure that the reference remains fixed to the class where it is defined. This is useful when you want to prevent subclasses from overriding the behavior. It is ideal for maintaining consistency and preventing unintended overrides by subclasses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;static&lt;/code&gt;&lt;/strong&gt; when you want the reference to adapt to the class that is called at runtime. This is useful for implementing polymorphic behavior, where subclasses can override properties or methods. This feature enables more dynamic and flexible code, as it adapts to the context in which it is called.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Practical Example
&lt;/h3&gt;

&lt;p&gt;Consider a scenario where you have a base class &lt;code&gt;Logger&lt;/code&gt; and a subclass &lt;code&gt;FileLogger&lt;/code&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$logLevel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'info'&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;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Logging at level: '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$logLevel&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileLogger&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$logLevel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'debug'&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;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Logging at level: '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$logLevel&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="nc"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;    &lt;span class="c1"&gt;// Outputs: Logging at level: info&lt;/span&gt;
&lt;span class="nc"&gt;FileLogger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Outputs: Logging at level: debug&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;Logger::log()&lt;/code&gt; uses &lt;code&gt;self&lt;/code&gt; to ensure that it always refers to the &lt;code&gt;$logLevel&lt;/code&gt; in the &lt;code&gt;Logger&lt;/code&gt; class, while &lt;code&gt;FileLogger::log()&lt;/code&gt; uses &lt;code&gt;static&lt;/code&gt; to refer to the &lt;code&gt;$logLevel&lt;/code&gt; in the &lt;code&gt;FileLogger&lt;/code&gt; class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Community Insights and Examples
&lt;/h2&gt;

&lt;p&gt;Developers often share practical examples to illustrate the differences between &lt;code&gt;self&lt;/code&gt; and &lt;code&gt;static&lt;/code&gt;. For instance, when defining a method that returns a new instance of a class, using &lt;code&gt;new self()&lt;/code&gt; will always return an instance of the class where the method is defined, while &lt;code&gt;new static()&lt;/code&gt; will return an instance of the class that was called at runtime. This behavior is crucial for implementing factory methods or singleton patterns.&lt;/p&gt;

&lt;p&gt;Online forums and Q&amp;amp;A platforms like Stack Overflow have numerous discussions where developers seek clarification on the nuances of &lt;code&gt;self&lt;/code&gt; and &lt;code&gt;static&lt;/code&gt;. These discussions often highlight common pitfalls and best practices, such as understanding how &lt;code&gt;self&lt;/code&gt; and &lt;code&gt;static&lt;/code&gt; behave in the context of inheritance and method overriding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example from Community Discussions
&lt;/h3&gt;

&lt;p&gt;Here's an example that often comes up in community discussions:&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;ParentClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Parent'&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;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getName&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="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Always refers to ParentClass::$name&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;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getStaticName&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="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Refers to the class that was called at runtime&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChildClass&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ParentClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Child'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;ParentClass&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Outputs: Parent&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;ChildClass&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Outputs: Parent&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;ParentClass&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getStaticName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Outputs: Parent&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;ChildClass&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getStaticName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Outputs: Child&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;self::$name&lt;/code&gt; always refers to &lt;code&gt;ParentClass::$name&lt;/code&gt;, regardless of whether it is called from &lt;code&gt;ParentClass&lt;/code&gt; or &lt;code&gt;ChildClass&lt;/code&gt;. In contrast, &lt;code&gt;static::$name&lt;/code&gt; adapts to the class that was called at runtime, demonstrating the power of late static binding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Understanding the differences between &lt;code&gt;self&lt;/code&gt; and &lt;code&gt;static&lt;/code&gt; is essential for writing robust and maintainable PHP code. By leveraging community insights and practical examples, developers can make informed decisions about when to use each keyword, leading to more effective and flexible object-oriented designs.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>php</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
