All flavors of PHP 8 getters

bdelespierre

Benjamin Delespierre

Posted on August 1, 2021

All flavors of PHP 8 getters

Getters are the most basic methods a class can have. Their only job is to return a value, usualy from its properties. There's isn't much to say about it.

Or is there? ๐Ÿคจ

Today I'm going to present you 10 ways you can implement a getter in PHP 8.0.

  • Public access
  • Classic getter
  • Classic getter, but without a verb
  • Getter/setter
  • Magic getter
  • Offset getter
  • Magic call
  • Reference getter
  • Encapsulation violation ๐Ÿคซ
  • Returning a closure

Let's get started!

Public access

class User
{
    public string $name = "Robert PAULSON";
}
Enter fullscreen mode Exit fullscreen mode

โœ… Pros

  • No need to write a getter method

โŒ Cons

  • Cannot be part of an interface
  • Exposes object's internal state

Classic getter

class User
{
    public function getName(): string
    {
        return "Robert PAULSON";
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… Pros

  • Can be part of an interface
  • Straightforward and easy to understand

โŒ Cons

  • ยฏ\_(ใƒ„)_/ยฏ

Classic getter, but without a verb

class User
{
    public function name(): string
    {
        return "Robert PAULSON";
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… Pros

  • Can still be part of an interface
  • Shorter than getName

โŒ Cons

  • Methods without a verb can be confusing

Getter/setter

class User
{
    private string $name = "Robert PAULSON";

    public function name(?string $name = null): string
    {
        if ($name) {
            $this->name = $name;
        }

        return $this->name;
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… Pros

  • Same as above
  • Less code to write if you also need a setter

โŒ Cons

Magic getter

/**
 * @property string $name
 */
class User
{
    private string $name = "Robert PAULSON";

    public function __get($key)
    {
        if ($key == 'name') {
            return $this->name;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… Pros

  • You can expose protected and private members on your own terms

โŒ Cons

  • You can't always typehint the returned value
  • Some companies have banned this (seriously)
  • You're going to need an annotation @property or PHPStorm won't "see" it

Offset getter

class User extends ArrayAccess
{
    public offsetExists($offset): bool
    {
        return $offset == 'name';
    }

    public offsetGet($offset)
    {
        if ($offset == 'name') {
            return 'Robert PAULSON';
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… Pros

  • Same as magic getter
  • Super cool $object['name'] notation

โŒ Cons

  • Same as magic getter

Magic call

/**
 * @method string getName()
 */
class User
{
    public function __call($method, $args)
    {
        if ($method == 'getName') {
            return 'Robert PAULSON';
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… Pros

  • Same as using magic getters
  • Save "space" by grouping several getters in one method
  • You can create aliases for your existing getters without adding new methods

โŒ Cons

  • You're going to need an annotation @method or PHPStorm won't "see" it
  • If you need this to lower the number of methods in your class, it might be the sign of a design issue

Reference getter

class User
{
    private string $name = "Robert PAULSON";

    public function &getName(): string
    {
        return $this->name;
    }
}

// usage
$user = new User;
var_dump($user); // string(14) "Robert PAULSON"

$name = &$user->getName();
$name = "Tyler DURDEN";
var_dump($user); // string(12) "Tyler DURDEN"
Enter fullscreen mode Exit fullscreen mode

โœ… Pros

  • Used for performance optimizations (eliminates the function call overhead)

โŒ Cons

  • I hope you know what you're doing

Encapsulation violation

class User
{
    private string $name = "Robert PAULSON";
}

// can't access $name because it's private
// and there's no getter to obtain its value
$user = new User();

// let's use the reflection API
$property = (new ReflectionClass(User::class))->getProperty('name');
$property->setAccessible(true);
$name = $property->getValue($user);

echo $name; // Robert PAULSON
Enter fullscreen mode Exit fullscreen mode

โœ… Pros

  • Very useful for debugging classes you don't own without rewriting them

โŒ Cons

  • Very slow
  • Quite ugly

Returning a closure

class User
{
    private $name = "Robert PAULSON";

    public function obtainNameGetter(): callable
    {
        return fn() => $this->name;
    }

    public function setName(string $name): void
    {
        $this->name = $name;
    }
}

// usage
$user = new User();
$getter = $user->obtainNameGetter();

echo $getter(); // "Robert PAULSON"

// now let's change the username
$user->setName("Tyler DURDEN");

echo $getter(); // "Tyler DURDEN"
Enter fullscreen mode Exit fullscreen mode

โœ… Pros

  • Can be used to solve circular dependencies
  • Poor-man lazy-loading implementation
  • You can compose the returned closure

โŒ Cons

  • The returned closure is a black-box
  • You cannot serialize the returned value easily

Did I miss something? Tell me what you think of this list in the comments and don't forget to like/follow, it keeps me motivated to write more articles for you ๐Ÿค—

๐Ÿ’– ๐Ÿ’ช ๐Ÿ™… ๐Ÿšฉ
bdelespierre
Benjamin Delespierre

Posted on August 1, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

All flavors of PHP 8 getters
php All flavors of PHP 8 getters

August 1, 2021

Get, set... STOP!
php Get, set... STOP!

May 12, 2020

ยฉ TheLazy.dev

About