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


384

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

$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. Не имеет ничего общего с массивами
Колоб Каньон

Ответы:


848
$x = new stdClass();

Комментарий в ручном подытоживает лучше всего:

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

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


5
$ о = (объект) NULL; - Если объект преобразован в объект, он не изменяется. Если значение любого другого типа преобразуется в объект, создается новый экземпляр встроенного класса stdClass. Если значение было NULL, новый экземпляр будет пустым. Массивы преобразуются в объект со свойствами, названными ключами, и соответствующими значениями. Для любого другого значения переменная-член с именем scalar будет содержать это значение.
DDS

11
Я просто говорю stdClassв своей голове как «стандартный класс»
sjagr

1
Если вы продолжаете забывать, используйте мой ответ :)
RafaSashi

26
Если вы встречаете «не найдено»: new \stdClass(); PHP Namespace Doc
2540625

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делает.
Пейсер

2
Я написал, что stdClassделает. Я использовал stdClassкод, который отвечает на вопрос. Извините, но я не создаю новую проблему, это было мое личное мнение (как я писал).
cgaldiolo

6
"личные предпочтения"! = "проблема"
cgaldiolo

4
@Pacerier, я не понимаю твоего упрямства. Вопрос был «Как определить пустой объект в PHP». Мой ответ правильный, и я написал, чтобы использовать «новый stdClass ()». Код, который я предоставил пользователю 'ed209', правильный, и я использовал "новый stdClass ()". Кроме того, я добавил личное мнение и использовал смелый «лично», чтобы понять, что это не «стандартный» путь. По моему скромному мнению, проблема, которая заслуживает такого большого количества комментариев, должна быть как минимум неправильным ответом. Вместо этого, если вы считаете личное мнение проблемой, возможно, это проблема для конструктивного обмена идеями.
cgaldiolo

9
Мне очень нравится стенография(object) []
Рахиль Вазир

35

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

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

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

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

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

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

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


Я не мог найти эту цитату в журнале изменений для пустых.
powpow12

@ powpow12 Раньше был там . Это было изменено в 5.0.0.
Стэнли Умеанози


14

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

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


1
Это должен быть принятый ответ
Майк Арон

11

В дополнение к ответу зомбата, если вы продолжаете забывать 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. Одним из преимуществ является то, что o легче запомнить, чем stdClass, и он короче, независимо от того, используете ли вы его в качестве имени класса, имени функции или того и другого. Даже если у вас нет кода внутри вашего класса o, его все же легче запомнить, чем неуклюжий заглавный и названный stdClass (который может вызвать идею «класса болезней, передающихся половым путем»). Если вы настроите класс o, вы можете найти использование функции o () вместо синтаксиса конструктора. Это нормальная функция, которая возвращает значение, которое менее ограничено, чем конструктор. Например, имя функции может быть передано в виде строки функции, которая принимает вызываемый параметр. Функция также поддерживает связывание. Таким образом, вы можете сделать что-то вроде:

Это отличное начало для базового «языка» для создания других языковых уровней, когда верхний уровень записывается в полных внутренних DSL. Это похоже на стиль разработки LISP, и PHP поддерживает его лучше, чем большинство людей понимают. Я понимаю, что это немного касательно вопроса, но вопрос касается того, что я считаю основой для полного использования возможностей PHP.


2
@Pacerier ты имеешь в виду отсутствие скобок? ;) cis.upenn.edu/~matuszek/General/JavaSyntax/parentheses.html
still_dreaming_1

1
Это опечатка, это должно быть отсутствие скобок.
Pacerier


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)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.