Web Development Articles

PHP Null Coalescing (??) vs Elvis Operator (?:)

0 👍
👎 0
 Laravel
 PHP

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 Coalescing Assignment (??=)

0 👍
👎 0
 PHP

PHP Null-Coalescing Assignment (??=)

The PHP Null-Coalescing Assignment operator ??= is a shorthand that combines the null coalescing operator ?? with an assignment = operator.


Some benefits of the null coalescing assignment operator is it reduces code verbosity significantly. It’s readable with clear intent for setting defaults. It’s safe and avoids undefined variable notices. It’s efficient with a single operation instead of multiple lines.

Below is 3 different ways of accomplishing the same objective. The value of $variable will be 30. The first example uses the ??= (null-coalescing assignment) operator. Notice it's a shorthand for the other 2 similar methods:

 

 // Null-Coalescing Assignment (all-in-one)

 $variable ??= 30;

 

 // Null Coalescing combined with Assignment

 $variable = $variable ?? 30;

 

 // Ternary Operator combined with Assignment

 $variable = $variable ? $variable : 30;


Here are a few different ways of using the Null-Coalescing Assignment operator
??=

 

 // Variable is null

 $name = null;

 $name ??= 'Peter';

 echo $name; // Output: 'Peter'

 

 // Variable already has a value

 $count = 25;

 $count ??= 30;

 echo $count; // Output: 25 (unchanged)

 

 // Variable doesn't exist

 $location ??= 'Chicago';

 echo $location; // Output: 'Chicago'

 

 

Javascript Null Coalescing Operator ??

0 👍
👎 0
 NodeJS

The double question mark ?? in javascript is referred to as the null coalescing operator.  It was introduced in JavaScript ES2020.  It allows you to check for null or undefined variable.   In most cases the order of operation for this operator follows the math and comparison operators.  Below are a few examples: 


Example 1:
let myval = null;
console.log(myval ?? 20); // output is 20 because myval is null

Example 2:
console.log(myval ?? 20); // output is 20 because myval is undefined

Example 3:
let myval = [];
console.log(myval ?? [1,2,3]);  // output is [] because it isn't null and it's not undefined

If the myval is anything other than null or undefined, the output will be the value of the right-hand side of the equation.

 

self:: vs static:: in PHP

0 👍
👎 1
 PHP
 LAMP

self:: vs static:: in PHP is all about inheritance and late static binding.  It’s used when you are dealing with overrides and methods coming from the parent class.

 

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.

 

 class Automobile {

    public static $type = "Automobile";

 

    public static function getTypeUsingSelf() {

        return self::$type// bound to Automobile

    }

 

    public static function getTypeUsingStatic() {

        return static::$type; // late static binding

    }

 }

 

 class Car extends Automobile {

    public static $type = "Car";

 }

 

 class Truck extends Automobile {

    public static $type = "Truck";

 }

 

 class Van extends Automobile {

    public static $type = "Van";

 }

 

 // ------------------- USAGE -------------------

 

 echo Car::getTypeUsingSelf();   // Output: Automobile

 echo "<br>";

 echo Car::getTypeUsingStatic(); // Output: Car

 

 

Javascript Map, Filter, Reduce methods

0 👍
👎 0
 MongoDB

Map

The map() method is used for creating a new array from an existing one, applying a function to each one of the elements of the first array.

let numbers = [1, 2, 3, 4, 5];
let doubled = numbers.map(num => num * 2);
console.log(doubled) // [2, 4, 6, 8, 5] 

Filter

The filter() method takes each element in an array and it applies a conditional statement against it. If this conditional returns true, the element gets pushed to the output array. If the condition returns false, the element does not get pushed to the output array.

const numbers = [1, 2, 3, 4];
const odds = numbers.filter(num => num % 2 === 1);
console.log(odds); // [1, 3]

Or with an array of Objects you can implement filter() like the following.  

const students = [
{name: 'eric', age: 12},
{name: 'Jenny' age: 11},
{name: 'Freddy', age: 9}
];
const overTen = students.filter(student => student.age > 10); console.log(overTen); // [{name:'Eric', age:12}, {name:'Jenny', age:11}]

Reduce

The reduce() method reduces/calculates a value down to a single value. To get the output value, it runs a reducer function on each element of the array.

const array1 = [1, 2, 3, 4];   // 0 + 1 + 2 + 3 + 4
const initialValue = 10;
const sumWithInitial = array1.reduce(
(accumulator, currentValue) => accumulator + (currentValue * 10), 
initialValue
);

// Expected output is 110.  Ok so the accumulator starts at the value of zero.  And then accumulator is accumulator plus currentValue times 10.  Add 10(initialValue... we set it to 10) + 10 + 20 + 30 + 40

 

Laravel Eloquent ORM Polymorphism Examples

0 👍
👎 0
 Laravel
 PHP
 PostgreSQL
 MySQL

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 Object __invoke()

0 👍
👎 0
 PHP

What is the __invoke() method used for in objects?  The __invoke() method is a PHP magic method that allows an object to be called as if it were a function.  It’s great for maintaining state and focusing on a single calculation.

Let’s take a look a more practical use.  In this example we will use it for issuing API requests:

 

 class HttpRequest {

   

    public function __construct(private string $url)

    {   

    }

 

    public function __invoke($data) {

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $this->url);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        $response = curl_exec($ch);

        curl_close($ch);

        return $response;

    }

 }

 

 $amazon = new HttpRequest('https://api.example.com/amazon/store');

 $temu = new HttpRequest('https://api.example.com/temu/store');

 

 $amazonResponse = $amazon(['item_id'=>12333]);

 $temuResponse = $amazon(['item_id'=>12333]);