master

laravel/framework

Last updated at: 29/12/2023 09:25

Optional.php

TLDR

The Optional.php file in the Illuminate\Support namespace defines the Optional class, which implements the ArrayAccess interface and uses the Macroable trait. This class provides methods for dynamically accessing properties, checking property existence, and calling methods on an underlying object.

Methods

There are no methods defined in the file.

Classes

Optional

The Optional class is responsible for providing optional access to the properties and methods of an underlying object. It implements the ArrayAccess interface and uses the Macroable trait.

The class has the following public methods:

  • __get($key): Dynamically access a property on the underlying object.
  • __isset($name): Dynamically check if a property exists on the underlying object.
  • offsetExists($key): Determine if an item exists at an offset.
  • offsetGet($key): Get an item at a given offset.
  • offsetSet($key, $value): Set an item at a given offset.
  • offsetUnset($key): Unset an item at a given offset.
  • __call($method, $parameters): Dynamically pass a method call to the underlying object.

These methods provide a convenient way to interact with an object and handle cases where the object may be null or inaccessible.

<?php

namespace Illuminate\Support;

use ArrayAccess;
use ArrayObject;
use Illuminate\Support\Traits\Macroable;

class Optional implements ArrayAccess
{
    use Macroable {
        __call as macroCall;
    }

    /**
     * The underlying object.
     *
     * @var mixed
     */
    protected $value;

    /**
     * Create a new optional instance.
     *
     * @param  mixed  $value
     * @return void
     */
    public function __construct($value)
    {
        $this->value = $value;
    }

    /**
     * Dynamically access a property on the underlying object.
     *
     * @param  string  $key
     * @return mixed
     */
    public function __get($key)
    {
        if (is_object($this->value)) {
            return $this->value->{$key} ?? null;
        }
    }

    /**
     * Dynamically check a property exists on the underlying object.
     *
     * @param  mixed  $name
     * @return bool
     */
    public function __isset($name)
    {
        if (is_object($this->value)) {
            return isset($this->value->{$name});
        }

        if (is_array($this->value) || $this->value instanceof ArrayObject) {
            return isset($this->value[$name]);
        }

        return false;
    }

    /**
     * Determine if an item exists at an offset.
     *
     * @param  mixed  $key
     * @return bool
     */
    public function offsetExists($key): bool
    {
        return Arr::accessible($this->value) && Arr::exists($this->value, $key);
    }

    /**
     * Get an item at a given offset.
     *
     * @param  mixed  $key
     * @return mixed
     */
    public function offsetGet($key): mixed
    {
        return Arr::get($this->value, $key);
    }

    /**
     * Set the item at a given offset.
     *
     * @param  mixed  $key
     * @param  mixed  $value
     * @return void
     */
    public function offsetSet($key, $value): void
    {
        if (Arr::accessible($this->value)) {
            $this->value[$key] = $value;
        }
    }

    /**
     * Unset the item at a given offset.
     *
     * @param  string  $key
     * @return void
     */
    public function offsetUnset($key): void
    {
        if (Arr::accessible($this->value)) {
            unset($this->value[$key]);
        }
    }

    /**
     * Dynamically pass a method to the underlying object.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        if (static::hasMacro($method)) {
            return $this->macroCall($method, $parameters);
        }

        if (is_object($this->value)) {
            return $this->value->{$method}(...$parameters);
        }
    }
}