【问题标题】:PHP quick syntax for creating an stdClass with pre-populated data [duplicate]用于创建具有预填充数据的 stdClass 的 PHP 快速语法 [重复]
【发布时间】:2013-07-30 15:53:13
【问题描述】:

我应该补充一点,虽然 KVP 数组可以正常工作,但在我看来,在执行 OOP 时我更喜欢对象,因为 $foo->bar->foo 似乎比 $foo->bar['foo'] 更干净。

PHP 有一种通过$foo = array('foo' => 'bar'); 甚至new 5.4 bracket syntax$foo = ['foo' => 'bar'] 使用预先填充的数据创建数组的好方法,但对象似乎不存在相同的语法 (stdClass)。

Array demo:

<?php
    class Foo {
        public $bar = array(
            'foo' => 'bar',
            'bar' => 'foo'
        );
    }

    $foo = new Foo;
    var_dump($foo->bar);
    /*
        array(2) {
          ["foo"]=>
          string(3) "bar"
          ["bar"]=>
          string(3) "foo"
        }
    */
?>

太好了——如果我们想对对象做同样的事情而不使用__construct


Try #1 - casting to object - nope; we can't cast in the declaration of a class variable:

<?php
    class Foo {
        public $bar = (object)array(
            'foo' => 'bar',
            'bar' => 'foo'
        );
    }

    /*
        Parse error: syntax error, unexpected T_OBJECT_CAST on line 4
    */
?>

Try #2 - using json_decode and json_encode - nope; we can't call functions in the declaration of a class variable:

<?php
    class Foo {
        public $bar = json_decode(json_encode(array(
            'foo' => 'bar',
            'bar' => 'foo'
        )));
    }

    /*
        Parse error: syntax error, unexpected '(', expecting ',' or ';' on line 3
    */
?>

Try #3 - using javascript style brackets - nope; even though []'s were added in PHP 5.4, object brackets still do not exist*:

*rfc for array brackets

<?php
    class Foo {
        public $bar = {
            'foo' => 'bar',
            'bar' => 'foo'
        };
    }

    /*
        Parse error: syntax error, unexpected '{' on line 3
    */
?>

似乎唯一可行的方法是使用 __construct 并将 KVP 数组转换为对象,但将变量声明为一个对象似乎完全倒退,在我们使用它之前,将其强制转换到别的东西。

__construct demo:

<?php
    class Foo {
        public $bar = array(
            'foo' => 'bar',
            'bar' => 'foo'
        );

        public function __construct() {
            $this->bar = (object)$this->bar;
        }
    }

    $foo = new Foo;
    var_dump($foo->bar);
    /*
        object(stdClass)#2 (2) {
          ["foo"]=>
          string(3) "bar"
          ["bar"]=>
          string(3) "foo"
        }
    */
?>

  • 是否有一些我找不到的速记语法?
  • 如果 不是;它会在未来的 PHP 版本中添加吗?
  • 如果不是/直到 然后;有没有比必须添加__construct 更好的方法? 单次?
  • 相反,我是否应该处理这样一个事实,即使用 在这种情况下,数组会更好,尽管在我看来, 看起来更乱?

为什么?

在为一家公司开发一个新的数据库类时,我不得不求助于当前代码来管理保存数据库凭据,以便稍后在代码中进行进一步检查。当然,不同的设计模式,例如$connectionHost$connectionDatabase 等也可以正常工作 - 但对我来说似乎很混乱。

Example:

<?php
    class DB {
        public $connection = array(
            'host'     => null,
            'database' => null,
            'user'     => null,
            'engine'   => null
        );
        public function __construct($host, $database, $user, $engine = 'mysql') {
            //Essentially I'd like the following line not to be needed:
            $this->connection = (object)$this->connection;

            $this->connection->host     = $host;
            $this->connection->database = $database;
            $this->connection->user     = $user;
            $this->connection->engine   = $engine;
        }
    }

    $db = new DB('127.0.0.1', 'server_db', 'my_user');
    var_dump($db->connection->host);
?>

http://codepad.org/vwy1y9NP

【问题讨论】:

  • 你为什么要混合objects和数据开始?像$foo-&gt;foo['bar'] 这样的行应该会引起一些警钟。需要记住的是,对象比数组慢得多。
  • 有趣的问题,但同意你不应该这样做的担忧。
  • 对象被认为是动态信息,你不能用动态信息声明属性。
  • @FritsvanCampen 我已将我的测试用例添加到 OP。
  • @Gordon 第二个链接(不是 marked as duplicate 链接)描述了将其简单地转换为对象的可能性,而在将其声明为时无法做到这一点一个类属性。第一个链接指的是通过解析的对象(与 OP 底部的实际用例不同 - 将这些指定为字符串不会产生影响,唯一的转换方法是将类构造函数调用为new Foo(array('foo' =&gt; 'bar'));,然后我还不如将它投射到那里的一个对象上。“没有”是我想确定的,所以谢谢。

标签: php oop object casting


【解决方案1】:

是的,坚持使用数组。没有声明对象的简写方式。但是,如果绝对需要,您可以直接分配嵌套属性,而无需自己实例化中间对象:

php > $x = new StdClass;
php > $x->foo->bar = 'baz';
php > var_dump($x);
object(stdClass)#2 (1) {
  ["foo"]=>
  object(stdClass)#1 (1) {
    ["bar"]=>
    string(3) "baz"
  }
}

【讨论】:

  • 在那种特定的情况下,你可以单行它:$x = (object)array('foo' =&gt; (object)array('bar' =&gt; 'baz')); - 它只是令人难以置信的混乱,你仍然不能在声明时使用new 关键字类常量,除非在 __construct 中使用。 免责声明:我不是投反对票的人。
  • 是的,这只有在您使用该对象的全部目的是作为数据存储结构时才有用。
猜你喜欢
  • 1970-01-01
  • 2012-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
  • 2011-01-25
相关资源
最近更新 更多