All flavors of PHP 8 getters
Tags: php, programming, beginners, codequality
Published: 2021-08-01 11:15:57

---
title: All flavors of PHP 8 getters
published: true
description: A quick recap of the many ways you can get value from objects in PHP
tags: [php, programming, beginners, codequality]
//cover_image: https://direct_url_to_image.jpg
---

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

```php
class User
{
    public string $name = "Robert PAULSON";
}
```

**✅ Pros**

+ No need to write a getter method

**❌ Cons**

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

## Classic getter

```php
class User
{
    public function getName(): string
    {
        return "Robert PAULSON";
    }
}
```

**✅ Pros**

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

**❌ Cons**

+ ¯\\\_(ツ)\_/¯

## Classic getter, but without a verb

```php
class User
{
    public function name(): string
    {
        return "Robert PAULSON";
    }
}
```

**✅ Pros**

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

**❌ Cons**

+ Methods without a verb can be confusing

## Getter/setter

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

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

        return $this->name;
    }
}
```

**✅ Pros**

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

**❌ Cons**

+ What if you want to set the value to `null`?
+ Violates the [Single Responsibility Principle](https://en.wikipedia.org/wiki/Single-responsibility_principle)

## Magic getter

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

    public function __get($key)
    {
        if ($key == 'name') {
            return $this->name;
        }
    }
}
```

**✅ 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](https://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.property.pkg.html) `@property` or PHPStorm won't *"see"* it

## Offset getter

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

    public offsetGet($offset)
    {
        if ($offset == 'name') {
            return 'Robert PAULSON';
        }
    }
}
```

**✅ Pros**

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

**❌ Cons**

+ Same as magic getter

## Magic call

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

**✅ 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](https://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.method.pkg.html) `@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

```php
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"
```

**✅ Pros**

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

**❌ Cons**

+ I hope you know what you're doing

## Encapsulation violation

```php
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
```

**✅ Pros**

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

**❌ Cons**

+ Very slow
+ Quite ugly

## Returning a closure

```php
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"
```

**✅ 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 🤗