Как определить пустой объект в PHP

С новым массивом я делаю это:

$aVal = array();

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

Есть ли подобный синтаксис для объекта

(object)$oVal = "";

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

18 ответов

Решение
$x = new stdClass();

Комментарий в руководстве суммирует это лучше всего:

stdClass - это объект PHP по умолчанию. У stdClass нет свойств, методов или родительского элемента. Он не поддерживает магические методы и не реализует интерфейсы.

Когда вы приводите скаляр или массив как Object, вы получаете экземпляр stdClass. Вы можете использовать stdClass всякий раз, когда вам нужен экземпляр общего объекта.

Стандартный способ создания "пустого" объекта:

$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";

Я хочу отметить, что в PHP нет такой вещи, как пустой объект в смысле:

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

но, конечно, $obj будет пустым.

С другой стороны, пустой массив означает пустой в обоих случаях

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

Цитата из функции changelog пуста

Объекты без свойств больше не считаются пустыми.

Мне нравится, как легко создавать объекты анонимного типа в 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

Кроме того, используя этот синтакс, вы можете найти несколько забавных сюрпризов, но он отлично работает в большинстве случаев.

php.net сказал, что лучше:

$new_empty_object = new stdClass();

В дополнение к ответу зомбата, если вы продолжаете забывать stdClass

   function object(){

        return new stdClass();

    }

Теперь вы можете сделать:

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

Ты можешь использовать 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 ) 

Используйте универсальный объект и сопоставьте пары значений ключа с ним.

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

Или приведите массив в объект

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

Вы также можете попробовать этот способ.

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

Выход:

object(stdClass)#1 (0) { }

Чтобы получить доступ к данным в 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};

Если вы хотите создать объект (как в 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

Как уже отмечали другие, вы можете использовать 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.

Вот пример с итерацией:

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

Если вы не хотите делать это:

$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',
);

Мы можем просто создать пустой объект, используя этот метод:

$object = new ObjectClass();

Например:

class ObjectClass
{
    // Something goes here
}

$object = new ObjectClass();

Теперь у нас есть переменная $object это ObjectClass но пусто. Обратите внимание, если он содержит функцию __construct()тогда он может быть не пустым.

Я знаю, что это старый вопрос, но кажется, что некоторые люди забывают о конструкторах.

Вы также можете получить пустой объект, проанализировав JSON:

      $blankObject= json_decode('{}');

Std Class - это объект 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)

У вас есть эта плохая, но полезная техника:

$var = json_decode(json_encode([]), FALSE);
Другие вопросы по тегам