Web Development Articles

Using PHP Class Interface

0 👍
👎 1
 PHP

In PHP, an interface defines a contract or blueprint that any class implementing it must follow.

It specifies method signatures (the names, parameters, and visibility of methods), however does  not implement the methods.

A class that implements an interface must define all of the methods declared in the interface.

Interfaces help achieve abstraction and multiple inheritance (since a class can implement multiple interfaces).


Example:


// Define an interface

 interface Employee {

    public function clockIn(string $message);

 }

 

 // Implement the interface in a class

 class Engineer implements Employee {

    public function clockIn(string $message) {

        echo "Engineer Clock In: " . PHP_EOL;

    }

 }

 

 // Another class implementing the same interface

 class Mechanic implements Employee {

    public function clockIn(string $message) {

        echo "Mechanic Clock In: " . PHP_EOL;

    }

 }

 

 // Usage

 function processTask(Employee $employee) {

    $employee->clockIn("Task has been processed!");

 }

 

 // You can swap implementations easily

 $engineer = new Engineer();

 $mechanic = new Mechanic();

 

 processTask($engineer);  // Clock In Engineer

 processTask($mechanic);    // Clock In Mechanic

 

 

What interfaces can contain:

 - Method declarations (no body/implementation)

 - Constants (e.g. const MAX_LIMIT = 100;)

What interfaces cannot contain:

 - Properties/variables

 - Constructors with implementation

 - Method bodies

Example:

 

 interface ExampleInterface {

    // Allowed

    public function doSomething();

 

    // Allowed

    const VERSION = "1.0";

 

    // Not allowed: properties inside interfaces

    // public $name;   // This will cause an error

 }

 

 

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

 



PHP Access Modifiers (public, private, protected)

0 👍
👎 0
 PHP
 LAMP

In PHP Object-Oriented programming, public, private, and protected are access modifiers (visibility keywords) used to control how properties (variables) and methods (functions) of a class can be accessed.

They are important in Object-Oriented Programming (OOP) because they enforce encapsulation (controlling how data is exposed and used).


Public
Members declared public can be accessed from inside the class, outside of the class and by subclasses (child classes).  If no visibility is specified on a property the default will be public.


class
Car {

    public $brand;

    public function setBrand($brand) {

   $this->brand = $brand; // accessible inside the class

    }

 }

 $car = new Car();

 $car->brand = "Toyota"; // accessible outside the class

echo $car->brand; // Output: Toyota


Private

Members declared private can only be accessed inside of the class that defines them.  They cannot be accessed from outside the class or by subclasses.

 


class Car {

    private $engineNumber;

    public function setEngineNumber($num) {

       $this->engineNumber = $num; // accessible inside the class

    }

 

    public function getEngineNumber() {

       return $this->engineNumber; // allowed via public method

    }

 }

 

 $car = new Car();

 $car->setEngineNumber("ENG123");

 // echo $car->engineNumber; ERROR: Cannot access private property

 echo $car->getEngineNumber(); // Output: ENG123

 

 

Protected

Members declared protected can be accessed inside of the class, in child(sub) classes that inherit from it.  They cannot be accessed directly from outside of the class… only subclasses.

 

class Vehicle {

  protected $type = "Generic Vehicle";

 

   protected function getType() {

       return $this->type;

   }

}

 

class Car extends Vehicle {

  public function showType() {

       return $this->getType(); // accessible in child class

   }

}

 

$car = new Car();

// echo $car->type; ERROR: Cannot access protected property

echo $car->showType(); // Output: Generic Vehicle

 

 

PostgreSQL many-to-many Relationship

0 👍
👎 0
 PostgreSQL

In this example we will look at how to work with a many-to-many relationship.  So first let’s look at a situation where we can leverage a many-to-many relationship.  Imagine we have both Students and Courses.  A student can be enrolled in multiple courses and a course can have multiple students.  This is called a many-to-many relationship and requires what’s called a pivot table.  Although there aren’t any restrictions to the name of a pivot table I will call it “course_student”.  The course_student pivot table will have, at minimum, 2 foreign key fields.  A reference to courses table and a reference to students table.  

 

 

 CREATE TABLE students (

   id INT PRIMARY KEY AUTO_INCREMENT,

   name VARCHAR(100) NOT NULL,

   phone_number VARCHAR(100) UNIQUE NOT NULL,

 

 );

 

 CREATE TABLE courses (

   id INT PRIMARY KEY AUTO_INCREMENT,

   title VARCHAR(100) NOT NULL,

   description TEXT NOT NULL

 );

 

 -- The pivot table has a reference key to each table

 CREATE TABLE course_student (

   student_id INT,

   course_id INT,

   PRIMARY KEY (student_id, course_id),

   FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE,

   FOREIGN KEY (course_id) REFERENCES courses(id) ON DELETE CASCADE
);

 

Below are a few useful ways to query this schema. Assuming you are familiar with a LEFT JOIN, these queries specifically use LEFT JOIN for connecting the three tables. courses to course_student to students


# Get all courses that student with id = 2 is enrolled

SELECT c.id course_id, c.title, s.id student_id, s.name

FROM students s

LEFT JOIN course_student cs ON s.id = cs.student_id

LEFT JOIN course c ON c.id = cs.course_id

WHERE s.id = 2;

 

# Get all students enrolled in course with id = 1

 SELECT c.id course_id, c.title, s.id student_id, s.name

 FROM courses c

 LEFT JOIN course_student cs ON c.id = cs.course_id

 LEFT JOIN student s ON s.id = cs.student_id

 WHERE c.id = 1;

 

 

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

 

PHP Null Coalescing Nesting AND Chaining

0 👍
👎 0
 Laravel
 PHP

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 Match Expression (match)

0 👍
👎 0
 Laravel
 PHP

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.