PHP
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Object-Oriented PHP
-
Section 5: Working with Data
-
Section 6: Modern PHP (PHP 8)
-
Section 7: Working with Files and Networking
-
Section 8: Common PHP Frameworks Overview
-
Section 9: Tooling and Ecosystem
-
Section 10: Practical Projects
-
Section 11: Interview Practice
-
Section 12: More Standard Library
-
Section 13: Data Structures and Algorithms in PHP
-
Section 14: More Practice Exercises
-
Section 15: More Security and Best Practices
-
Section 16: More Testing and Tooling
-
Section 17: WordPress-Style CMS Concepts
-
Section 18: Advanced OOP Practice
-
Section 19: More Web Fundamentals
-
Section 20: Database Practice
-
Section 21: PHP Manual: Array Functions
-
Section 22: PHP Manual: Date and Calendar Functions
-
Section 23: PHP Manual: Filesystem and Directory Functions
-
Section 24: PHP Manual: Filter and Var Handling
-
Section 25: PHP Manual: Math Functions
-
Section 26: PHP Manual: JSON and XML
-
Section 27: PHP Manual: Network and Stream Functions
-
Section 28: PHP Manual: Error and Exception Handling
-
Section 29: PHP Manual: Output Control and Misc
-
Section 30: PHP Manual: FTP, Zip, and Mail
-
Section 31: Modern PHP Frameworks Deep Dive
-
Section 32: PHP Design Patterns
-
Section 33: More Practice Exercises
-
Section 34: PHP Performance and Deployment
-
Section 35: More Interview Practice
-
Section 36: More PHP Standard Library
-
Section 37: PHP Concurrency and Async
-
Section 38: More Web Development Practice
-
Section 39: PHP Testing Deep Dive
-
Section 40: Composer and Package Development
-
Section 41: PHP Security Deep Dive
-
Section 42: More Practical Projects
-
Section 43: Legacy PHP Maintenance
-
Section 44: More Algorithm Practice
-
Section 45: Final Practice and Review
-
Section 46: PHP for E-Commerce Patterns
-
Section 47: PHP API Design Deep Dive
-
Section 48: PHP Caching Strategies
-
Section 49: PHP Queue and Background Jobs
-
Section 50: PHP Multi-Tenancy Patterns
-
Section 51: PHP Real-Time Features
-
Section 52: PHP CMS and Content Modeling
-
Section 53: PHP Internationalization
-
Section 54: More Framework-Specific Practice
-
Section 55: PHP Legacy Code Refactoring
-
Section 56: More Practice Projects Round 2
-
Section 57: PHP Command-Line Applications
-
Section 58: PHP and Microservices
-
Section 59: More Interview and Review Round 2
20: Namespaces
Imagine you're working in a large office building. You shout, "Hey, Sarah!" across the room. If there's only one Sarah in the entire building, she'll answer, and everything is great. But what happens when your company grows, and suddenly you have a Sarah in Accounting, a Sarah in Marketing, and a Sarah in Engineering? If you just shout "Sarah," you're going to get three people looking at you, and you've just created a conflict.
To fix this, you stop using just the first name. You start saying "Accounting Sarah" or "Engineering Sarah." You've essentially created a "namespace" for your employees based on their department. The name "Sarah" is still the same, but the prefix tells you exactly which one you're talking to.
In PHP, namespaces do the exact same thing for your classes, functions, and constants. As your projects get bigger—or as you start pulling in third-party libraries via Composer—the odds of two different developers naming a class User or Database are almost 100%. Namespaces prevent your app from crashing when that happens.
Avoiding the Name Collision Headache
Let's say you're building an e-commerce site. You wrote a great class called PaymentGateway to handle your internal logic. Then, you install a professional payment SDK, and surprise: they also have a class called PaymentGateway. PHP will throw a fatal error because it can't have two classes with the same name in the global scope.
Here is how we solve that using the namespace keyword at the very top of the file:
<?php
namespace App\Payments;
class PaymentGateway {
public function process() {
echo "Processing internal payment...";
}
}
?>
By adding namespace App\Payments;, this class is no longer just PaymentGateway. Its "full name" (called the Fully Qualified Class Name) is now \App\Payments\PaymentGateway. It's now safely tucked away in its own "department," so it won't clash with the SDK's version.
Pulling Classes into Your Current Space
You probably don't want to type \App\Payments\PaymentGateway every single time you instantiate the class. It's tedious and makes your code look cluttered. This is where the use keyword comes in. Think of it as telling PHP, "Whenever I say 'PaymentGateway' in this file, I actually mean the one from the App\Payments namespace."
<?php
namespace App\Orders;
use App\Payments\PaymentGateway;
class OrderProcessor {
public function checkout() {
$gateway = new PaymentGateway();
$gateway->process();
}
}
?>
I've used namespaces in hundreds of projects, and the most important thing to remember is that the namespace declaration must be the very first statement in your PHP file. If you put a function or a bit of HTML before it, PHP will scream at you.
Handling the "Two Sarahs" Problem with Aliasing
Now, what if you actually need both versions of the class in the same file? Maybe you're migrating from your old internal gateway to the new SDK and need to compare them. You can't use both because they have the same short name. The solution is aliasing using the as keyword.
<?php
use App\Payments\PaymentGateway as InternalGateway;
use ExternalSDK\PaymentGateway as StripeGateway;
$internal = new InternalGateway();
$external = new StripeGateway();
?>
Now you've given them distinct nicknames for the duration of that file, and the conflict is gone.
The Global Scope Shortcut
Sometimes you'll be inside a namespace, but you need to use a built-in PHP class, like DateTime or Exception. PHP will first look for \Your\Namespace\DateTime, fail to find it, and then fallback to the global one. However, for the sake of clarity and a tiny bit of performance, I always recommend prefixing global classes with a backslash \.
Using new \DateTime() explicitly tells PHP, "Don't look in the current namespace; go straight to the root global space." It's a small habit that saves you from some very confusing bugs down the road.
📋 Practical Task
Exercise: Resolving the Logger Conflict
You are working on a system that has two different logging requirements. One is for system-level errors (writing to a server log) and one is for user-activity tracking (writing to a database). Both developers named their class Logger.
Your Task:
- Create two separate "virtual" files (or blocks of code).
- The first should place the
Loggerclass inside theSystem\Diagnosticsnamespace. - The second should place the
Loggerclass inside theUser\Analyticsnamespace.
- The first should place the
- In a third block of code (your main execution file), import both classes.
- Since they both share the name
Logger, you must use theaskeyword to alias them asSysLoggerandUserLogger. - Instantiate both and call a method on each (e.g.,
log()) to prove they are operating from their respective namespaces.
There are no comments for now.