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

时间:2009-09-16 17:24:29

标签: php object

使用新数组我这样做:

$aVal = array();

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

对象是否有类似的语法

(object)$oVal = "";

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

17 个答案:

答案 0 :(得分:759)

$x = new stdClass();

comment in the manual总结得最好:

  

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

     

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

答案 1 :(得分:85)

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

$oVal = new stdClass();

但是,如果PHP> = 5.4,我个人更愿意使用:

$oVal = (object)[];

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

与PHP相同< 5.4是:

$oVal = (object) array();

(object)[]相当于new stdClass()

请参阅PHP手册(here):

  

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

和(here):

  

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


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

  

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

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

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

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

  

警告:从空值

创建默认对象

如果您的配置(请参阅error reporting level)向浏览器显示此警告,则可能会出现问题。这是另一个完整的主题,但快速而肮脏的方法可能是使用error control operator (@)忽略警告:

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

答案 2 :(得分:33)

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

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

但当然$ obj将是空的。

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

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

来自changelog函数empty

的引用
  

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

答案 3 :(得分:17)

php.net说这是最好的:

$new_empty_object = new stdClass();

答案 4 :(得分:12)

我喜欢在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

另外,使用这个synthax你可以找到一些funny surprises,但在大多数情况下都能正常工作。

答案 5 :(得分:10)

如果你忘记stdClass

,除了zombat的回答
   function object(){

        return new stdClass();

    }

现在你可以做到:

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

答案 6 :(得分:6)

您可以使用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 ) 

答案 7 :(得分: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};

答案 8 :(得分: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

答案 9 :(得分:4)

您也可以尝试这种方式。

<servlet>
<servlet-name>SaveMxAdapterServlet</servlet-name>
<servlet-class>
com.danlaw.polarion.mxadapter.servlet.SaveMxAdapterServlet</servlet-class>

</servlet>
<servlet-mapping>
<servlet-name>SaveMxAdapterServlet</servlet-name>
<url-pattern>/SaveMxAdapter</url-pattern>
</servlet-mapping>

输出:

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

答案 10 :(得分:3)

正如其他人所指出的那样,你可以使用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) - &gt; some_operation_or_conversion_on_this_value();

这是一个很好的开端,用于构建其他语言层的基础“语言”,顶层是用完整的内部DSL编写的。这类似于lisp的开发风格,PHP支持它比大多数人意识到的更好。我意识到这有点像问题,但问题涉及我认为充分利用PHP的基础。

答案 11 :(得分:2)

如果您不想这样做:

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

您可以使用以下其中一项:

PHP&gt; = 5.4

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

PHP&lt; 5.4

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

答案 12 :(得分:2)

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

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

或者将数组转换为对象

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

答案 13 :(得分:1)

这是迭代的一个例子:

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

答案 14 :(得分:0)

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

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

答案 15 :(得分: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上测试)

答案 16 :(得分:-1)

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

$blankObject= json_decode('{}');