DEV Community

loading...

The ArrayAccess Interface: A Practical Use

Charles Pellens
・2 min read

Introduction

Having many years of experience with PHP, it contains some mysterious (and sometimes interesting) functionality that isn't always in plain sight. While some of these can create and endless stream of unanticipated bugs in your code, a few can actually benefit your code by making use of code patterns that otherwise aren't used in many other mainstream programming languages.

Definition

This interface contains four method declarations:

  • abstract public offsetExists( mixed $offset ): bool
  • abstract public offsetGet( mixed $offset ): mixed
  • abstract public offsetSet( mixed $offset, mixed $value ): void
  • abstract public offsetUnset( mixed $offset ): void

Purpose

Typically, an interface is used to define the interactivity between data types. However, PHP contains some behind-the-scenes functionality with this interface that may be of use in your next project: indexing your objects as an array.

Example - Storing singletons within a container

When developing plugins in WordPress, I typically define my post types as classes, which are usually singleton instances. It wouldn't make sense for a plugin to contain more than one instance of a post type definition. Additionally, we can use this pattern to take care of some dependency injection.

For these reason, I will implement the ArrayAccess interface on my plugin class' definition (which, again, acts as the container). See the below code that I quickly wrote up to explain this pattern:

<?php

namespace MyWorkspace\Plugin;

use \ArrayAccess;

class Plugin implements ArrayAccess
{
    /** @var PostType[] $postTypes */
    protected array $postTypes = [];

    public function offsetGet(mixed $offset): PostType
    {
        return $this->postTypes[$offset];
    }

    public function offsetExists(mixed $offset): bool
    {
        return isset($this->postTypes[$offset])
            && ($this->postTypes[$offset] instanceof PostType);
    }

    public function offsetSet(mixed $offset, mixed $value): void
    {
        if ($value instanceof PostType) {
            $this->postTypes[$offset] = $value;
        }
    }

    public function offsetUnset(mixed $offset): void
    {
        unset($this->postTypes[$offset]);
    }

    public function register(string $className): void {
        /* ... register the post type ... */
        $this[$className] = new $className($this);
    }
}

class SomePostType extends PostType {
/* ... */
}

// Define the plugin and register SomePostType
$myPlugin = new Plugin();
$myPlugin->register(SomePostType::class);

// Fetch the instance of SomePostType
$myPostType = $myPlugin[SomePostType::class];

Enter fullscreen mode Exit fullscreen mode

Thanks for Reading!

Thank you for reading my first article on Dev.to. I hope you found this to be informative, or thought-provoking at a minimum. There are lots of other opportunities to put this interface to use. How do you currently (or plan to) use this? Would you like to see more write ups about PHP features which are lesser known?

Discussion (0)