如何在PHP中定义一个空对象


383

用一个新的数组,我这样做:

$aVal = array();

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

对象有类似的语法吗

(object)$oVal = "";

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

13
$var = (object) (boolean) (string) (int) (array) new StdClass; 要知道,只是为了安全。
Xeoncross

1
Google已将此问题标题索引为:Arrays - How to define an empty object in PHP。与阵列无关
Kolob Canyon

Answers:


848
$x = new stdClass();

手册中注释总结起来最好:

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

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


5
$ o =(对象)NULL; -如果将对象转换为对象,则不会对其进行修改。如果将任何其他类型的值转换为对象,则将创建stdClass内置类的新实例。如果值为NULL,则新实例将为空。数组转换为具有由键命名的属性和相应值的对象。对于任何其他值,名为scalar的成员变量将包含该值。
DDS

11
我只是说stdClass“标准课”
sjagr

1
如果您忘记使用我的答案:)
RafaSashi 2015年

26
如果遇到“未找到”:new \stdClass(); PHP命名空间文档
2540625 '17

3
@IvanCastellanos您能解释一下如何stdClass()从单词中记住AIDS吗?
亚当

117

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

$oVal = new stdClass();

但是,对于PHP> = 5.4,我个人更喜欢使用:

$oVal = (object)[];

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

与PHP <5.4相同的是:

$oVal = (object) array();

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

请参阅PHP手册(此处):

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

和(这里):

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


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

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

关于您的示例,如果您写:

$oVal = new stdClass();
$oVal->key1->var1 = "something"; // PHP creates  a Warning here
$oVal->key1->var2 = "something else";

PHP创建以下警告,隐式创建属性key1(对象本身)

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

如果您的配置可能会出现问题(请参见错误报告级别)向浏览器显示此警告,则。这是另一个主题,但是一种快速而肮脏的方法可能是使用错误控制运算符(@)来忽略警告:

$oVal = new stdClass();
@$oVal->key1->var1 = "something"; // the warning is ignored thanks to @
$oVal->key1->var2 = "something else";

3
您无需解决问题,而是创建一个新问题。需要解决的问题是人们应该知道该怎么stdClass做。
Pacerier,2015年

2
我写了什么stdClass。我stdClass在回答问题的代码上使用过。对不起,但是我没有提出一个新的问题,这是我的个人观点(如我所写)。
cgaldiolo

6
“个人喜好”!=“问题”
cgaldiolo15年

4
@Pacerier,我不理解你的固执。问题是“如何在PHP中定义一个空对象”。我的答案是正确的,我写了“ new stdClass()”。我提供给用户“ ed209”的代码是正确的,并且我使用了“ new stdClass()”。此外,我还添加了个人意见,并使用粗体的“个人”来表明这不是“标准”方式。以我的拙见,一个值得这么多评论的问题至少应该是一个错误的答案。相反,如果您认为个人意见是一个问题,那么可能是建设性共享想法的问题。
cgaldiolo

9
我真的很喜欢速记(object) []
Rahil Wazir

35

我想指出的是,在PHP中,没有像空对象这样的东西:

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

但是$ obj当然是空的。

另一方面,空数组在两种情况下均表示为空

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

来自changelog函数的报价为

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


我在变更日志中找不到该报价为空。
powpow19年

@ powpow12 它曾经在那里。在5.0.0中进行了更改。
Stanley Umeanozie,


14

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

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

所以我总是尝试像javascript一样在PHP中编写这种对象:

//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

另外,使用此合成器,您会发现一些有趣的惊喜,但在大多数情况下都可以正常工作。


1
这应该是公认的答案
Mike Aron

11

如果您忘记了Zombat的答案, stdClass

   function object(){

        return new stdClass();

    }

现在您可以执行以下操作:

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

我喜欢这项技术,尽管大多数IDE不会将“对象”这一术语强调为一个函数,这可能会使其他程序员感到困惑。但是,它对我有用!
布里克斯斯特

7

您可以使用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值转换为一个对象,该对象生成stdClass内置类的新的空实例:

$obj_c = (object) null;
$obj_c->name = "John";
print($obj_c);

// outputs:
// stdClass Object ( [name] => John ) 

5

要以类似的方式访问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};

4

正如其他人指出的那样,您可以使用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。一个优点是,与将stdClass用作类名,函数名或两者都使用相比,o比stdClass更容易记住并且更短。即使您的o类内部没有任何代码,也要比笨拙的大写stdClass(可能会引用“性传播疾病类”的想法)记忆起来容易。如果自定义o类,则可能会发现o()函数的用法而不是构造函数的语法。这是一个正常的函数,它返回一个值,该值比构造方法的限制要少。例如,函数名称可以作为字符串传递给接受可调用参数的函数。一个函数还支持链接。因此,您可以执行以下操作:

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



1
这是一个错字,应该是无括号。
Pacerier,2015年


4

如果要创建具有动态属性的对象(如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

4

您也可以尝试这种方式。

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

输出:

object(stdClass)#1 (0) { }

4

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

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

或将数组转换为对象

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

3

如果您不想这样做:

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

您可以使用以下之一:

PHP> = 5.4

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

PHP <5.4

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

3

这是迭代的示例:

<?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; ?>

0

您有一个糟糕但有用的技术:

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

0

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”的类。该名称已被系统使用。您可以定义一个名为“对象”的类。

您可以定义一个扩展stdClass的类,但不会获得任何好处,因为stdClass不执行任何操作。

(在PHP 5.2.8上测试)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.