Почему такого рода заявления могут работать в PHP? - PullRequest
13 голосов
/ 21 февраля 2010
$user->Phonenumbers[]->phonenumber = '123 123';
$user->Phonenumbers[]->phonenumber = '456 123';
$user->Phonenumbers[]->phonenumber = '123 777';

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

EDIT

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

Ответы [ 4 ]

7 голосов
/ 21 февраля 2010

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

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

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

6 голосов
/ 21 февраля 2010

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

<?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[] сначала создает новый (пустой) элемент массива, который затем преобразуется в пустой объект из-за синтаксиса -> и устанавливается переменная-член.

2 голосов
/ 21 февраля 2010

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

 $does_not_exist->foo = 1;

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

 $does_not_exist[] = 1;

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

1 голос
/ 21 февраля 2010

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 и вызовет уведомление.

...