PHP中的stdClass是什么?

1161

请定义stdClass是什么。

18个回答

1171

stdClass 是一个通用的“空”类,用于将其他类型转换为对象。尽管其他两个答案所说的那样,stdClass 不是 PHP 中对象的基类。这可以很容易地证明:

class Foo{}
$foo = new Foo();
echo ($foo instanceof stdClass)?'Y':'N';
// outputs 'N'

我不认为PHP中有基础对象的概念。


2
这是一个实用类!顺便说一下,这是真正的注释! - Gustav
23
实际上,代码片段后的第一句话已经回答了这个问题。 - MauganRa
1
另一个导致Java的Object类和PHP的stdClass之间差异的主要因素是动态属性。在Java的Object对象中,您不允许定义动态属性(或变量),但是在PHP的stdClass对象中可以这样做。 - Miro Markaravanes
3
在PHP中,动态属性可以分配给任何类,而不仅仅是stdClass。 - StanE
我多么希望有一个基类可以修改。这样我就可以添加一个stdClass->methods(),我的生活会更加幸福一些。 - Gerry
显示剩余2条评论

855

stdClass是PHP的通用空类,有点像Java中的Object或Python中的object编辑:但实际上不作为通用基类使用;感谢@Ciaran 指出这一点)。

它适用于匿名对象、动态属性等。

将StdClass视为关联数组的替代品是一种简单的思考方式。看下面这个例子,它展示了如何使用json_decode()获得一个StdClass实例或一个关联数组。 除此之外,SoapClient::__soapCall也会返回一个StdClass实例,但该方法在此示例中未被展示。

<?php
//Example with StdClass
$json = '{ "foo": "bar", "number": 42 }';
$stdInstance = json_decode($json);
echo $stdInstance->foo . PHP_EOL; //"bar"
echo $stdInstance->number . PHP_EOL; //42
//Example with associative array
$array = json_decode($json, true);
echo $array['foo'] . PHP_EOL; //"bar"
echo $array['number'] . PHP_EOL; //42

查看PHP中StdClass的动态属性获取更多示例。


7
也许他使用了mysql_fetch_object。如果我没记错的话,这会创建一个stdlcass的实例。 - Galen
74
这句话的意思是:“它并不完全像Java中的Object类那样作为一个基础类,详见我下面的回答。” - Ciaran McNulty
1
我希望你知道,在Python中,对象并不是所有对象的派生类... 至少在你被迫从Python 3.0中派生对象之前不是。 - monokrome
14
我认为人们应该说stdClass类似于JavaScript的{}构造。 - Earth Engine
1
先生,您的答案部分不正确,因为文章是错误的。扩展此类唯一(这也是错误的)的好处是可以对其进行类型提示,即 function(StdClass $a, array $params),而不是检查 $a 是否为对象和 instanceof - Dejan Marjanović
显示剩余2条评论

114

stdClass是PHP另一个很棒的功能。您可以创建一个匿名PHP类。让我们看一个例子。

$page=new stdClass();
$page->name='Home';
$page->status=1;

现在假设你有另一个类,它将使用页面对象进行初始化并根据其执行。

<?php
class PageShow {

    public $currentpage;

    public function __construct($pageobj)
    {
        $this->currentpage = $pageobj;
    }

    public function show()
    {
        echo $this->currentpage->name;
        $state = ($this->currentpage->status == 1) ? 'Active' : 'Inactive';
        echo 'This is ' . $state . ' page';
    }
}

现在您需要使用页面对象创建一个新的PageShow对象。

您不需要编写新的类模板,只需使用stdClass即可动态创建类。

    $pageview=new PageShow($page);
    $pageview->show();

4
一个空类,具有可与行一起使用的有效函数,并且它是更好的编码规范。 - borrel
1
实际上,使用 STDclass 与使用数组相同。事实上,STDclass 是在类型转换(例如从数组到对象)时生成的。 - varuog
1
请在您的代码中更正一个打字错误: ($this->currentpage->name==1) 应该是 ($this->currentpage->status==1) - Enriqe
9
你可以创建一个匿名的 PHP 类,但它并不是真正的匿名类。你可以使用 instanceof、get_class等语句。 - John Smith
2
现在PHP实际上有匿名类,它们与stdClass非常不同,因此这个答案特别令人困惑。 - IMSoP

64

值得注意的是,stdClass对象也可以通过使用json_decode()创建。


7
没问题。我经常使用json_encode和json_decode将数组转换为对象,反之亦然,根据需要进行转换。 - pinkal vansia
6
$x = json_decode(json_encode($object), True)会将对象解码为一个数组,但它不是二进制安全的。如果它不是纯文本,它可能会在JSON中出现错误。 - simontemplar
@simontemplar 在 PHP 中,你不应该写 True。布尔值应该是小写的 truefalse - BadHorsie
@BadHorsie 说谁? 实际上,手册中使用所有大写字母和首字母大写来演示,而不是全部小写。这不是JavaScript。 - simontemplar
2
@simontemplar 手册没有规定,但是PSR-2有规定,所以如果你遵循任何标准,它应该是小写的。当然,如果你想以这种方式编写它是“有效”的,但你应该遵循标准。布尔值的手册文档可能非常古老,可能是在标准形成之前编写的。说实话,PHP最初是以完全混乱的方式编写的,没有任何标准(请参见使用的各种变量/函数/对象命名约定的广泛范围)。我真的从未见过任何开发人员使用您的格式编写的PHP代码。 - BadHorsie
2
我遵循PSR-2标准,除了True/False/Null和将类的左括号放在自己的行上。除此之外,我并不关心其他方面。但是,如果编辑别人的代码,我会遵循他们使用的任何标准(如果有的话,通常没有),如果失败了,我会按照“正确”的方式遵循PSR-2标准。有很多可怕的代码存在,存在着许多其他问题,而三个关键字的大小写是我最不用担心的。 - simontemplar

29
同样地,
$myNewObj->setNewVar = 'newVal'; 

返回一个stdClass对象 - 自动转换

今天我通过拼错发现了这个:

$GLOBASLS['myObj']->myPropertyObj->myProperty = 'myVal';

很酷!


10
但这会引发一个 E_NOTICE 错误。 - Petah
3
只有在 PHP 5.3 及以上版本才支持这个功能,对吧?但是确实是不好的做法。 - ChristoKiwi

28
使用 stdClass,您可以创建一个具有自己属性的新对象。 考虑以下示例,它将用户的详细信息表示为一个关联数组:
$array_user = array();
$array_user["name"] = "smith john";
$array_user["username"] = "smith";
$array_user["id"] = "1002";
$array_user["email"] = "smith@nomail.com";

如果你想表示对象的属性的相同细节,你可以使用下面的 stdClass
$obj_user = new stdClass;
$obj_user->name = "smith john";
$obj_user->username = "smith";
$obj_user->id = "1002";
$obj_user->email = "smith@nomail.com";

如果你是一个Joomla开发者,请参考[Joomla文档中的这个例子][1]。https://docs.joomla.org/Inserting,_Updating_and_Removing_data_using_JDatabase

24
我们之所以有 stdClass ,是因为在PHP中没有办法区分普通数组和关联数组(就像在JavaScript中你有{}表示对象,[]表示数组来区分它们)。
这就为空对象创建了一个问题。例如:

PHP:

$a = [1, 2, 3]; // this is an array
$b = ['one' => 1, 'two' => 2]; // this is an associate array (aka hash)
$c = ['a' => $a, 'b' => $b]; // this is also an associate array (aka hash)

假设您想要对变量 $c 进行 JSON 编码

echo json_encode($c);
// outputs => {'a': [1,2,3], 'b': {one: 1, two: 2}}

现在假设您删除了$b中的所有键,使其为空。由于$b现在为空(您记得已经删除了所有键吗?),它看起来像[],如果您仔细观察它,它可能是一个数组或对象。

因此,如果您再次进行json_encode,输出将不同。

echo json_encode($c);
// outputs => {'a': [1,2,3], 'b': []}

这是一个问题,因为我们知道b应该是一个关联数组,但PHP(或任何类似json_encode的函数)并不知道。

所以stdClass来拯救。再次以相同的例子为例。

$a = [1, 2, 3]; // this is an array
$b = (object) ['one' => 1, 'two' => 2]; // this makes it an stdClass
$c = ['a' => $a, 'b' => $b]; // this is also an associate array (aka hash)

现在即使你从$b中删除所有的键并将其置为空,由于它是stdClass,这并不重要,当你json_encode时,你会得到这个:

echo json_encode($c);
// outputs => {'a': [1,2,3], 'b': {}}

这也是为什么json_encodejson_decode默认返回stdClass的原因。

 $c = json_decode('{"a": [1,2,3], "b": {}}', true); //true to deocde as array
 // $c is now ['a' => [1,2,3], 'b' => []] in PHP
 // if you json_encode($c) again your data is now corrupted

感谢您提供的详细解决方案,我推荐您的解决方案用于深度学习。 - imnhasan
根据我的经验,stdClass 仅仅是因为 json_encode()json_decode() 的使用。你可以始终将 json_decode() 的结果收集为递归数组,而不需要处理 stdClass,对于 json_encode(),你可以像这个答案中展示的那样使用类型转换为 (object),这在技术上创建了 stdClass,但你不需要在实际源代码中编码它,也不需要关心实际的内部实现细节。简而言之,在 PHP 中你永远不需要自己使用 stdClass - Mikko Rantalainen

23

stdClass不是匿名类或匿名对象

这里的答案包括表达式,认为stdClass是一个匿名类甚至是匿名对象。事实并非如此。

stdClass只是一个常规的预定义类。您可以使用instanceof运算符或get_class函数来验证此内容。在这里没有任何特殊之处。PHP在将其他值转换为对象时使用此类。

在许多情况下,程序员使用stdClass的地方,数组是更好的选择,因为它具有有用的函数,并且这种用法代表数据结构而不是真正的对象。


根据我的经验,stdClass 大多是因为不理解 PHP 中 json_encode() 的实际工作方式而意外使用的。您可以仅使用(可能是递归的)数组构建所需的所有数据,并且 json_encode() 将发出数组或对象,具体取决于您在每个数组中使用的是数字键还是字符串键。如果您确实需要一个类,则最好实际定义一个真正的类。stdClass 在功能上与 class stdClass {} 相同。 - Mikko Rantalainen

12

值得注意的是,使用强制类型转换时,您不需要像@Bandula所提供的答案中那样创建对象。 相反,您可以将数组简单地强制转换为对象,这将返回stdClass。例如:

$array = array(
    'Property1'=>'hello',
    'Property2'=>'world',
    'Property3'=>'again',
);

$obj = (object) $array;
echo $obj->Property3;

输出:again


8

使用stdClass对象

stdClass允许您创建匿名类,并且通过对象转换,您还可以以面向对象的方式访问关联数组的键。就像访问常规对象属性一样。

示例

class Example {

  private $options;

  public function __construct(Array $setup)
  {
    // casting Array to stdClass object
    $this->options = (object) $setup;

    // access stdClass object in oop style - here transform data in OOP style using some custom method or something...
    echo $this->options->{'name'}; // ->{'key'}
    echo $this->options->surname;  // ->key
  }

}

$ob1 = new Example(["name" => "John", "surname" => "Doe"]);

将会回显

约翰·多


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接