PHP · STEP 2 · OOP
PHP · OOP
PHP 8.5 (any 8.3+ works): classes, constructors, methods, inheritance and static members — the JavaScript version next to the PHP version, with constructor promotion, readonly properties, match and enums.
What you will learn#
- How to Create a Class
- How to Instantiate a Class
- Write a Constructor and Methods
- Create an Inherited Class
- Write Static Methods/Properties
Below you'll see JavaScript examples of object-oriented patterns and their PHP counterparts.
Creating and Instantiating a Class#
In Javascript
// Creating a Classclass Dog {} // Instantiationconst Sparky = new Dog();In PHP
<?php // Creating a classclass Dog {} // Instantiation: same new keyword$sparky = new Dog();The Constructor and Methods#
In Javascript
// Creating a Classclass Dog { // The constructor runs when we instantiate a new instance constructor(name, age) { this.name = name; this.age = age; } // A Method bark() { console.log(`${this.name} barks`); }} // Instantiationconst Sparky = new Dog("Sparky", 4);Sparky.bark();in PHP
<?php class Dog{ // Properties are declared up front, with a visibility and (since 7.4) a type public string $name; public int $age; // The constructor runs when we instantiate a new instance public function __construct(string $name, int $age) { $this->name = $name; $this->age = $age; } // A method; -> reaches into the object where JavaScript uses a dot public function bark(): void { echo "{$this->name} barks\n"; }} // Instantiation$sparky = new Dog("Sparky", 4);$sparky->bark();Where JavaScript creates this.name on first assignment, PHP wants the property declared (undeclared ones are deprecated since 8.2). Because "declare, take as parameter, assign" is so repetitive, PHP 8.0 added constructor property promotion: put the visibility on the parameter — public function __construct(public string $name, public int $age) {} — and all three happen at once. The inheritance example below uses it. Add readonly (PHP 8.1) when a property must never change after construction; private and protected do what JavaScript's #private fields do.
Inheritance#
In Javascript
// Creating a Classclass Dog { // The constructor runs when we instantiate a new instance constructor(name, age) { this.name = name; this.age = age; } // A Method bark() { console.log(`${this.name} barks`); }} class SmallDog extends Dog { constructor(name, age) { //Super calls the constructor of the parent class super(name, age); } //This will override the version of bark in the parent class bark() { console.log(`${this.name} yaps`); }} // Instantiationconst Sparky = new SmallDog("Sparky", 4);Sparky.bark();in PHP
<?php class Dog{ public function __construct( public string $name, public int $age, ) {} public function bark(): void { echo "{$this->name} barks\n"; }} // Same extends keywordclass SmallDog extends Dog{ public function __construct(string $name, int $age) { // parent:: reaches the parent class; call its constructor explicitly parent::__construct($name, $age); } // This overrides the version of bark in the parent class public function bark(): void { echo "{$this->name} yaps\n"; }} // Instantiation$sparky = new SmallDog("Sparky", 4);$sparky->bark();If a child defines no __construct, the parent's runs automatically. A class extends one parent; beyond that PHP has interface (a contract to implements) and trait (methods to use).
Static Methods and Properties#
In Javascript
// Static properties/methods belong to the class, not the instanceclass Calculator { static lastResult = 0; // a table of operator functions instead of eval() static operations = { "+": (a, b) => a + b, "-": (a, b) => a - b, "*": (a, b) => a * b, "/": (a, b) => a / b, }; static calculate(num1, num2, operator) { Calculator.lastResult = Calculator.operations[operator](num1, num2); return Calculator.lastResult; } static showLastResult() { console.log(Calculator.lastResult); }} Calculator.calculate(2, 2, "+");Calculator.showLastResult();In PHP
<?php // Static properties/methods belong to the class, not the instanceclass Calculator{ // A property declared static is shared by the whole class public static float $lastResult = 0.0; // A static method: no $this inside, called on the class public static function calculate(float $num1, float $num2, string $operator): float { // match instead of eval(): compares with ===, returns a value, must be exhaustive self::$lastResult = match ($operator) { '+' => $num1 + $num2, '-' => $num1 - $num2, '*' => $num1 * $num2, '/' => $num1 / $num2, }; return self::$lastResult; } public static function showLastResult(): void { echo self::$lastResult . "\n"; }} // Double colons access static methods/propertiesCalculator::calculate(2, 2, '+');Calculator::showLastResult(); // 4An operator missing from the match throws UnhandledMatchError rather than silently doing nothing; add a default => arm for a fallback. When a set of named values is really a type, PHP 8.1 has an enum, and match pairs with it:
<?php enum Size{ case Small; case Large;} $size = Size::Small;$text = match ($size) { Size::Small => 'fits in a bag', Size::Large => 'needs a yard',};echo $text . "\n"; // fits in a bagSize::Small is a real type — a Size $size parameter rejects a plain string — and Laravel can cast a database column straight to it.
Resources to Learn More#
- Classes and Objects — basics, properties, constructors and promotion, visibility, inheritance, static, interfaces, traits
- Enumerations and
match
See also