Menu
Coddy logo textTech

Nullable Types

Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 64 of 91.

Sometimes a value legitimately might not exist. A user might not have a middle name, or a search might return no results. Nullable types let you explicitly declare that a parameter, return value, or property can be either a specific type or null.

Add a question mark ? before the type to make it nullable:

<?php
class User {
    public ?string $middleName = null;
    
    public function __construct(
        public string $firstName,
        public string $lastName
    ) {}
    
    public function getFullName(): string {
        if ($this->middleName !== null) {
            return "$this->firstName $this->middleName $this->lastName";
        }
        return "$this->firstName $this->lastName";
    }
}

$user = new User("John", "Doe");
echo $user->getFullName();

Output:

John Doe

Nullable return types work the same way. This is useful when a method might not find what it's looking for:

<?php
class UserRepository {
    private array $users = [];
    
    public function find(int $id): ?User {
        return $this->users[$id] ?? null;
    }
}

$repo = new UserRepository();
$user = $repo->find(1);
echo $user === null ? "Not found" : $user->firstName;

Output:

Not found

Using nullable types makes your code's intent clear. When you see ?string, you immediately know that null is a valid value and should be handled. Without the question mark, passing null would cause a type error.

challenge icon

Challenge

Easy

Let's build a contact management system that handles optional information gracefully using nullable types. Not everyone provides all their details, so your system needs to handle missing data elegantly.

You'll organize your code across three files:

  • Contact.php — Create a Contact class that represents a person in your contact list. Some information is required, but other details are optional:
    • Use constructor promotion for a required $name (string) and an optional $phone (nullable string, defaulting to null)
    • Add a nullable string property $email initialized to null
    • Create a method setEmail(?string $email): void that sets the email property
    • Create a method getContactInfo(): string that returns the contact's information in this format: "Name: [name]" followed by " | Phone: [phone]" only if phone is not null, followed by " | Email: [email]" only if email is not null
  • ContactBook.php — Create a ContactBook class that stores and searches contacts. Include the Contact file. The class should:
    • Have a private array to store contacts
    • Have a method addContact(Contact $contact): void that adds a contact to the collection
    • Have a method findByName(string $name): ?Contact that searches for a contact by exact name match and returns the contact if found, or null if not found
  • main.php — Include the ContactBook file. You'll receive three inputs: a name to add, a phone number (or the string "none" if no phone), and a name to search for.

    Create a ContactBook and add a new Contact using the first two inputs. If the phone input is "none", pass null as the phone number.

    Then search for a contact using the third input. If found, print the contact's info using getContactInfo(). If not found, print "Contact not found".

This challenge demonstrates how nullable types make your code's intent clear — when you see ?string for phone or email, you immediately know these fields are optional and might not have a value.

Cheat sheet

Use a question mark ? before a type to make it nullable, allowing it to accept either the specified type or null:

<?php
class User {
    public ?string $middleName = null;
    
    public function __construct(
        public string $firstName,
        public string $lastName
    ) {}
}

Nullable types work with properties, parameters, and return types:

<?php
class UserRepository {
    public function find(int $id): ?User {
        return $this->users[$id] ?? null;
    }
}

Check for null before using nullable values:

<?php
if ($this->middleName !== null) {
    return "$this->firstName $this->middleName $this->lastName";
}
return "$this->firstName $this->lastName";

Without the ?, passing null to a typed parameter or property causes a type error. Nullable types make it explicit that null is a valid value.

Try it yourself

<?php

require_once 'ContactBook.php';

// Read inputs
$nameToAdd = trim(fgets(STDIN));
$phoneInput = trim(fgets(STDIN));
$nameToSearch = trim(fgets(STDIN));

// TODO: Create a ContactBook instance

// TODO: Determine the phone value (null if input is "none", otherwise use the input)

// TODO: Create a new Contact with the name and phone

// TODO: Add the contact to the ContactBook

// TODO: Search for a contact using nameToSearch

// TODO: If found, print the contact's info using getContactInfo()
// TODO: If not found, print "Contact not found"

?>
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming