Почему это выражение может работать в PHP?

$user->Phonenumbers[]->phonenumber = '123 123';
$user->Phonenumbers[]->phonenumber = '456 123';
$user->Phonenumbers[]->phonenumber = '123 777';

Я никогда не видел такой синтаксис

ИЗМЕНИТЬ

Это, скорее всего, функция, вы, ребята, знаете, как я могу реализовать такую ​​функцию?

Ответ 1

Кажется, что что-то вроде следующего создает объект stdClass со свойством phonenumber и помещает его в массив $user->Phonenumbers:

$user->Phonenumbers[]->phonenumber = 12345;

Я никогда не видел этот синтаксис тоже.

Ответ 2

Gumbo прав, вот рабочий пример:

<?php
class Test
{
    public $arr = array();
    public $obj = null;
}
$a = new Test();
$a->arr[]->foo = 1234;
$a->arr[]->bar = 'test';
var_dump( $a->arr );

// even more weird on null objects
$a->obj->foobar = 'obj was null!';
var_dump( $a->obj );

возвращает:

array(2) {
  [0]=>
  object(stdClass)#2 (1) {
    ["foo"]=>
    int(1234)
  }
  [1]=>
  object(stdClass)#3 (1) {
    ["bar"]=>
    string(4) "test"
  }
}
object(stdClass)#4 (1) {
  ["foobar"]=>
  string(13) "obj was null!"
}

edit: Хорошо, я нашел что-то связанное в руководстве php об этом:

Если объект преобразуется в объект, он не изменяется. Если значение любого другого типа преобразуется в объект, создается новый экземпляр встроенного класса stdClass. Если значение было NULL, новый экземпляр будет пустым. (источник)

Таким образом, использование синтаксиса -> преобразует предмет в объект. В приведенном выше примере $obj имеет значение null, поэтому создается новый пустой экземпляр и устанавливается член foobar.

При просмотре примера массива arr[] сначала создает новый (пустой) элемент массива, который затем преобразуется в пустой объект из-за синтаксиса -> и переменной члена.

Ответ 3

php "неявно" создает массивы и объекты при использовании операторов [] и → в переменных undefined.

 $does_not_exist->foo = 1;

здесь php создает объект stdclass и выдает "строгий" предупреждение "Создание объекта по умолчанию из пустого значения". Аналогичная вещь с массивами

 $does_not_exist[] = 1;

странно работает без предупреждения, которое некоторые люди считают ошибкой.

Ответ 4

PHP будет выводить NULL в контекст, в котором он используется.

var_dump( (bool) NULL );
var_dump( (int) NULL );
var_dump( (float) NULL );
var_dump( (string) NULL );
var_dump( (array) NULL );
var_dump( (object) NULL );

даст

bool(false)
int(0)
float(0)
string(0) ""
array(0) {}
object(stdClass)#1 (0) {}

Следовательно, при выполнении:

$a = NULL;
$a[] = NULL;       // used in array context `[]`
$a[0]->foo = NULL; // object context `->`
$a[0]->foo++;      // number context `++`

результирующая структура будет

array(1) {
  [0]=>
  object(stdClass)#1 (1) {
    ["foo"]=>
    int(1)
  }
}

Как я уже упоминал в комментариях, это противоречит стандартам E_STRICT, хотя и будет поднимать уведомление.