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
129: Laravel Eloquent ORM Relationships
I've sat through countless code reviews where a developer looks at a line like $user->posts()->where('active', 1)->get() and asks why they can't just do $user->posts->where('active', 1). At first glance, they look identical. In fact, if you're just trying to get a list of posts, they often produce the same result. But this reveals a fundamental misunderstanding of how Eloquent handles relationships.
The "Method vs. Property" Confusion
The biggest misconception I see is the belief that $user->posts and $user->posts() are just two different ways of doing the same thing. They aren't. They are entirely different tools.
When you access $user->posts (the property), you are using a Dynamic Property. Laravel executes the query for you, fetches all the related posts from the database, and wraps them in a Collection. Once that happens, you are no longer talking to the database; you are filtering data in PHP's memory.
When you access $user->posts() (the method), you are getting the Relationship Object. This is essentially a Query Builder. It hasn't gone to the database yet. This allows you to chain further constraints onto the SQL query before it's ever executed.
// This fetches EVERY post for the user into memory, then filters with PHP.
// If the user has 10,000 posts, your server might crash.
$activePosts = $user->posts->where('active', 1);
// This adds "AND active = 1" to the SQL query.
// The database only sends back the records you actually need.
$activePosts = $user->posts()->where('active', 1)->get();
Defining One-to-Many and One-to-One Links
To make the above work, we have to define the relationships in our models. Let's assume we're building a simple blogging platform. A User has one Profile (One-to-One) and many Posts (One-to-Many).
In your User model, you'd define them like this:
public function profile()
{
return $this->hasOne(Profile::class);
}
public function posts()
{
return $this->hasMany(Post::class);
}
Crucially, the "inverse" must be defined on the other side. The Post model needs to know who it belongs to using the belongsTo method. I always tell my juniors: if you have a hasMany on one side, you almost certainly need a belongsTo on the other.
// Inside Post.php
public function user()
{
return $this->belongsTo(User::class);
}
Handling the Complexity of Many-to-Many
Now, things get interesting when we talk about Tags. A Post can have many Tags, and a Tag can belong to many Posts. You can't store this in a single column in either table. You need a "pivot table"—usually named alphabetically, like post_tag.
You don't need a Model for the pivot table itself (unless you're doing something very advanced). You just tell Eloquent to use belongsToMany on both ends.
// Inside Post.php
public function tags()
{
return $this->belongsToMany(Tag::class);
}
// Inside Tag.php
public function posts()
{
return $this->belongsToMany(Post::class);
}
The beauty of this is that Laravel handles the heavy lifting of joining the three tables behind the scenes. When you call $post->tags, Laravel queries the pivot table to find the IDs and then fetches the actual tags. Just remember: if you're adding a tag to a post, you don't manually insert into the pivot table. You use the attach() method: $post->tags()->attach($tagId);.
📋 Practical Task
Build a Course-Lesson Relationship System
You are tasked with implementing the data layer for a learning management system. You have three existing models: Course, Lesson, and Instructor. Your goal is to establish the correct Eloquent relationships to allow for complex querying.
Requirements:
- Course & Lesson: A
Coursehas manyLessons. ALessonbelongs to oneCourse. - Course & Instructor: A
Coursecan be co-taught by multipleInstructors, and anInstructorcan teach multipleCourses. (Implement this as a Many-to-Many relationship).
Your Task:
- Write the relationship methods in the
Course,Lesson, andInstructormodels. - Write a code snippet that retrieves a specific
Courseby ID and then uses the relationship method (not the dynamic property) to count how many lessons in that course are marked as'completed' = true. - Write a line of code that attaches an
Instructorwith ID 5 to aCoursewith ID 10.
There are no comments for now.