Web Development Articles

PHP Spaceship Operator (<=>)

0 👍
👎 0
 Laravel
 PHP

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

 

JavaScript Self-Invoked Functions (IIFEs)

0 👍
👎 0
 NodeJS
 Javascript

What is a self-invoked function? (IIFE)

A self-invoked function, also called an Immediately Invoked Function Expression (IIFE) is a Javascript function expression that is invoked immediately after its declaration.  A self-invoked function can be a valuable tool for creating isolated scopes and managing variable privacy in javascript applications.

 

Key aspects of IIFEs:

 

- IIFEs execute immediately when defined

- Allows creation of private scopes without polluting global namespace

- Return values can be assigned to variables

- Parameters can be passed to IIFEs



Basic syntax:

 

 (function() {

    // code here

 })();

 

 // OR arrow functions (ES6+)

 (() => {

       // code here

 })();

 

 

 

Why are IIFEs Necessary?

Immediate Execution with Parameters

 

 // Immediately logs provided data

 (function(date, location) {

    console.log(`Date: ${date.toDateString()}`);

    console.log(`Location: ${location}`);

 })(new Date(), 'Seattle');

 

 // Immediately logs:

 // Date: Thu Oct 16 2025

 // Location: Seattle

 

 

Avoiding Global Namespace Pollution

 

 // if multiple scripts use the same variable names

 // they won't conflict

 (function() {

    const restaurant = "Dairy Queen";

    console.log(user); // "Dairy Queen"

 })();

 

 (function() {

    const restaurant = "Burger King";

    console.log(user); // "Burger King"

 })();

 

 

Data Privacy/Encapsulation

 

 // Problem: counter value is vulnerable.

 var counter = 0;

 function increment() {

    return ++counter;

 }

 

 // FIX: keeps variables private. counterModule isn't directly accessible

 const counterModule = (function() {

    let count = 0;

   

    return {

        increment: function() {

            return ++count;

        },

        decrement: function() {

            return --count;

        },

        getCount: function() {

            return count;

        }

    };

 })();

 

 counterModule.count = 100; // WONT WORK!!

 // count is not accessible directly

 

 console.log(counterModule.getCount()); // 0

 counterModule.increment();

 console.log(counterModule.getCount()); // 1

 // OUPTUT: 0 1

 

 

Module Pattern Implementation

 

 const User = (function() {

    let memory = 0;

   

    function add(a, b) {

        return a + b;

    }

   

    function store(value) {

        memory = value;

    }

   

    function recall() {

        return memory;

    }

   

    // Only expose public methods

    return {

        add: add,

        store: store,

        recall: recall

    };

 })();

 

 console.log(Calculator.add(5, 3)); // 8

 Calculator.store(10);

 console.log(Calculator.recall()); // 10

 // memory is private and inaccessible

 

 

PHP $this, self and parent operators

0 👍
👎 0
 Laravel
 PHP

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

 




How To Use PHP Late Static Binding

0 👍
👎 0
 Laravel
 PHP

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

 



Solve Vue.js Component Overload with Parent-Child Patterns

0 👍
👎 0
 Laravel
 VueJS

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>

 

 

Understanding JavaScript Promise.all()

0 👍
👎 0
 Javascript

Promise.all() takes an array of promises and returns a single promise that fulfills when all input promises have been fulfilled, or rejects immediately if any of the input promises reject.


Basic Usage:

 

 // resolve promise1

 const promise1 = new Promise((resolve, reject) => {

   setTimeout(resolve, 200, "King");

 });

 

 // resolve promise2

 const promise2 = new Promise((resolve, reject) => {

   setTimeout(resolve, 100, "Queen");

 });

 

 // Notice that all promises supplied must resolve or an error is

 // thrown and the promise will be handled in catch()

 Promise.all([promise1, promise2]).then(

    (fulfilled) => {

        console.log(`All fulfilled: ${fulfilled.length}`);

        console.log(fulfilled)

    }

 ).catch(e => console.log(e));

 

 // All fulfilled:

 // [ 'King', 'Queen' ]


All Promises Must Resolve:

If any Promise in the chain is rejected, a Promise error is returned and will be handled with Promise.catch().  It’s important to get into a habit of providing a Promise.catch() to handle any rejected results.
 

 

 // All promises are resolved successfully! An array with resolved results
// from each of the fulfilled promises is provided to the chained
// Promise.then(x => console.log(x)) method.

 Promise.all([

    Promise.resolve("Success 1"),

    Promise.resolve("Success 2"),

    Promise.resolve("Success 3")

  ]).then(results => {

    console.log(results); // ['Success 1', 'Success 2', 'Success 3']

  });

 



Handling Rejections Gracefully:

 

 // One promise rejects - all others are ignored

 const promise1 = new Promise((resolve, reject) => {

    setTimeout(resolve, 200, "King");

 });

 

 const promise2 = new Promise((resolve, reject) => {

    setTimeout(reject, 100, "Queen rejected!");

 });

 

 Promise.all([promise1, promise2])

 .then((fulfilled) => {

    // This will NOT execute

    console.log("All fulfilled");

 })

 .catch(e => {

    console.log("Error:", e); // "Error: Queen rejected!"

 });

 

// Output: "Error: Queen rejected!"

 



Order of Preservation:


A results array is returned ordered in the sequence in which the promise fulfills in the list. All promises are executed in parallel. The first promise to resolve will be the first element of the return array.  Notice in this example the first promise in the supplied promises array is actually the last promise in the return array of resolved promises.

 

 // Order of Preservation

 // Results maintain the same order as input promises

 Promise.all([

   new Promise((resolve, reject) => {

      setTimeout(resolve, 100, "First");

   }),

   Promise.resolve("Second"),

   Promise.resolve("Third")

  ])

 .then(results => {

   console.log(results[0]); // "Second"

   console.log(results[1]); // "Third"

   console.log(results[2]); // "First"

 });

 



Immediate Rejection:

Notice slowResolve below continues executing but the results are ignored. It’s handled in Promise.catch()

 

 // If any promise rejects, Promise.all immediately rejects

 // without waiting for other promises

 const fastResolve = new Promise(resolve =>

   setTimeout(resolve, 100, "Fast")

 );

 const slowResolve = new Promise(resolve =>

   setTimeout(resolve, 500, "Slow")

 );

 const fastReject = new Promise((resolve, reject) =>

   setTimeout(reject, 50, "Rejected!")

 );

 

 Promise.all([fastResolve, slowResolve, fastReject])

 .then(results => {

    // Never executes

    console.log("Success:", results);

 })

 .catch(error => {

   console.log("Caught:", error); // "Caught: Rejected!"

   // Both fastResolve and slowResolve continue executing but its result are ignored

 });

 



Always Include Proper Error Handling:

 

 Promise.all([apiCall1(), apiCall2(), apiCall3()])

 .then(([result1, result2, result3]) => {

   // Process all results

   console.log("All API calls succeeded");

 })

 .catch(error => {

   console.error("One or more API calls failed:", error);

   // Handle the error appropriately

 });

 



Parallel Processing

It’s perfect for processing multiple API calls in parallel. 

 

 const userId = 123;

 const api1 = new Promise(resolve => fetch(`/api/users/${userId}`));
const api2 = new Promise(
    resolve => fetch(`/api/users/${userId}/posts`)
);

 const api3 = new Promise(
    resolve => fetch(`/api/users/${userId}/settings`)
);

 Promise.all([

    api1,

    api2,

    api2

 ])

 .then(responses => Promise.all(responses.map(r => r.json())))

 .then(([user, posts, settings]) => {

    console.log("User profile, posts and settings loaded");

    // Use all data

 })

 .catch(error => {

    console.error(error);

 });

 

 

Promise.all() Summary:

1. Promise.all() waits for all promises to resolve or any to reject

2. Order of results matches the input array order

3. Fast failure - rejects immediately on first rejection

4. Always use .catch() to handle potential rejections

5. Perfect for parallel operations that don't depend on each other

 

 

If you need different behavior (like waiting for all promises to settle regardless of outcome), checkout Promise.allSettled().

 

How to use JavaScript Promise catch()

0 👍
👎 0
 Javascript

There are a few ways to take advantage of the Promise catch method.  The catch() method is run when the Promise is rejected or throws an error.  Return value from a Promise is passed forward to the catch() method.  Promises can be chained as well.  It simply forwards the return value from the chained Promise to the catch method if the Promise is rejected or an error is thrown.

 

A basic example of using catch() with a Promise reject:

 

 // using Promise.reject

 let rejectPromise = new Promise(function(resolve, reject){

    reject("promise rejected")

 })

 

 function displayCatch(x) {

    console.log(x)

 }

 

 rejectPromise.catch(x => displayCatch(x))

 

 

A basic example of using catch() by throwing an error from the promise:

 

 // throw an error

 let promiseError = new Promise(function(resolve, reject){

    throw "throw error"

 })

 function displayCatch(x) {

    console.log(x)

 }

 promiseError.catch(x => displayCatch(x));

 

 

Chained promises.  Reject or throw error from chained Promise:

 

 let resolvePromise = new Promise(function(resolve, reject) {

    setTimeout(resolve, 50, "resolved chained");

 })

 

 function resolveDisplay(x) {

    console.log(x)

    throw "throw error from chained Promise"

 }

 

 function displayCatch(x) {

    console.log(x)

 }

 

 resolvePromise.then(x => resolveDisplay(x)).catch(x => displayCatch(x))