如何在 PHP 中定义一个空对象
Posted
技术标签:
【中文标题】如何在 PHP 中定义一个空对象【英文标题】:How to define an empty object in 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 这条评论到底给这个问题增加了什么?
【参考方案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
值转换为一个对象,该对象会生成 stdClass 内置类的新空实例:
$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 强大功能的基础。
【讨论】:
@Pacerier 你的意思是没有括号吗? ;) cis.upenn.edu/~matuszek/General/JavaSyntax/parentheses.html 打错字了,应该是无括号。 @Pacerier 好点 english.stackexchange.com/questions/130219/…【参考方案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()
的吗?以上是关于如何在 PHP 中定义一个空对象的主要内容,如果未能解决你的问题,请参考以下文章