PHP Type Declarations

Building Strong Foundations through Declarations

If you come from the olden days of PHP, you might have been spoiled by having PHP automatically declare types for you. The convenience is not something you want every time. Sometimes you want to be able to specify what type of data you want to store or return.

It is still optional in PHP; it’s up to you whether you want to use it or not. If you do use it, which I encourage you to do so, and you specify the wrong data type, PHP will throw an error.

As of PHP 7, we can add PHP return type declarations.

<?php

function x(): int {
  return 1;
}

Type declarations also allow us to specify what type of data type the parameter will accept. To specify the type, just add the type in front of the parameter.

<?php

function x( int $y ) {
  return 1;
}

As of PHP 7, PHP will throw a type-error-exception if the incorrect data type is presented.

Any type can be allowed to accept null values as long as the parameter has a default null value.

<?php

function x( int $y = null ) {
  return 1;
}

PHP doesn’t require for you to use type declaration everywhere. To illustrate this, let’s make a modification to our previous GermanShepherd class.

https://www.dinocajic.com/php-this-keyword/

We won’t touch the constant and property types and we’ll only modify a couple of the methods. The first modification will be to the sleep() method. Let’s declare the $energy_level parameter as an int.

<?php

class GermanShepherd {
  // ...
  public function sleep( int $energy_level = 100 ) {
      if ( $energy_level < 40 ) {
          echo "I'm sleeping";
      } else {
          echo "I don't want to sleep";
      }
  }
}

If you now try to pass any other type of argument besides an int, you will get an error. For example, instantiate the object and pass a string to the sleep() method. You should get a TypeError fatal error.

$gs = new GermanShepherd();
$gs->sleep(“Dino”);

We’ll also make modifications to the get_eye_color() and does_shed() methods. These methods return strings, so we’ll specify string as the return type.

<?php

class GermanShepherd {
  // ...
  
  public function get_eye_color(): string
  {
      return $this->eye_color;
  }

  public function does_shed(): string
  {
      return ( $this->does_shed ) ? "Yes" : "No";
  }
  
  // ...
}

Finally, let’s modify the get_scientific_classification() method and specify array as the return type.

<?php

class GermanShepherd {
  
  // ...
  
  public function get_scientific_classification(): array
  {
      return [
          "kingdom" => $this->kingdom,
          "phylum" => $this->phylum,
          "class" => $this->class,
          "order" => $this->order,
          "family" => $this->family,
          "genus" => $this->genus,
          "species" => $this->species,
          "subspecies" => $this->subspecies,
          "breed" => $this->breed
      ];
  }
}

The fully modified code can be seen below. Note that only some items received the type declaration; most did not.

<?php
// Type Declarations
class GermanShepherd {

    const HAS_HEART = true;
    const HAS_TAIL = true;

    public $eye_color = "Brown";
    public $dob = "January 30, 2017";
    public $does_shed = true;
    public $kingdom = "Animalia";
    public $phylum = "Chordata";
    public $class = "Mammalia";
    public $order = "Carnivara";
    public $family = "Canidae";
    public $genus = "Canis";
    public $species = "Canis Lupus";
    public $subspecies = "Canis Lupus Familiaris";
    public $breed = "German Shepherd Dog";
    public $fur_color = "Black and Tan";

    public function walk() {
        echo "I'm walking";
    }

    public function bark() {
        echo "I'm barking";
    }

    public function sleep( int $energy_level = 100 ) {
        if ( $energy_level < 40 ) {
            echo "I'm sleeping";
        } else {
            echo "I don't want to sleep";
        }
    }

    public function get_eye_color(): string
    {
        return $this->eye_color;
    }

    public function does_shed(): string
    {
        return ( $this->does_shed ) ? "Yes" : "No";
    }

    public function get_scientific_classification(): array
    {
        return [
            "kingdom" => $this->kingdom,
            "phylum" => $this->phylum,
            "class" => $this->class,
            "order" => $this->order,
            "family" => $this->family,
            "genus" => $this->genus,
            "species" => $this->species,
            "subspecies" => $this->subspecies,
            "breed" => $this->breed
        ];
    }
}

$gs_dog = new GermanShepherd();
$gs_dog->sleep(10);
echo "<br>";
echo $gs_dog->get_eye_color() . "<br>";
echo $gs_dog->does_shed() . "<br>";

var_dump( $gs_dog->get_scientific_classification() );

For the Car class, let’s change the property types and specify the return types for each method. Each of our methods return a string, so we’ll specify the string return type for each method.

<?php

class Car {
  
  // ...
  
  public function turnOn(): string
  {
      if ( $this->car_on ) {
          return "The " . $this->get_make_and_model() . " is already on.";
      }

      $this->car_on = true;
      return $this->get_make_and_model() . " has been turned on.";
  }

  public function turnOff(): string
  {
      if ( $this->car_on ) {
          $this->car_on = false;
          return "The " . $this->get_make_and_model() . " has been turned off.";
      }

      return "The " . $this->get_make_and_model() . " is already off.";
  }

  public function drive(): string
  {
      if ( $this->car_on ) {
          return "I'm driving";
      } else {
          return "You gotta turn me on";
      }
  }

  public function get_make_and_model(): string
  {
      return $this->make . " " . $this->model;
  }
}

For the properties, we have strings for the color, make, model, transmission, vehicle type, and the two units of measurement properties.

<?php

class Car {

    // ...

    public string $color;
    public string $make;
    public string $model;
    public string $transmission = "6 Speed Manual";
    public string $vehicle_type = "Coupe";
    public string $exterior_um = "in";
    public string $weight_um = "lbs";

    // ...
    
}

The year, fuel type, horsepower, and torque parameters are integer values, so they’ll have an int type declaration.

<?php

class Car {
    // ...
    public int $year;
    public int $fuel_type = 93;
    public int $hp;
    public int $tq;
    // ...
}

Since the exterior dimensions and the weight of the vehicle can be stored in a decimal format, we’ll declare those as floats. We also have one additional property, car_on, that is used to store boolean values.

<?php

class Car {

    // ...
    public float $exterior_height;
    public float $exterior_width;
    public float $exterior_length;
    public float $weight;

    public bool $car_on = false;
  
    // ...
}

Continue your learning with these articles

PHP This Keyword

EMPOWERING OBJECTS TO SPEAK WITH ‘THIS’ VOICE

PHP – P47: $THIS KEYWORD

If you considered yourself the object, and you wanted to access yourself, you would use the I pronoun. If the object wants to access itself, it uses $this.

PHP Type Declarations

Building Strong Foundations through Declarations

PHP – P48: type declarations

If you come from the olden days of PHP, you might have been spoiled by having PHP automatically declare types for you. The convenience is not something you want every time. Sometimes you want to be able to specify what type of data you want to store or return.

PHP Constructor

ERECTING WORLDS FROM BLUEPRINTS WITH CONSTRUCTORS

PHP – P49: CONSTRUCTORS

If you’re used to other object oriented programming languages, you’re probably familiar with the constructor. You may also be familiar with the constructor being named as the class name; it’s just a method that shares the same name as the class name.

Leave a Reply