【问题标题】:Why can this kind of statement work in PHP?为什么这种语句可以在 PHP 中工作?
【发布时间】:2011-01-19 09:13:09
【问题描述】:
$user->Phonenumbers[]->phonenumber = '123 123';
$user->Phonenumbers[]->phonenumber = '456 123';
$user->Phonenumbers[]->phonenumber = '123 777';

我从未见过这种语法

编辑

这似乎更像是一个功能,你们知道我该如何实现这样的功能吗?

【问题讨论】:

  • 有什么更具体的吗?语法的哪一部分你没见过?
  • 我猜是 Phonenumbers[]->phonenumber 部分
  • 这实际上不会抛出错误吗? :o 能否提供更多代码,尤其是课堂上Phonenumbers 的定义?

标签: php syntax language-features


【解决方案1】:

似乎像下面这样创建了一个具有 phonenumber 属性的 stdClass 对象并将其推送到$user->Phonenumbers 数组中:

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

我也从未见过这种语法。

【讨论】:

  • 如果 Phonenumbers 是一个数组,你如何使用-> 符号呢?与 $foo = array(); $foo->test = 12345; 比较会产生警告。
  • 哦,可能不是语法,希望是一个特性,你能弄清楚如何实现这种特性吗?
  • @Tatu Ulmanen:[] 用于阵列。但是我不知道[]->为什么要创建一个新对象。
  • @ORM:你在哪里找到的?
  • 我已经发布了一个工作示例。但我以前也从未见过。
【解决方案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!"
}

编辑:好的,我在php手册中找到了一些相关的内容:

如果将对象转换为对象,则不会对其进行修改。如果将任何其他类型的值转换为对象,则会创建 stdClass 内置类的新实例。如果值为 NULL,则新实例将为空。 (source)

因此使用-&gt; 语法将事物 转换为对象。在上面的示例中,$objnull,因此创建了一个新的空实例,并设置了 foobar 成员。

查看数组示例时,arr[] 首先创建一个新的(空)数组元素,然后由于-&gt; 语法将其转换为空对象并设置成员变量。

【讨论】:

  • 这太棒了!你能解释一下为什么吗?
  • 鉴于它甚至适用于空对象(示例的第二部分),因此使用[] 创建数组会导致此结果。但我不知道为什么你甚至可以访问一个不存在的对象并用它即时创建它。
  • 将引发 E_STRICT 通知:严格标准:从空值创建默认对象
  • 将 NULL 转换为数组会导致空数组。 请参阅 de.php.net/manual/en/language.types.array.php - 所以基本上,PHP 通过运算符上下文转换 NULL。
【解决方案3】:

当对未定义的变量使用 [] 和 -> 运算符时,php“隐式”创建数组和对象。

 $does_not_exist->foo = 1;

这里 php 创建一个 stdclass 对象并抛出一个“严格”警告“从空值创建默认对象”。与数组类似的事情

 $does_not_exist[] = 1;

奇怪地在没有警告的情况下工作,有些人consider 是一个错误。

【讨论】:

    【解决方案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)
      }
    }
    

    就像我在 cmets 中提到的那样,这样做违反了E_STRICT 标准,并且会引起注意。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-23
      • 1970-01-01
      相关资源
      最近更新 更多