Laravel Articles
Solve Vue.js Component Overload with Parent-Child Patterns
Has your Vue component become a tangled mess? Too much template markup, too many responsibilities, and decreasing maintainability.
Well the solution is to use component composition with parent-child relationships that Vue provides.
In this tutorial, you'll learn to:
1. Refactor effectively breaking up monolithic components into focused children
2. Pass data gracefully using props to send data from parent to child
3. Handle child events by capturing custom events emitted by child components
4. Maintain clean data flow by establishing predictable communication between components
See a real-world example where a parent component delegates UI to a specialized Toolbar child, creating cleaner code and better separation of concerns.
Parent Component:
<template>
<div class="parent-component">
<h2>Evaluate Product</h2>
<Toolbar :message="message" @evaluate-product="evaluate" />
<div class="parent-data">
<p>Total Likes: {{ total.likes }}</p>
<p>Total Dislikes: {{ total.dislikes }}</p>
<p v-if="action">Last Action: {{ action }}</p>
</div>
</div>
</template>
<script>
import Toolbar from './Toolbar.vue';
export default {
name: 'EvaluateComponent',
components: {
Toolbar
},
data(){
return {
total: {
likes: 0,
dislikes: 0
},
message: '',
action: null,
messageTimeout: null
}
},
methods:{
evaluate(task) {
// Clear previous timeout
if (this.messageTimeout) {
clearTimeout(this.messageTimeout);
}
switch(task) {
case 'like':
this.total.likes++;
this.message = "Like incremented successfully!";
this.action = 'like';
break;
case 'dislike':
this.total.dislikes++;
this.message = "Dislike incremented successfully!";
this.action = 'dislike';
break;
}
// Auto-clear message after 3 seconds
this.messageTimeout = setTimeout(() => {
this.message = '';
}, 3000);
}
},
beforeDestroy() {
// Clean up timeout when component is destroyed
if (this.messageTimeout) {
clearTimeout(this.messageTimeout);
}
}
}
</script>
Child Component (Toolbar tag in the parent):
<template>
<div class="child-component">
<div class="message" v-if="messageSet">{{ message }}</div>
<button @click="performEvaluate('like')">Like</button>
<button @click="performEvaluate('dislike')">Dislike</button>
</div>
</template>
<script>
export default {
props: {
message: {
type: String,
default: ''
}
},
data() {
return {
// You can add data properties here if needed
}
},
emits: ['evaluate-product'],
computed: {
messageSet() {
return this.message.length > 0;
}
},
methods: {
performEvaluate(evaluation) {
this.$emit('evaluate-product', evaluation);
}
}
}
</script>
Laravel Webpack.mix Asset Compilation AND Performance Optimization
Getting Started with webpack.mix
This is an essential must know for Laravel developers. This tutorial will go through the basics of webpack.mix and preparing live CSS stylesheets and Javascript includes.
Locate webpack.mix.js and the /resources and /public directories. I will define a few ways to specify the files from resources compiled to the live public directory. Check out these 2 examples… they should cover necessary usage for 99% of projects.
Example: Combine multiple files into a single file.
In this example I’ll define a simple way to combine multiple custom javascript files into a single file. Let’s take 4 custom stylesheets and 4 javascript files. We will combine all specified stylesheets from /resources/css into a single stylesheet named /public/css/custom-all.css. Also let’s combine the specified javascript files from /resources/js into a single javascript file named /public/js/custom-all.js
All files that can be edited directly are located in the resources directory. All compiled files will be placed in the public directory where the code can be accessed live.
mix.js('resources/js/app.js', 'public/js')
.vue()
.sass('resources/sass/app.scss', 'public/css');
// Combine all custom JS into one file
mix.scripts([
'resources/js/custom/main.js',
'resources/js/custom/helpers.js',
'resources/js/custom/components/*.js'
], 'public/js/custom-all.js');
// Combine all custom CSS into one file
mix.styles([
'resources/css/custom/main.css',
'resources/css/custom/components/buttons.css',
'resources/css/custom/pages/*.css'
], 'public/css/custom-all.css');
Let’s see how to use things in a blade template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Your Laravel Application</title>
<!-- Compiled CSS -->
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
<link href="{{ mix('css/custom-all.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
<!-- Your application content -->
</div>
<!-- Compiled JavaScript -->
<script src="{{ mix('js/app.js') }}"></script>
<script src="{{ mix('js/custom-all.js') }}"></script>
</body>
</html>
Example: Prepare several files.
This example is very similar to the example above. The only difference is in this example we are generating individual files in the public directory for each file specified from the resources directory.
// Webpack-compiled JS and CSS
mix.js('resources/js/app.js', 'public/js')
.vue({ version: 2 })
.sass('resources/sass/app.scss', 'public/css') // Or .css() if not using Sass
.css('resources/css/app.css', 'public/css');
// Custom JS files (separate from Webpack bundle)
mix.js('resources/js/custom/main.js', 'public/js/custom.js')
.js('resources/js/custom/helpers.js', 'public/js/helpers.js');
// Custom CSS files (separate from Webpack bundle)
mix.css('resources/css/custom/main.css', 'public/css/custom.css')
.css('resources/css/custom/components/buttons.css', 'public/css/components/buttons.css');
Notice in webpack.mix.js the definitions for mix.js and mix.css methods. Each of the javascript files and stylesheets from the resources directory has a corresponding file in the public directory.
Now let’s look at how to use this in a blade template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Your Laravel Application</title>
<!-- Compiled CSS -->
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
<link href="{{ mix('css/custom.css') }}" rel="stylesheet">
<link href="{{ mix('css/components/buttons.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
<!-- Your application content -->
</div>
<!-- Compiled JavaScript -->
<script src="{{ mix('js/app.js') }}"></script>
<script src="{{ mix('js/custom.js') }}"></script>
<script src="{{ mix('js/helpers.js') }}"></script>
</body>
</html>
To generate the public CSS and JS files:
npm install
npm run dev
Laravel Eloquent ORM Polymorphism Examples
Laravel Eloquent ORM Polymorphism
In Laravel's Eloquent ORM, polymorphism refers to polymorphic relationships, which allow a model to belong to more than one type of model using a single association.
This is useful when you have a relationship that can apply to multiple different models without having to create separate foreign keys or pivot tables for each type. Examples would be Users and Products that each have one or more images.
Let’s take a look at different types of polymorphic relationships commonly used in Laravel Eloquent ORM.
One-to-One (Polymorphic)
Example: An Image model could belong to either a User or a Product.
// Image model
public function imageable()
{
return $this->morphTo();
}
// User model
public function image()
{
return $this->morphOne(Image::class, 'imageable');
}
// Product model
public function image()
{
return $this->morphOne(Image::class, 'imageable');
}
Table Definitions: User, Product models can both have an Image. Notice Image.imageable_id and Image.imageable_type. This can join on both User.id and Product.id tables.
CREATE TABLE users (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
email VARCHAR(255) UNIQUE
);
CREATE TABLE products (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
price DECIMAL(10,2)
);
CREATE TABLE images (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
url VARCHAR(255),
imageable_id BIGINT UNSIGNED, -- FK ID (user.id or product.id)
imageable_type VARCHAR(255), -- Model class (App\Models\User/App\Models\Product)
INDEX idx_imageable (imageable_id, imageable_type)
);
One-to-Many (Polymorphic)
Example: A Comment model could belong to both a Post and a Video.
// Comment model
public function commentable()
{
return $this->morphTo();
}
// Post model
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
// Video model
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
Table Definitions: Post, Video models can both have a Comment. Notice Comment.commentable_id and Comment.commentable_type. This can join on both Post.id and Video.id tables.
CREATE TABLE posts (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
body TEXT
);
CREATE TABLE videos (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
url VARCHAR(255)
);
CREATE TABLE comments (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
body TEXT,
commentable_id BIGINT UNSIGNED, -- FK ID (post.id|video.id)
commentable_type VARCHAR(255), -- Model class (App\Models\Post|App\Models\Video)
INDEX idx_commentable (commentable_id, commentable_type)
);
Many-to-Many (Polymorphic)
Example: A Tag model can be applied to both Post and Video.
// Tag model
public function posts()
{
return $this->morphedByMany(Post::class, 'taggable');
}
public function videos()
{
return $this->morphedByMany(Video::class, 'taggable');
}
// Post model
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
// Video model
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
Table Definitions: Both Post, Video models can have multiple Tags. Also, a Tag can belong to multiple Post, Video models. Notice the pivot table taggables…
CREATE TABLE tags (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) UNIQUE
);
CREATE TABLE posts (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
body TEXT
);
CREATE TABLE videos (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
url VARCHAR(255)
);
CREATE TABLE taggables (
tag_id BIGINT UNSIGNED, -- FK to tags.id
taggable_id BIGINT UNSIGNED, -- FK ID (post.id or video.id)
taggable_type VARCHAR(255), -- Model class (App\Models\Post / App\Models\Video)
PRIMARY KEY (tag_id, taggable_id, taggable_type),
INDEX idx_taggable (taggable_id, taggable_type)
);
PHP Spaceship Operator (<=>)
PHP Spaceship Operator (<=>)
The PHP Spaceship Operator (<=>) is a comparison operator that provides a three-way comparison between two values. It's also known as the "combined comparison operator."
How it works:
The operator returns -1, 0, or 1 depending on the condition.
-1 => if the left operand is less than the right operand
0 => if both operands are equal
1 => if the left operand is greater than the right operand
Sample Usage:
$a = 1;
$b = 1;
$result = $a <=> $b; // result is 0
$b = 2;
$result = $a <=> $b; // result is -1
$b = 0;
$result = $a <=> $b; // $result is 1
Spaceship Operator vs using if-else:
// using if/else
if ($a < $b) {
return -1;
} elseif ($a > $b) {
return 1;
} else {
return 0;
}
// using spaceship operator
return $a <=> $b;
Benefits:
- Concise: Replaces complex if-else chains
- Readable: Clear intention for comparison
- Consistent: Always returns -1, 0, or 1
- Type-safe: Handles different data types predictably
PHP Match Expression (match)
PHP Match Expression (match)
The PHP match expression is a powerful feature introduced in PHP 8.0 that provides a more concise and flexible alternative to switch statements.
Basic Match Syntax
$result = match ($value) {
pattern1 => expression1,
pattern2 => expression2,
// ...
default => default_expression,
};
Comparison switch vs match
// switch statement
switch ($statusCode) {
case 200:
$message = 'OK';
break;
case 404:
$message = 'Not Found';
break;
case 500:
$message = 'Server Error';
break;
default:
$message = 'Unknown';
}
// match equivalent
$message = match ($statusCode) {
200 => 'OK',
404 => 'Not Found',
500 => 'Server Error',
default => 'Unknown',
};
Various Usage Examples:
// multiple conditions
$result = match ($httpCode) {
200, 201, 202 => 'Success',
400, 401, 403 => 'Client Error',
500, 501, 502 => 'Server Error',
default => 'Unknown',
};
// Match uses strict comparison (===)
$result = match ($value) {
0 => 'Integer zero',
'0' => 'String zero',
false => 'Boolean false',
default => 'Other',
};
// Complex Expressions
$age = 25;
$category = match (true) {
$age < 13 => 'Child',
$age < 20 => 'Teenager',
$age < 65 => 'Adult',
default => 'Senior',
};
// returning different types
function processValue($value) {
return match ($value) {
'int' => 42,
'string' => 'Hello World',
'array' => [1, 2, 3],
'bool' => true,
default => null,
};
}
// Using with arrays
$user = [
'role' => 'admin',
'status' => 'active'
];
$permissions = match ($user['role']) {
'admin' => ['read', 'write', 'delete'],
'editor' => ['read', 'write'],
'viewer' => ['read'],
default => [],
};
// nested match expressions
$result = match ($type) {
'number' => match ($value) {
$value > 0 => 'Positive',
$value < 0 => 'Negative',
default => 'Zero',
},
'string' => 'String type',
default => 'Unknown type',
};
// Conditional Logic in Patterns
$score = 85;
$grade = match (true) {
$score >= 90 => 'A',
$score >= 80 => 'B',
$score >= 70 => 'C',
$score >= 60 => 'D',
default => 'F',
};
Advantages Over Switch
- Returns a value - Can be assigned directly to variables
- No fall-through - Prevents accidental bugs
- Strict comparisons - More predictable behavior
- More concise - Less boilerplate code
- Better error handling - Throws UnhandledMatchError for unhandled cases
Important Notes
- Match expressions must be exhaustive or include a default case
- Throws UnhandledMatchError if no pattern matches and no default is provided
- Each arm must be a single expression (use anonymous functions for complex logic)
- Patterns are evaluated in order, first match wins
The match expression is a significant improvement that makes conditional logic more readable, safer, and more expressive in modern PHP code.
PHP Null Coalescing Nesting AND Chaining
PHP Null Coalescing Nesting AND Chaining
The null coalescing operator is essential for writing clean, safe PHP code that gracefully handles missing data without generating warnings or errors.
Null Coalescing Assignment Operator (??)
// ternary operator usage
$value = isset($a) ? $a : (isset($b) ? $b : $c);
// null-coalescing shorthand for above solution
$value = $a ?? $b ?? $c;
Null Coalescing Assignment Operator (??=)
// Only assign if variable is null or doesn't exist
$array['key'] ??= 'default value';
$user->name ??= 'Anonymous';
// Equivalent to:
if (!isset($array['key'])) {
$array['key'] = 'default value';
}
Use with error suppression
$value = $object->property->nestedProperty ?: 'default';
echo "Value: ".$value."\r\n"; //Warning is thrown
$value = @$object->property->nestedProperty ?? 'default';
echo "Value: ".$value."\r\n"; // Value: default
PHP Null Coalescing (??) vs Elvis Operator (?:)
PHP Null Coalescing (??) vs Elvis Operator (?:)
Both operators handle null/empty values but with important differences in behavior.
Null Coalescing (??)
The null coalescing operator was introduced in PHP 7. It returns the first operand if it exists and is not NULL, otherwise it returns the second operand.
- Checks if left operand is set and not NULL
- Returns left operand if it exists and is not NULL
- Returns right operand otherwise
- Does NOT consider empty strings, 0, false as "empty"
// Sample usage below. If is $beast IS NOT set a warning will be thrown.
$pet = "puppy";
$beast = null;
echo "Result: " . ($beast ?? $pet) ."\r\n"; // Result: puppy
Elvis Operator (?:)
The ternary operator shorthand checks for truthy values (not just NULL).
- Checks if left operand is truthy (not empty, not zero, not false, not NULL)
- Returns left operand if it's truthy
- Returns right operand otherwise
- Considers empty strings, 0, false as "empty"
// Ternary Operator sample usage
$pet = "kitty";
$beast = "";
echo "Result: " . ($beast ?: $pet) ."\r\n"; // Result: kitty
$beast = "tiger";
echo "Result: " . ($beast ?: $pet) ."\r\n"; // Result: tiger
Choose an operator to use based on whether you need to distinguish between NULL and other "empty" values in your specific use case.
- Use Null Coalescing when you only want to handle NULL values specifically
- Use Elvis Operator when you want to handle all "empty" values
- Null Coalescing is safer for undefined variables (no warnings)
- Consider using null coalescing with arrays and object properties that might not exist
PHP Null-Safe(Null-Conditional) Operator (?->)
Null-Safe(Null-Conditional) Operator (?->)
The null-safe operator (?->), also known as the null-conditional operator, is a feature in several programming languages that allows you to safely access members of an object without explicitly checking for null references. If the object is null, the expression returns null instead of throwing a NullPointerException.
Basic Property Access
class User {
public ?Profile $profile = null;
}
class Profile {
public string $name = "John Doe";
public ?Address $address = null;
public function getName(): string {
return $this->name;
}
}
class Address {
public string $street = "123 Main St";
}
$user = new User();
// Safe property access
$name = $user?->profile?->name; // Returns null instead of error
var_dump($name); // NULL
// With actual data
$user->profile = new Profile();
$name = $user?->profile?->name;
var_dump($name); // string(8) "John Doe"
Method Calls
$user = new User();
// Safe method call
$result = $user?->profile?->getName(); // Returns null
var_dump($result); // NULL
$user->profile = new Profile();
$result = $user?->profile?->getName();
var_dump($result); // string(8) "John Doe"
Array Access with Null-Safe
class DataContainer {
public ?array $items = null;
public function getItems(): ?array {
return $this->items;
}
}
$container = new DataContainer();
// Safe array access
$firstItem = $container?->items[0] ?? 'default';
var_dump($firstItem); // string(7) "default"
$container->items = ['apple', 'banana'];
$firstItem = $container?->items[0] ?? 'default';
var_dump($firstItem); // string(5) "apple"
Chaining Multiple Levels
$user = new User();
$user->profile = new Profile();
$user->profile->address = new Address();
// Deep chaining
$street = $user?->profile?->address?->street;
var_dump($street); // string(11) "123 Main St"
// With null in chain
$user->profile->address = null;
$street = $user?->profile?->address?->street;
var_dump($street); // NULL
Used with Null-Coalescing Operator
$user = null;
// Null-safe + null coalescing
$userName = $user?->profile?->name ?? 'Guest';
var_dump($userName); // string(5) "Guest"
$user = new User();
$userName = $user?->profile?->name ?? 'Guest';
var_dump($userName); // string(5) "Guest"
$user->profile = new Profile();
$userName = $user?->profile?->name ?? 'Guest';
var_dump($userName); // string(8) "John Doe"
Used with Ternary Operator
$user = null;
$displayName = $user?->profile?->name ?: 'Anonymous User';
var_dump($displayName); // string(15) "Anonymous User"
Key Benefits
1. Reduces Boilerplate: Eliminates repetitive null checks
2. Prevents NullPointerExceptions: Safe access to nested properties
3. Cleaner Code: More readable and concise syntax
4. Short-Circuiting: Stops evaluation when null is encountered
5. Method Safety: Safe method calls on potentially null objects
Limitations
1. Read-Only: Cannot be used for assignment
2. Context-Specific: Only works in expressions, not statements
3. Language Support: Syntax varies between languages
4. Debugging: Can make null-related bugs harder to trace
The null-safe operator is particularly useful in scenarios with deep object graphs, API responses, configuration objects, and any situation where multiple nested objects might be null.
How To Use PHP Late Static Binding
self:: vs static:: in PHP is all about inheritance and late static binding. So what is late static binding. When building a child class there may be a static property that overrides that same static property on the parent. So when extending this class you will potentially need access to the property on both classes. The way to do this is through late static binding. You can use the self:: and static:: operators to accomplish this.
self::
- Refers to the class where the method is defined.
- Does not consider inheritance overrides.
static::
- Refers to the class that is actually called at runtime.
- This is called late static binding.
- Allows child classes to override static properties/methods and still be respected.
Example: self:: vs static::
class Animal {
public static $type = "Generic Animal";
public static function getTypeUsingSelf() {
return self::$type; // bound to Animal
}
public static function getTypeUsingStatic() {
return static::$type; // late static binding
}
}
class Dog extends Animal {
public static $type = "Dog";
}
// ------------------- USAGE -------------------
echo Dog::getTypeUsingSelf(); // Output: Generic Animal
echo "<br>";
echo Dog::getTypeUsingStatic(); // Output: Dog
PHP $this, self and parent operators
Sometimes different aspects of object oriented programming can be a little confusing if you can’t picture a use case for them. Three class operators in PHP where usage can be a little confusing at times are $this, self and parent. In this article I will try to break things down and maybe you can see where you can use this in your code. Ok so let’s begin.
1. $this
- Refers to the current object instance.
- You use $this when you want to access properties or methods of the current object.
Example:
class Animal {
public $name;
public function setName($name) {
$this->name = $name; // "this object’s" name
}
public function getName() {
return $this->name; // returns "this object’s" name
}
}
$dog = new Animal();
$dog->setName("Buddy");
echo $dog->getName(); // Output: Buddy
2. self
- Refers to the current class itself, not the instance.
- Used for static methods and static properties.
- Does not depend on an object ($this is not available in static context).
Example:
class MathHelper {
public static $pi = 3.14159;
public static function circleArea($radius) {
return self::$pi * $radius * $radius; // accessing static property with self
}
}
echo MathHelper::circleArea(5); // Output: 78.53975
3. parent
- Refers to the immediate parent class.
- Used when you want to access a method or constructor from the parent class that is overridden in the child.
Example:
class Animal {
public function makeSound() {
return "Some generic animal sound";
}
}
class Dog extends Animal {
public function makeSound() {
// Call parent method, then add more
return parent::makeSound() . " and Woof!";
}
}
$dog = new Dog();
echo $dog->makeSound(); // Output: Some generic animal sound and Woof!
Now to summarize:
- $this refers to an instance of the class. It isn’t available in a static context, therefore cannot be used within a static class function.
- The self:: operator refers to the class-level property. It is used in a static context and refers to the actual class itself.
- The parent:: operator calls the overridden method from the parent class. It’s used in inheritance typically to call an overwritten method on the parent class.
Here is a really good example that should help you concieve these concepts and clear up any confusion.
class Animal {
public $name;
public static $kingdom = "Animalia";
public function __construct($name) {
$this->name = $name; // instance reference
}
public function describe() {
return "I am an animal named {$this->name}.";
}
public static function getKingdom() {
return "Kingdom: " . self::$kingdom; // static reference
}
}
class Dog extends Animal {
public function describe() {
// Use parent to get base description
$base = parent::describe();
// Add Dog-specific description
return $base . " I am also a dog that says Woof!";
}
public function introduce() {
// `$this` calls instance method
return $this->describe();
}
public static function getInfo() {
// `self` calls static property from this class (or parent if not overridden)
return "Dogs belong to " . self::$kingdom;
}
}
// ------------------- USAGE -------------------
// Create an object
$dog = new Dog("Buddy");
// $this -> instance reference
echo $dog->introduce();
// Output: I am an animal named Buddy. I am also a dog that says Woof!
echo "<br>";
// self -> static reference
echo Dog::getInfo();
// Output: Dogs belong to Animalia
echo "<br>";
// parent -> calling parent method inside child
echo $dog->describe();
// Output: I am an animal named Buddy. I am also a dog that says Woof!
echo "<br>";
// static method from parent
echo Animal::getKingdom();
// Output: Kingdom: Animalia