【问题标题】:PHP arrays and {$property} syntax [closed]PHP 数组和 {$property} 语法 [关闭]
【发布时间】:2016-07-03 19:57:43
【问题描述】:

请有人向我解释一下这段代码:

<?php

class Model
{

    protected $dates = [];

    public function __get($property)
    {
        if (in_array($property, $this->dates)) {
            return new DateTime($this->{$property});
        }

        return $this->{$property};
    }

}

class User extends Model
{
    protected $dates = ['createdAt'];

    protected $createdAt = '2016-01-01 12:35:15';
}

class Comment extends Model
{
    protected $dates = ['createdAt'];

    protected $createdAt = '2016-01-01 12:35:15';
}

$comment = new Comment;

var_dump($comment->createdAt->format('H:i'));

我不明白他是如何在这里使用数组的。他是否仅使用 $property 访问数组的索引? $this->{$property} 是如何工作的?

好笑,不过这段代码我看不懂,虽然只是初学者的例子……

亲切的问候, 米兰

【问题讨论】:

  • 我投票决定将此问题作为离题结束,因为Stack Overflow 不接受要求解释代码的问题

标签: php arrays properties


【解决方案1】:

我不明白他在这里如何使用数组。

他/她正在使用dates 数组将日期属性值自动转换为正确的DateTime 对象。如果属性与$this-&gt;dates 数组中的元素之一匹配,则属性值将作为DateTime 值返回,否则返回正常属性值。

$this->{$property} 是如何工作的?

这是您访问对象上的动态属性的方式

// let's say $property is set to 'foo'
$this->{$property}

// is the same as
$ths->foo

那是垃圾代码。

属性的动态获取/设置意味着某些属性以特殊方式运行。随着更多 Model 属性的添加,它们也会泄漏到 PHP Class 属性中。这是灾难的秘诀。

这里有一个更好的代码示例

class Util {
  static public function datetime($str) {
    return new DateTime($str);
  }
}

class Model {
  protected $attributes = [];

  protected $map_attributes = [];

  public function __construct($attributes = []) {
    $this->attributes = $attributes;
  }

  public function __set($property, $value) {
    $attributes[$property] = $value;
  }

  public function __get($property) {
    if (!array_key_exists($property, $this->attributes))
      return null;
    elseif (array_key_exists($property, $this->map_attributes))
      return call_user_func($this->map_attributes[$property], $this->attributes[$property]);
    else
      return $this->attributes[$property];
  }
}

class User extends Model {
  protected $map_attributes = [
    'created_at' => ['Util', 'datetime']
  ];
}

$u = new User(['foo' => 'bar', 'created_at' => '2016-01-01 12:35:15']);

echo $u->foo, PHP_EOL;                       // bar
echo $u->created_at->format('H:i'), PHP_EOL; // 12:35

Run this code at REPL.it

现在所有获取/设置模型属性都很好地沙盒化在单个 $this-&gt;attributes 数组类属性中。这可以防止属性在ModelModel 的子类中乱扔垃圾。

此外,每个类都可以通过在$this-&gt;map_attributes 中设置适当的映射函数来任意将任何属性映射到另一个值。这意味着当子类需要返回不同的类型时,不需要更新Model::__get 以支持新的属性->值映射。

因此,丑陋而危险的$this-&gt;{$property} 也会消失。动态属性访问有一个用例,但我认为这(您发布的原始代码)不是其中之一。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-04
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多