ArrayAccess::offsetExists

(PHP 5 >= 5.0.0)

ArrayAccess::offsetExistsОпределяет, существует ли заданное смещение (ключ)

Описание

abstract public boolean ArrayAccess::offsetExists ( mixed $offset )

Определяет, существует или нет данное смещение (ключ).

Данный метод исполняется, когда используется функция isset() или функция empty() для объекта, реализующего интерфейс ArrayAccess.

Замечание:

Когда используется функция empty(), метод ArrayAccess::offsetGet() вызывается и результат проверяется только в случае, если метод ArrayAccess::offsetExists() возвращает TRUE.

Список параметров

offset

Смещение (ключ) для проверки.

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

Замечание:

Возвращаемое значение будет приведено к логическому типу, если возвращаемое значение не является логическим.

Примеры

Пример #1 Пример использования ArrayAccess::offsetExists()

<?php
class obj implements arrayaccess {
    public function 
offsetSet($offset$value) {
        
var_dump(__METHOD__);
    }
    public function 
offsetExists($var) {
        
var_dump(__METHOD__);
        if (
$var == "foobar") {
            return 
true;
        }
        return 
false;
    }
    public function 
offsetUnset($var) {
        
var_dump(__METHOD__);
    }
    public function 
offsetGet($var) {
        
var_dump(__METHOD__);
        return 
"value";
    }
}

$obj = new obj;

echo 
"Выполняется obj::offsetExists()\n";
var_dump(isset($obj["foobar"]));

echo 
"\nВыполняется obj::offsetExists() и obj::offsetGet()\n";
var_dump(empty($obj["foobar"]));

echo 
"\nВыполняется obj::offsetExists(), но *не* obj:offsetGet() поскольку нечего возвращать\n";
var_dump(empty($obj["foobaz"]));
?>

Результатом выполнения данного примера будет что-то подобное:

Выполняется obj::offsetExists()
string(17) "obj::offsetExists"
bool(true)

Выполняется obj::offsetExists() и obj::offsetGet()
string(17) "obj::offsetExists"
string(14) "obj::offsetGet"
bool(false)

Выполняется obj::offsetExists(), но *не* obj:offsetGet() поскольку нечего возвращать
string(17) "obj::offsetExists"
bool(true)

Коментарии

Please note something:

The docs explain clearly that this method is called when "isset()" or "empty()" are called on the object's key.

This means that there is a huge difference in your custom implementation when you have an internal array on which you choose to call either "isset()" or "array_key_exists()".

Even though the method says "offsetExists", it is *not* supposed to be used only when the offset exists, because this is not at all the behavior of neither "isset" nor "empty" internally.

This means you can have issues like this (more explanations below):

<?php

class Value {
    public function 
__construct(
        public 
string $value,
    ) {
    }
}

class 
MyArray implements ArrayAccess {
    private array 
$internal = [];

    public function 
offsetExists(mixed $offset): bool
   
{
        return 
array_key_exists($offset$this->internal);
    }

   
// ... rest of the implementation
   
public function offsetGet(mixed $offset): mixed
   
{
        return 
$this->offsetExists($offset) ? $this->internal[$offset] : null;
    }

    public function 
offsetSet(mixed $offsetmixed $value): void
   
{
        if (
is_null($offset)) {
           
$this->internal[] = $value;
        } else {
           
$this->internal[$offset] = $value;
        }
    }

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

$object = new MyArray();
$object['key'] = null;

// This is where the error occurs:
// PHP Fatal error:  Uncaught TypeError: Value::__construct(): Argument #1 ($value) must be of type string, null given
$otherValue = isset($object['key']) ? new Value($object['key']) : null;
?>

The thing here is that we have some code that cannot use the "??" operator because we need the output of the "isset" call to return true, and only then we want to use.

With a real array, this should be fairly common because we know how "isset" works.

However, since the "offsetExists" method has a lot of different implementations in PHP libaries, you should *not* trust the output in "isset" with objects implementing ArrayAccess.

A workaround is to create an intermediate variable and run "isset()" on it:

<?php

// Before
$otherValue = isset($arrayObject['key']) ? new Value($arrayObject['key']) : null;

// After
$rawValue $arrayObject['key'] ?? null;
$otherValue = isset($rawValue) ? new Value($rawValue) : null;

?>
2025-04-07 15:28:32
http://php5.kiev.ua/manual/ru/arrayaccess.offsetexists.html

    Поддержать сайт на родительском проекте КГБ