Oihana PHP

objects

Table of Contents

Functions

compress()  : object
Compress the given object by removing properties that match certain conditions.
ensureObjectPath()  : object
Ensures that a given property of an object is initialized as an object.
filter()  : object
Keeps the public properties of an object that satisfy a predicate.
freeze()  : array<int|string, mixed>
Builds a plain associative array snapshot of the given properties of an object.
hasAllProperties()  : bool
Check if all of the given properties exist in the object.
hasAnyProperty()  : bool
Check if at least one of the given properties exists in the object.
keys()  : array<int, string>
Returns the list of public property names of an object.
map()  : object
Transforms every public property value of an object through a callback.
omit()  : object
Removes the specified public properties from an object.
pick()  : object
Keeps only the specified public properties of an object.
set()  : object
Sets a value in an object using a key path.
setObjectValue()  : object
Sets a value in a flat object using a single property name.
toAssociativeArray()  : array<string|int, mixed>
Recursively converts an object (or array) into a full associative array.
values()  : array<int, mixed>
Returns the list of public property values of an object.

Functions

compress()

Compress the given object by removing properties that match certain conditions.

compress(object $object[, array{clone?: bool, conditions?: callable|array|string|null, depth?: null|int, excludes?: array|null, recursive?: bool, removeKeys?: array|null, throwable?: bool} $options = [] ][, int $currentDepth = 0 ]) : object

This function traverses the object and removes properties according to the provided options. It can operate recursively on nested objects and arrays.

Parameters
$object : object

The object to compress.

$options : array{clone?: bool, conditions?: callable|array|string|null, depth?: null|int, excludes?: array|null, recursive?: bool, removeKeys?: array|null, throwable?: bool} = []

Optional configuration.

$currentDepth : int = 0

Internal counter used to track recursion depth.

Tags
throws
InvalidArgumentException

If invalid callbacks are provided and 'throwable' is true.

example

Basic removal of null values

use function oihana\core\objects\compress;

$obj = (object)[
    'id'          => 1,
    'name'        => 'hello',
    'description' => null,
];

$result = compress($obj, [
    'conditions' => fn($v) => $v === null,
]);

// Result: { "id":1, "name":"hello" }
echo json_encode($result);

Excluding certain properties

$obj = (object)[
    'id'    => 1,
    'debug' => 'keep me',
    'temp'  => null,
];

$result = compress($obj, [
    'conditions' => fn($v) => $v === null,
    'excludes'   => ['debug'],
]);

// Result: { "id":1, "debug":"keep me" }
echo json_encode($result);

Removing properties by name

$obj = (object)[
    'id'    => 1,
    'token' => 'secret',
    'name'  => 'test',
];

$result = compress($obj, [
    'removeKeys' => ['token'],
]);

// Result: { "id":1, "name":"test" }
echo json_encode($result);

Recursive compression

$obj = (object)[
    'id'    => 1,
    'child' => (object)[
        'value' => null,
        'label' => 'ok',
    ],
];

$result = compress($obj, [
    'conditions' => fn($v) => $v === null,
    'recursive'  => true,
]);

// Result: { "id":1, "child":{ "label":"ok" } }
echo json_encode($result);
author

Marc Alcaraz

since
1.0.0
Return values
object

The compressed object, with properties removed according to the rules.

ensureObjectPath()

Ensures that a given property of an object is initialized as an object.

& ensureObjectPath(object &$current, string $segment) : object

If the property does not exist or is not an object, it will be replaced with a new stdClass instance. The function returns a reference to the nested object, allowing direct modification.

This is useful when building or navigating nested object structures dynamically.

Parameters
$current : object

The current object in which the property is ensured.

$segment : string

The property name to ensure as an object.

Tags
example
$data = new stdClass();
$ref =& ensureObjectPath($data, 'config');
$ref->enabled = true;
// $data now contains: (object)['config' => (object)['enabled' => true]]
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
object

A reference to the ensured nested object (stdClass).

filter()

Keeps the public properties of an object that satisfy a predicate.

filter(object $object, callable $fn) : object

Returns a new stdClass containing only the properties for which fn( $value , $key ) returns a truthy value. The source object is never modified.

Parameters
$object : object

The source object.

$fn : callable

The predicate callback: fn( $value , $key ): bool.

Tags
example
use function oihana\core\objects\filter;

$values = (object) [ 'a' => 1 , 'b' => 2 , 'c' => 3 ] ;

$result = filter( $values , fn( $v ) => $v % 2 === 1 ) ;
// (object) [ 'a' => 1 , 'c' => 3 ]
author

Marc Alcaraz (ekameleon)

since
1.0.9
Return values
object

A new stdClass with only the kept properties.

freeze()

Builds a plain associative array snapshot of the given properties of an object.

freeze(object $object, array<int|string, string> $fields[, int $flags = CleanFlag::NULLS ][, bool $deep = false ]) : array<int|string, mixed>

Typical use case: freezing a reference to another document. A caller names a record, the server re-reads it and copies the properties it chooses onto the current document, so the snapshot survives later changes to the source.

Property selection and renaming

Each entry of $fields is the name of a source property. When the entry carries a string key, that key becomes the name of the property in the snapshot — which lets a name property land as thingName on the carrying document:

[ '_key' , 'url' , 'thingName' => 'name' ]

Reading

Properties are read with $object->{ $field } ?? null, so magic __get() / __isset() accessors are honoured — unlike pick(), which relies on get_object_vars(). A property that is missing, uninitialized or inaccessible therefore reads as null, and is dropped as long as $flags discards nulls (which the default does).

Filtering

The collected values are handed to clean() with $flags, so the whole CleanFlag vocabulary applies. The default, CleanFlag::NULLS, only discards null0, 0.0, '', false and [] are kept. Note that CleanFlag::TRIM is a modifier of CleanFlag::EMPTY and does nothing on its own, and that CleanFlag::FALSY short-circuits NULLS / EMPTY / TRIM and never applies to arrays. CleanFlag::RETURN_NULL is rejected: this function always returns an array.

Depth

By default an object value is copied by handle, so the snapshot keeps sharing the instance with the source. Pass $deep = true to convert every object or array value into a plain associative array with toAssociativeArray(), which makes the snapshot genuinely inert.

The returned array follows the order of $fields, not the declaration order of the object. The source object is never modified.

Parameters
$object : object

The source object.

$fields : array<int|string, string>

The properties to copy. An integer key means the source name is reused as-is ; a string key renames the property in the snapshot.

$flags : int = CleanFlag::NULLS

A bitmask of CleanFlag values applied to the collected values. Defaults to CleanFlag::NULLS.

$deep : bool = false

If true, object and array values are converted into plain associative arrays. Defaults to false.

Tags
throws
InvalidArgumentException

If $flags contains CleanFlag::RETURN_NULL, or is not a valid combination of CleanFlag constants.

example

Basic snapshot

use function oihana\core\objects\freeze;

$thing = (object) [ '_key' => 'aeb1' , 'id' => null , 'name' => 'Alice' , 'score' => 0 ] ;

$frozen = freeze( $thing , [ 'name' , '_key' , 'id' , 'url' ] ) ;
// [ 'name' => 'Alice' , '_key' => 'aeb1' ]
// 'id' is null and 'url' does not exist : both are dropped.

Renaming properties

$frozen = freeze( $thing , [ '_key' , 'thingName' => 'name' ] ) ;
// [ '_key' => 'aeb1' , 'thingName' => 'Alice' ]

Discarding empty strings and empty arrays too

use oihana\core\arrays\CleanFlag;

$thing = (object) [ 'name' => 'Alice' , 'label' => '   ' , 'tags' => [] , 'score' => 0 ] ;

$frozen = freeze( $thing , [ 'name' , 'label' , 'tags' , 'score' ] , CleanFlag::MAIN ) ;
// [ 'name' => 'Alice' , 'score' => 0 ]

Inert snapshot of a nested object

$thing = (object) [ 'name' => 'Alice' , 'address' => (object) [ 'city' => 'Paris' ] ] ;

$frozen = freeze( $thing , [ 'name' , 'address' ] , deep : true ) ;
// [ 'name' => 'Alice' , 'address' => [ 'city' => 'Paris' ] ]
// Mutating $thing->address afterwards no longer alters $frozen.
author

Marc Alcaraz (ekameleon)

since
1.2.0
Return values
array<int|string, mixed>

The frozen snapshot, in the order of $fields. Keys are the property names, except for the numeric ones that PHP casts to integers, as in any array.

hasAllProperties()

Check if all of the given properties exist in the object.

hasAllProperties(object $object, array<int, string> $properties[, bool $notNull = false ]) : bool

If $notNull is set to true, each property must also be non-null.

Parameters
$object : object

The object to inspect

$properties : array<int, string>

List of property names to check

$notNull : bool = false

Whether to check for non-null values (default: false)

Tags
example

Usage

$doc = (object)
[
    'id'     => 123,
    'slogan' => 'Hello'
];

$props = ['id', 'slogan'];

hasAllProperties($doc, $props);        // true
hasAllProperties($doc, $props, true);  // true

$props2 = ['id', 'description'] ;
hasAllProperties($doc, $props2) ; // false (description missing)
author

Marc Alcaraz

since
1.0.0
Return values
bool

True if all properties exist (and are not null if $notNull = true)

hasAnyProperty()

Check if at least one of the given properties exists in the object.

hasAnyProperty(object $object, array<int, string> $properties[, bool $notNull = false ]) : bool

If $notNull is set to true, the property must also be non-null.

Parameters
$object : object

The object to inspect

$properties : array<int, string>

List of property names to check

$notNull : bool = false

Whether to check for non-null values (default: false)

Tags
example

Recursive compression

$doc = (object)
[
   'id'     => 123  ,
   'slogan' => null ,
];

$props = [ 'slogan' , 'description' ] ;

hasAnyProperty( $doc , $props ) ; // true  (because 'slogan' exists)
hasAnyProperty( $doc , $props , true ) ; // false (because 'slogan' is null)
author

Marc Alcaraz

since
1.0.0
Return values
bool

True if at least one property exists (and is not null if $notNull = true)

keys()

Returns the list of public property names of an object.

keys(object $object) : array<int, string>

Only the accessible (public and dynamic) properties are returned, in declaration order, mirroring the behaviour of get_object_vars() from outside the class.

Parameters
$object : object

The source object.

Tags
example
use function oihana\core\objects\keys;

$user = (object) [ 'id' => 42 , 'name' => 'Alice' ] ;

keys( $user ) ; // [ 'id' , 'name' ]
author

Marc Alcaraz (ekameleon)

since
1.0.9
Return values
array<int, string>

A list of the object's public property names.

map()

Transforms every public property value of an object through a callback.

map(object $object, callable $fn) : object

Returns a new stdClass with the same property names, each value replaced by the result of fn( $value , $key ). The source object is never modified.

Parameters
$object : object

The source object.

$fn : callable

The mapping callback: fn( $value , $key ): mixed.

Tags
example
use function oihana\core\objects\map;

$prices = (object) [ 'a' => 10 , 'b' => 20 ] ;

$result = map( $prices , fn( $v ) => $v * 2 ) ;
// (object) [ 'a' => 20 , 'b' => 40 ]
author

Marc Alcaraz (ekameleon)

since
1.0.9
Return values
object

A new stdClass with mapped values.

omit()

Removes the specified public properties from an object.

omit(object $object, array<int, string> $keys) : object

Returns a new stdClass containing every public property of the source object except the listed ones. The source object is never modified. This is the inverse of pick().

Parameters
$object : object

The source object.

$keys : array<int, string>

The list of property names to remove.

Tags
example
use function oihana\core\objects\omit;

$user = (object) [ 'id' => 42 , 'name' => 'Alice' , 'password' => 'secret' ] ;

$result = omit( $user , [ 'password' ] ) ;
// (object) [ 'id' => 42 , 'name' => 'Alice' ]
author

Marc Alcaraz (ekameleon)

since
1.0.9
Return values
object

A new stdClass without the omitted properties.

pick()

Keeps only the specified public properties of an object.

pick(object $object, array<int, string> $keys) : object

Returns a new stdClass containing only the listed properties that actually exist on the source object. The source object is never modified. Keys that are absent are silently ignored.

Parameters
$object : object

The source object.

$keys : array<int, string>

The list of property names to keep.

Tags
example
use function oihana\core\objects\pick;

$user = (object) [ 'id' => 42 , 'name' => 'Alice' , 'email' => 'alice@example.com' ] ;

$result = pick( $user , [ 'id' , 'name' ] ) ;
// (object) [ 'id' => 42 , 'name' => 'Alice' ]
author

Marc Alcaraz (ekameleon)

since
1.0.9
Return values
object

A new stdClass with only the picked properties.

set()

Sets a value in an object using a key path.

set(object $object, string|null $key, mixed $value[, non-empty-string $separator = '.' ][, bool $copy = false ][, array<string, class-string>|string|callable|null $classFactory = null ]) : object

Supports dot notation for nested properties. Intermediate objects are created if needed.

Parameters
$object : object

The object to modify (or copy).

$key : string|null

The key path to set (e.g. 'user.address.country'). If null, replaces entire object.

$value : mixed

The value to set.

$separator : non-empty-string = '.'

The separator used in the key path. Default is '.'.

$copy : bool = false

If true, returns a deep copy of the object with the modification.

$classFactory : array<string, class-string>|string|callable|null = null

A class name, factory callable, or array path => className to create intermediate objects (default: stdClass).

Tags
throws
InvalidArgumentException

If $classFactory is a string referencing a class that does not exist.

example
  1. Basic usage with nested keys and default stdClass
$obj = new \stdClass();
$obj = set($obj, 'user.profile.name', 'Alice');
echo $obj->user->profile->name; // Alice
  1. Replace the entire object when key is null
$original = (object)['foo' => 'bar'];
$new = set($original, null, ['x' => 123]);
echo $new->x; // 123
  1. Use a custom class as intermediate objects
class Node { public string $label = ''; }
$obj = set(new Node(), 'tree.branch.leaf', 'green', '.', false, Node::class);
echo $obj->tree->branch->leaf; // green
  1. Use a factory callable
$factory = fn() => new class { public string $value = ''; };
$obj = set(new \stdClass(), 'x.y.z', 99, '.', false, $factory);
echo $obj->x->y->z; // 99
  1. Use an array of path => class mappings
class Address { public string $city = ''; }
class User    { public string $name = ''; }
$obj = new \stdClass();
$obj = set($obj, 'user.address.city', 'Paris', '.', false, [
'user' => User::class,
'user.address' => Address::class,
]);
echo $obj->user->address->city; // Paris
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
object

The modified (or copied and modified) object.

setObjectValue()

Sets a value in a flat object using a single property name.

setObjectValue(object $document, string $key, mixed $value) : object

This helper function assigns the given value to the specified property of the provided object. It does not support nested paths or separators.

The object is returned with the updated property.

Parameters
$document : object

The object to modify.

$key : string

The property name to set.

$value : mixed

The value to assign to the property.

Tags
example
$obj = (object)['name' => 'Alice'];
$updated = setObjectValue($obj, 'age', 30);
// $updated = (object)['name' => 'Alice', 'age' => 30];
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
object

The modified object with the new or updated property.

toAssociativeArray()

Recursively converts an object (or array) into a full associative array.

toAssociativeArray(array<int|string, mixed>|object $document[, string|array<int, object|string>|object|null $encoder = null ][, bool $strict = false ]) : array<string|int, mixed>

This function handles nested objects, ensuring the entire array or object tree is converted.

Note that only public properties of the object will be included in the resulting array.

Parameters
$document : array<int|string, mixed>|object

An array or object to convert to a deep associative array .

$encoder : string|array<int, object|string>|object|null = null

Optional JSON encoder reference. This value is resolved into a callable using resolveCallable(). Supported forms:

  • Closure or invokable object
  • Callable array: [$object, 'method'] or ['Class', 'method']
  • Named function: 'my_json_encoder'
  • Static method string: 'MyClass::encode'
  • null to use native json_encode()

The resolved callable must have the signature: function(mixed $data): string

$strict : bool = false

If strict, not use json_encode but a standard loop.

Tags
example

Convert an object :

// Define some classes for the example.
class Address
{
    public string $street = '123 PHP Avenue';
    public string $city = 'Codeville';
}

class User
{
    public int $id = 42;
    public string $name = 'John Doe';
    public Address $address;
    private string $sessionToken = 'a-very-secret-token'; // This will be ignored.

    public function __construct()
    {
        $this->address = new Address();
    }
}

$userObject = new User();

$userArray = toAssociativeArray($userObject);

print_r($userArray);
// Output:
// Array
// (
//     [id] => 42
//     [name] => John Doe
//     [address] => Array
//      (
//          [street] => 123 PHP Avenue
//          [city] => Codeville
//      )
// )
// Note that the private property 'sessionToken' is not present.

Convert an array with sub-objects:

$data = (object)
[
    'id' => 123,
    'name' => 'Project Alpha',
    'provider' => (object)
    [
       'name' => 'Alice',
       'role' => 'Chef de projet'
    ],
    'team' =>
     [
        (object) ['name' => 'Bob'     ] ,
        (object) ['name' => 'Charlie' ]
     ]
];

$arrayAssoc = toAssociativeArray($data);

print_r($arrayAssoc);

Convert using a custom JSON encoder (Closure):

$encoder = function (mixed $data): string
{
    // Example: pretty-print JSON and remove null values
    return json_encode($data, JSON_PRETTY_PRINT);
};

$result = toAssociativeArray($userObject, $encoder);

print_r($result);

Convert using a static serializer method:

use oihana\reflect\utils\JsonSerializer;
use oihana\core\options\ArrayOption;

$result = toAssociativeArray
(
$userObject,
   fn(mixed $data): string =>
       JsonSerializer::encode( $data , jsonFlags: 0 , options: [ArrayOption::REDUCE => true] )
);

print_r($result);

Convert using a named function or static method string:

// Using a named function
function my_json_encoder(mixed $data): string
{
    return json_encode($data, JSON_UNESCAPED_SLASHES);
}

$result1 = toAssociativeArray($userObject, 'my_json_encoder');

// Using a static method string
$result2 = toAssociativeArray($userObject, 'MyJsonHelper::encode');

print_r($result1);
print_r($result2);
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
array<string|int, mixed>

The resulting associative array.

values()

Returns the list of public property values of an object.

values(object $object) : array<int, mixed>

Only the accessible (public and dynamic) property values are returned, in declaration order, mirroring the behaviour of get_object_vars() from outside the class.

Parameters
$object : object

The source object.

Tags
example
use function oihana\core\objects\values;

$user = (object) [ 'id' => 42 , 'name' => 'Alice' ] ;

values( $user ) ; // [ 42 , 'Alice' ]
author

Marc Alcaraz (ekameleon)

since
1.0.9
Return values
array<int, mixed>

A list of the object's public property values.

On this page

Search results