Question

How to Create and Use Empty Objects in PHP

phpobject

Question

How can I create an empty object in PHP and assign nested values to it, similar to creating and filling a nested array?

$aVal = array();

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

Is there equivalent object syntax that lets me write values such as $oVal->key1->var1 and $oVal->key1->var2?

Short Answer

You will learn how to create an empty PHP object with stdClass, why nested objects must be initialized before use, and when an array or a named class is the better data structure.

Concept

PHP arrays and objects both store related data, but they use different access syntax:

  • Arrays use keys: $data['key']
  • Objects use properties: $data->key

For a flexible, empty object, PHP provides stdClass:

$object = new stdClass();

Unlike nested array keys, nested object properties are not created automatically. Before assigning to $object->key1->var1, the key1 property must already contain an object. Otherwise, PHP is trying to set a property on null.

$object = new stdClass();
$object->key1 = new stdClass();
$object->key1->var1 = 'something';

This matters because objects usually represent entities with properties, such as a user, API response, configuration object, or request payload. In larger applications, developers often replace flexible stdClass objects with named classes that document the expected properties and behavior.

Mental Model

Think of an object as a cabinet with labelled compartments.

  • $oVal is the main cabinet.
  • $oVal->key1 is a compartment inside it.
  • $oVal->key1->var1 is a labelled item stored in that compartment.

You cannot put an item into the key1 compartment until that compartment exists. Therefore, create $oVal->key1 as an object before adding var1 and var2 to it.

Arrays feel different because PHP can create missing nested array keys while you assign to them. Objects require you to explicitly create each nested object.

Take Quiz

Syntax and Examples

Create an empty generic object with new stdClass():

<?php

$oVal = new stdClass();
$oVal->key1 = new stdClass();

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

echo $oVal->key1->var1; // something

stdClass is PHP's built-in generic object class. It is useful when the property names are only known at runtime or when you need a lightweight data container.

You can also initialize the nested object inline:

<?php

$oVal = new stdClass();
$oVal->key1 = (object) [
    'var1' => 'something',
    'var2' => 'something else',
];

For a single empty object, an object cast also works:

$oVal = (object) [];

However, new stdClass() is usually clearer to readers.

If a property name is stored in a variable or contains characters that cannot be written in normal property syntax, use braces:

<?php

$fieldName = 'first-name';
$oVal = new stdClass();
$oVal->{$fieldName} = 'Ada';

echo $oVal->{'first-name'}; // Ada

Step by Step Execution

Consider this code:

<?php

$profile = new stdClass();
$profile->contact = new stdClass();
$profile->contact->email = 'ada@example.com';
$profile->contact->verified = true;

Step by step:

  1. $profile = new stdClass(); creates one empty object.
  2. $profile->contact = new stdClass(); creates a second empty object and stores it in the contact property.
  3. $profile->contact->email = ... finds the contact object, then adds its email property.
  4. $profile->contact->verified = true; adds another property to the same nested object.

The resulting structure is conceptually similar to:

profile
└── contact
    ├── email: ada@example.com
    └── verified: true

This does not work safely:

<?php

$profile = new stdClass();
$profile->contact->email = 'ada@example.com';

At that point, contact has not been initialized as an object.

Real World Use Cases

Generic objects are useful for small, flexible data structures.

  • JSON API payloads: Build a request body with nested fields before encoding it with json_encode().
  • Configuration data: Group settings such as $config->database->host and $config->database->port.
  • Decoded JSON: json_decode($json) returns stdClass objects by default for JSON objects.
  • View data: Pass simple structured data to a template, such as $page->seo->title.
  • Temporary transformations: Assemble a response object from values retrieved from several sources.

Example: building JSON for an API request:

<?php

$payload = new stdClass();
$payload->customer = new stdClass();
$payload->customer->name = 'Ada Lovelace';
$payload->customer->email = 'ada@example.com';

$json = json_encode($payload, JSON_THROW_ON_ERROR);

The JSON result has a nested customer object.

Take Quiz

Real Codebase Usage

In production code, choose the structure based on how predictable the data is.

Flexible external data

stdClass is common when handling data from JSON or APIs whose fields may vary.

$response = json_decode($body);

if (!isset($response->user)) {
    throw new RuntimeException('Response does not include a user.');
}

Guard clauses before nested access

Check that optional nested data exists before using it:

if (!isset($response->user->email)) {
    return null;
}

return $response->user->email;

isset() is useful here because it returns false instead of raising an error when part of the property path is missing or null.

Named classes for known application data

When your application always expects the same fields, use a class rather than attaching arbitrary properties:

<?php

final class Contact
{
    public function __construct(
        public string $email,
        public bool $verified,
    ) {
    }
}

$contact = new Contact('ada@example.com', true);

Named classes provide clearer intent, type declarations, IDE autocomplete, and a place for validation or methods.

Arrays for map-like data

For data indexed by variable keys, arrays are often simpler:

$headers = [];
$headers['X-Request-ID'] = 'abc123';

Common Mistakes

Assigning through an uninitialized nested property

Broken code:

<?php

$oVal = new stdClass();
$oVal->key1->var1 = 'something';

$oVal->key1 has no object assigned to it yet. Initialize it first:

$oVal->key1 = new stdClass();
$oVal->key1->var1 = 'something';

Casting an empty string and expecting nested objects

$oVal = (object) '';

Although casting can produce an object, it does not create $oVal->key1. You still must initialize nested levels. Prefer the clearer form:

$oVal = new stdClass();

Mixing array and object syntax

Broken code:

$oVal = new stdClass();
$oVal['key1'] = 'value';

A standard object is accessed with ->, not array brackets:

$oVal->key1 = 'value';

Assuming a missing property is an object

A missing property reads as null (and may produce a warning when read). Do not chain into it without checking or initializing it.

Using dynamic properties on your own classes without declaring them

Adding undeclared properties to stdClass is intended. However, in PHP 8.2 and later, creating dynamic properties on most user-defined classes is deprecated. Declare class properties instead:

final class User
{
    public string $name;
}

$user = new User();
$user->name = 'Ada';

Forgetting that object assignment shares the same instance

$a = new stdClass();
$a->name = 'Ada';
$b = $a;
$b->name = 'Grace';

echo $a->name; // Grace

$a and $b refer to the same object instance. Use clone $a when you specifically need a separate shallow copy.

Comparisons

NeedBest choiceAccess syntaxNotes
Flexible key-value dataArray$data['key']Missing nested keys can be created during assignment.
Flexible property-based datastdClass$data->keyInitialize each nested object before assigning through it.
Predictable application entityNamed class$user->nameBest for types, validation, methods, and maintainability.
Data received from JSONstdClass or array-> or []Choose with json_decode() options.

stdClass versus arrays when decoding JSON

$json = '{"user":{"name":"Ada"}}';

$asObject = json_decode($json);
echo $asObject->user->name;

$asArray = json_decode($json, true);
echo $asArray['user']['name'];

Both represent the same JSON data. Use one style consistently within a piece of code where possible.

stdClass versus a named class

Use stdClass for temporary or unknown-shaped data. Use a named class when the object has a known purpose and stable fields. For example, a User class can guarantee that every user has an email address and can provide methods such as isVerified().

Take Quiz

Cheat Sheet

// Empty generic object
$data = new stdClass();

// Equivalent empty-object cast
$data = (object) [];

// Add a property
$data->name = 'Ada';

// Create a nested object before using it
$data->address = new stdClass();
$data->address->city = 'London';

// Build a nested object in one expression
$data->address = (object) [
    'city' => 'London',
    'country' => 'UK',
];

// Dynamic property name
$key = 'display-name';
$data->{$key} = 'Ada Lovelace';

// Safely check nested data
if (isset($data->address->city)) {
    echo $data->address->city;
}

Rules to remember:

  • Use new stdClass() for a generic empty object.
  • Use -> for object properties and [] for array keys.
  • Create every nested object before assigning into it.
  • Use stdClass for flexible data; use a declared class for stable domain data.
  • Dynamic properties are appropriate on stdClass, but generally avoid them on your own classes in PHP 8.2+.

FAQ

How do I make an empty object in PHP?

Use new stdClass():

$object = new stdClass();

Can I use (object) [] to create an empty object?

Yes. (object) [] creates an empty stdClass object. new stdClass() is often more readable.

Why does $object->a->b = 'value' fail?

Because $object->a has not been initialized as an object. Create it first with $object->a = new stdClass();.

Does PHP automatically create nested object properties?

No. PHP can create nested array keys during assignment, but nested objects must be initialized explicitly.

Should I use an array or an object in PHP?

Use arrays for flexible, key-indexed collections. Use objects when properties describe an entity or when you need behavior, types, and clearer structure.

What object type does json_decode() return?

By default, JSON objects decode to stdClass instances. Pass true as the second argument to receive associative arrays instead.

Can I add any property to stdClass?

Yes. stdClass is designed as a generic object that can receive dynamic properties.

Are object assignments copied in PHP?

Assigning an object variable copies the reference-like handle to the same object. Changes through either variable affect the same instance unless you use clone.

Take Quiz

Mini Project

Description

Build a small API-style profile payload using nested stdClass objects. This demonstrates the key rule for nested objects: create each level before assigning properties within it.

Goal

Create a profile object with nested contact and address information, then convert it to JSON.

Requirements

Initialize a root object using stdClass. Create a nested contact object before setting its properties. Create a nested address object before setting its properties. Add a name, email, city, and country. Encode and print the final structure as JSON.

Take Quiz

Keep learning

Related questions

View more