【问题标题】:How to define an empty object in PHP如何在 PHP 中定义一个空对象
【发布时间】:2010-11-28 21:28:05
【问题描述】:

使用新数组我这样做:

$aVal = array();

$aVal[key1][var1] = "something";
$aVal[key1][var2] = "something else";

对象是否有类似的语法

(object)$oVal = "";

$oVal->key1->var1 = "something";
$oVal->key1->var2 = "something else";

【问题讨论】:

  • $var = (object) (boolean) (string) (int) (array) new StdClass; 你知道,只是为了安全。
  • Google 已将此问题标题编入索引:Arrays - How to define an empty object in PHP。与数组无关
  • @KolobCanyon 这条评论到底给这个问题增加了什么?

标签: php object


【解决方案1】:

创建“空”对象的标准方法是:

$oVal = new stdClass();

但我个人更喜欢使用:

$oVal = (object)[];

它更短,我个人认为它更清晰,因为 stdClass 可能会误导新手程序员(即“嘿,我想要一个对象,而不是一个类!”...)。


(object)[] 等价于new stdClass()

请参阅 PHP 手册 (here):

stdClass:通过类型转换为对象创建。

here:

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

here(从 PHP 7.3.0 开始,var_export() 导出一个对象,该对象使用(object) 转换为数组):

现在将 stdClass 对象导出为强制转换为对象 ((object) array( ... )) 的数组,而不是使用不存在的方法 stdClass::__setState()。实际效果是现在 stdClass 是可导出的,生成的代码甚至可以在早期版本的 PHP 上运行。


但是请记住,empty($oVal) 返回 false,正如 @PaulP 所说:

没有属性的对象不再被认为是空的。

关于你的例子,如果你写:

$oVal = new stdClass();
$oVal->key1->var1 = "something"; // this creates a warning with PHP < 8
                                 // and a fatal error with PHP >=8
$oVal->key1->var2 = "something else";

PHP key1(对象本身)

警告:从空值创建默认对象

PHP >= 8 会产生以下错误:

致命错误:未捕获错误:未定义常量“key1”

在我看来,你最好的选择是:

$oVal = (object)[
  'key1' => (object)[
    'var1' => "something",
    'var2' => "something else",
  ],
];

【讨论】:

  • 不是解决问题,而是创建一个新问题。需要解决的问题是人们应该知道stdClass 做了什么。
  • 我写了stdClass 所做的事情。我在回答问题的代码上使用了stdClass。很抱歉,我并没有制造新问题,这是我个人的看法(正如我所写)。
  • “个人喜好”!=“问题”
  • @Pacerier,我不明白你的固执。问题是“如何在 PHP 中定义一个空对象”。我的回答是正确的,我写信使用“new stdClass()”。我提供给用户“ed209”的代码是正确的,我使用了“new stdClass()”。此外,我添加了个人意见,并使用了粗体的“个人”来明确这不是“标准”的方式。在我看来,一个值得这么多 cmets 的问题至少应该是一个错误的答案。相反,如果您认为个人意见是一个问题,那么 this 可能是一个建设性分享想法的问题。
  • 我真的很喜欢简写(object) []
【解决方案2】:

也可以通过解析JSON得到一个空对象:

$blankObject= json_decode('{}');

【讨论】:

  • 请不要重复现有的答案,尤其是如果您没有提供任何进一步的解释
【解决方案3】:

简答

$myObj = new stdClass();

// OR 

$myObj = (object) [
    "foo" => "Foo value",
    "bar" => "Bar value"
];

长答案

我喜欢在 JavaScript 中创建匿名类型的对象是多么容易:

//JavaScript
var myObj = {
    foo: "Foo value",
    bar: "Bar value"
};
console.log(myObj.foo); //Output: Foo value

所以我总是尝试在 PHP 中编写这种对象就像 javascript 所做的那样

//PHP >= 5.4
$myObj = (object) [
    "foo" => "Foo value",
    "bar" => "Bar value"
];

//PHP < 5.4
$myObj = (object) array(
    "foo" => "Foo value",
    "bar" => "Bar value"
);

echo $myObj->foo; //Output: Foo value

但由于这基本上是一个数组,因此您不能像 js 那样将匿名函数分配给属性:

//JavaScript
var myObj = {
    foo: "Foo value",
    bar: function(greeting) {
        return greeting + " bar";
    }
};
console.log(myObj.bar("Hello")); //Output: Hello bar

//PHP >= 5.4
$myObj = (object) [
    "foo" => "Foo value",
    "bar" => function($greeting) {
        return $greeting . " bar";
    }
];
var_dump($myObj->bar("Hello")); //Throw 'undefined function' error
var_dump($myObj->bar); //Output: "object(Closure)"

好吧,你可以做到,但 IMO 不实用/干净:

$barFunc = $myObj->bar;
echo $barFunc("Hello"); //Output: Hello bar

此外,使用此合成器您可以找到一些 funny surprises,但在大多数情况下都可以正常工作。

【讨论】:

    【解决方案4】:

    stdClass 是默认的 PHP 对象。 stdClass 没有属性、方法或父级。它不支持魔术方法,也不实现任何接口。

    当您将标量或数组转换为 Object 时,您将获得 stdClass 的一个实例。您可以在需要通用对象实例时使用 stdClass。

    <?php
    // ways of creating stdClass instances
    $x = new stdClass;
    $y = (object) null;        // same as above
    $z = (object) 'a';         // creates property 'scalar' = 'a'
    $a = (object) array('property1' => 1, 'property2' => 'b');
    ?>
    

    stdClass 不是基类! PHP 类不会自动从任何类继承。所有类都是独立的,除非它们明确扩展另一个类。 PHP 在这方面不同于许多面向对象的语言。

    <?php
    // CTest does not derive from stdClass
    class CTest {
        public $property1;
    }
    $t = new CTest;
    var_dump($t instanceof stdClass);            // false
    var_dump(is_subclass_of($t, 'stdClass'));    // false
    echo get_class($t) . "\n";                   // 'CTest'
    echo get_parent_class($t) . "\n";            // false (no parent)
    ?>
    

    您不能在代码中定义名为“stdClass”的类。该名称已被系统使用。您可以定义一个名为“Object”的类。

    你可以定义一个扩展stdClass的类,但是你不会得到任何好处,因为stdClass什么都不做。

    (在 PHP 5.2.8 上测试)

    【讨论】:

      【解决方案5】:

      使用通用对象并将键值对映射到它。

      $oVal = new stdClass();
      $oVal->key = $value
      

      或者将数组转换为对象

      $aVal = array( 'key'=>'value' );
      $oVal = (object) $aVal;
      

      【讨论】:

        【解决方案6】:

        这里是一个迭代的例子:

        <?php
        $colors = (object)[];
        $colors->red = "#F00";
        $colors->slateblue = "#6A5ACD";
        $colors->orange = "#FFA500";
        
        foreach ($colors as $key => $value) : ?>
            <p style="background-color:<?= $value ?>">
                <?= $key ?> -> <?= $value ?>
            </p>
        <?php endforeach; ?>
        

        【讨论】:

          【解决方案7】:

          如果您不想这样做:

          $myObj = new stdClass();
          $myObj->key_1 = 'Hello';
          $myObj->key_2 = 'Dolly';
          

          您可以使用以下方法之一:

          PHP >=5.4

          $myObj = (object) [
              'key_1' => 'Hello',
              'key_3' => 'Dolly',
          ];
          

          PHP

          $myObj = (object) array(
              'key_1' => 'Hello',
              'key_3' => 'Dolly',
          );
          

          【讨论】:

            【解决方案8】:

            你也可以试试这个方法。

            <?php
                 $obj = json_decode("{}"); 
                 var_dump($obj);
            ?>
            

            输出:

            object(stdClass)#1 (0) { }
            

            【讨论】:

              【解决方案9】:

              您可以使用new stdClass()(推荐):

              $obj_a = new stdClass();
              $obj_a->name = "John";
              print_r($obj_a);
              
              // outputs:
              // stdClass Object ( [name] => John ) 
              

              或者您可以将一个空数组转换为一个对象,该对象会生成一个新的 stdClass 内置类的空实例:

              $obj_b = (object) [];
              $obj_b->name = "John";
              print_r($obj_b);
              
              // outputs: 
              // stdClass Object ( [name] => John )  
              

              或者您可以将 null 值转换为一个对象,该对象会生成 std​​Class 内置类的新空实例:

              $obj_c = (object) null;
              $obj_c->name = "John";
              print($obj_c);
              
              // outputs:
              // stdClass Object ( [name] => John ) 
              

              【讨论】:

                【解决方案10】:

                如果您想创建具有动态属性的对象(如在 javascript 中),而不会收到未定义属性的警告。

                class stdClass {
                
                public function __construct(array $arguments = array()) {
                    if (!empty($arguments)) {
                        foreach ($arguments as $property => $argument) {
                            if(is_numeric($property)):
                                $this->{$argument} = null;
                            else:
                                $this->{$property} = $argument;
                            endif;
                        }
                    }
                }
                
                public function __call($method, $arguments) {
                    $arguments = array_merge(array("stdObject" => $this), $arguments); // Note: method argument 0 will always referred to the main class ($this).
                    if (isset($this->{$method}) && is_callable($this->{$method})) {
                        return call_user_func_array($this->{$method}, $arguments);
                    } else {
                        throw new Exception("Fatal error: Call to undefined method stdObject::{$method}()");
                    }
                }
                
                public function __get($name){
                    if(property_exists($this, $name)):
                        return $this->{$name};
                    else:
                        return $this->{$name} = null;
                    endif;
                }
                
                public function __set($name, $value) {
                    $this->{$name} = $value;
                }
                
                }
                
                $obj1 = new stdClass(['property1','property2'=>'value']); //assign default property
                echo $obj1->property1;//null
                echo $obj1->property2;//value
                
                $obj2 = new stdClass();//without properties set
                echo $obj2->property1;//null
                

                【讨论】:

                  【解决方案11】:

                  正如其他人指出的那样,您可以使用 stdClass。但是我认为没有 () 会更干净,就像这样:

                  $obj = new stdClass;
                  

                  但是,根据这个问题,您似乎真正想要的是能够动态地向对象添加属性。尽管可以,但您不需要为此使用 stdClass 。真的你可以使用任何类。只需创建任何类的对象实例并开始设置属性。我喜欢创建自己的类,它的名称只是 o,并带有一些我喜欢在这些情况下使用的基本扩展功能,并且很适合从其他类扩展。基本上它是我自己的基础对象类。我也喜欢有一个简单地命名为 o() 的函数。像这样:

                  class o {
                    // some custom shared magic, constructor, properties, or methods here
                  }
                  
                  function o() {
                    return new o;
                  }
                  

                  如果您不喜欢拥有自己的基础对象类型,您可以简单地让 o() 返回一个新的 stdClass。一个优点是 o 比 stdClass 更容易记住并且更短,无论您是否将其用作类名、函数名或两者兼而有之。即使您的 o 类中没有任何代码,它仍然比笨拙的大写和命名的 stdClass 更容易记住(这可能会引发“性传播疾病类”的想法)。如果您确实自定义了 o 类,您可能会发现使用 o() 函数而不是构造函数语法。它是一个返回值的普通函数,它的限制比构造函数少。例如,函数名称可以作为字符串传递给接受可调用参数的函数。一个函数也支持链接。因此,您可以执行以下操作: $result= o($internal_value)->some_operation_or_conversion_on_this_value();

                  对于基础“语言”来说,这是一个很好的开始,可以在其上构建其他语言层,顶层是用完整的内部 DSL 编写的。这类似于 lisp 开发风格,PHP 对它的支持比大多数人意识到的要好得多。我意识到这与这个问题有点切线,但这个问题涉及到我认为充分利用 PHP 强大功能的基础。

                  【讨论】:

                  【解决方案12】:

                  以与您类似的方式访问 stdClass 中的数据 对于关联数组,只需使用 {$var} 语法。

                  $myObj = new stdClass;
                  $myObj->Prop1 = "Something";
                  $myObj->Prop2 = "Something else";
                  
                  // then to acces it directly
                  
                  echo $myObj->{'Prop1'};
                  echo $myObj->{'Prop2'};
                  
                  // or what you may want
                  
                  echo $myObj->{$myStringVar};
                  

                  【讨论】:

                    【解决方案13】:

                    如果你一直忘记stdClass,除了zombat的回答

                       function object(){
                    
                            return new stdClass();
                    
                        }
                    

                    现在你可以这样做了:

                    $str='';
                    $array=array();
                    $object=object();
                    

                    【讨论】:

                    • 我喜欢这种技术,尽管大多数 IDE 不会将“对象”这个术语强调为一个可能会让其他程序员感到困惑的函数。但是,嘿,它对我有用!
                    【解决方案14】:

                    你有这个糟糕但有用的技术:

                    $var = json_decode(json_encode([]), FALSE);
                    

                    【讨论】:

                      【解决方案15】:

                      php.net 说最好:

                      $new_empty_object = new stdClass();
                      

                      【讨论】:

                      • 是的,这肯定是推荐的方式。
                      【解决方案16】:

                      我想指出,在 PHP 中没有空对象之类的东西:

                      $obj = new stdClass();
                      var_dump(empty($obj)); // bool(false)
                      

                      当然 $obj 是空的。

                      另一方面,空数组在这两种情况下都是空的

                      $arr = array();
                      var_dump(empty($arr));
                      

                      引用更新日志函数empty

                      没有属性的对象不再被认为是空的。

                      【讨论】:

                      • 我在更改日志中找不到空的引用。
                      • @powpow12 It used to be there。它在 5.0.0 中更改。
                      【解决方案17】:
                      $x = new stdClass();
                      

                      comment in the manual 总结得最好:

                      stdClass 是默认的 PHP 对象。 stdClass 没有属性、方法或 父母。它不支持魔法 方法,并且不实现接口。

                      当您将标量或数组转换为 对象,你得到一个实例 标准类。您可以使用 stdClass 每当您需要通用对象时 实例。

                      【讨论】:

                      • $o=(object)NULL; -- 如果一个对象被转换为一个对象,它不会被修改。如果将任何其他类型的值转换为对象,则会创建 stdClass 内置类的新实例。如果值为 NULL,则新实例将为空。数组转换为具有由键命名的属性和相应值的对象。对于任何其他值,名为 scalar 的成员变量将包含该值。
                      • 我只是在脑海中说stdClass是“标准类”
                      • @zombat,括号里的 stdClass() 是什么?
                      • 如果遇到“找不到”:new \stdClass();PHP Namespace Doc
                      • @IvanCastellanos 你能解释一下你是如何从AIDS这个词中记住stdClass()的吗?
                      猜你喜欢
                      • 1970-01-01
                      • 2021-09-22
                      • 1970-01-01
                      • 2019-01-14
                      • 2011-08-26
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多