CRUDUI PHP API

Patch
in package

FinalYes

$patch application — add / remove / replace over the $ref base (SPEC §5).

Byte-for-byte port of validator-ts/src/compose/patch.ts.

$patch is an OBJECT of operations. Two order-preserving input shapes are supported:

  1. Deep-path set — "field.validate.required": ".other". The dotted key is split into path segments and the value is SET at that node (creating intermediate objects). SPEC §5 canonical form. The value replaces any scalar leaf; for object values it deep-merges (both objects → deep merge, else the latter wins).

  2. Structured ops — explicit add / remove / replace keys: add: { "path.to.new": value, … } — deep-merge value at path replace: { "path.to.key": value, … } — same merge rule (scalar override) remove: [ "path.to.key", … ] | { … } — deep delete

Resolution order: base ($ref) first, then $patch overlays. add/replace deep-merge; remove deep-deletes; deep-path set splits then applies. An unresolved patch (op shape error, path conflict, strict-remove miss) is a LOAD ERROR — never valid:true.

Table of Contents

Methods

apply()  : array<string, mixed>
Apply a $patch object to the (already $ref-expanded) base spec.
applyAddReplace()  : array<string, mixed>
Structured add/replace: a map of deep-path → value, deep-merged at each path.
applyRemove()  : array<string, mixed>
Structured remove: an array of deep-paths, or a nested {k:{sub:…}} map.
mergeValue()  : mixed
Deep-merge leaf rule: both plain objects → recursive deep merge; otherwise the latter value wins (scalar/array override). Mirrors JS mergeValue; an UNDEFINED existing means "no prior leaf" (JS existing === undefined), so the incoming value is taken as-is.
removeDeepPath()  : array<string, mixed>
Delete a value at a deep path. Strict: a missing target is a load error.
removeNested()  : array<string, mixed>
Nested-map remove: for each key, recurse when both the target and the removal spec are objects, else unset the key. A missing key is tolerated here (silently skipped), unlike the array form.
setDeepPath()  : array<string, mixed>
Set a value at a deep path, creating intermediate objects. When both the existing leaf and the new value are plain objects, DEEP-MERGE; otherwise the new value REPLACES. Returns a new tree (PHP arrays are value types, so the input is never mutated).
splitPath()  : array<int, string>
Split a dotted deep-path into segments. Empty path is a shape error.
typeName()  : string
JS-style type name for $patch shape error messages.

Methods

apply()

Apply a $patch object to the (already $ref-expanded) base spec.

public static apply(array<string, mixed> $base, mixed $patch) : array<string, mixed>
Parameters
$base : array<string, mixed>
$patch : mixed
Return values
array<string, mixed>

applyAddReplace()

Structured add/replace: a map of deep-path → value, deep-merged at each path.

private static applyAddReplace(array<string, mixed> $base, mixed $val, string $op) : array<string, mixed>
Parameters
$base : array<string, mixed>
$val : mixed
$op : string
Return values
array<string, mixed>

applyRemove()

Structured remove: an array of deep-paths, or a nested {k:{sub:…}} map.

private static applyRemove(array<string, mixed> $base, mixed $val) : array<string, mixed>
Parameters
$base : array<string, mixed>
$val : mixed
Return values
array<string, mixed>

mergeValue()

Deep-merge leaf rule: both plain objects → recursive deep merge; otherwise the latter value wins (scalar/array override). Mirrors JS mergeValue; an UNDEFINED existing means "no prior leaf" (JS existing === undefined), so the incoming value is taken as-is.

private static mergeValue(mixed $existing, mixed $incoming) : mixed
Parameters
$existing : mixed
$incoming : mixed

removeDeepPath()

Delete a value at a deep path. Strict: a missing target is a load error.

private static removeDeepPath(array<string, mixed> $node, array<int, string> $segments) : array<string, mixed>
Parameters
$node : array<string, mixed>

the tree that holds the value

$segments : array<int, string>

the path from the root of the tree to the deleted member

Tags
throws
ComposeLoadError

when a segment is missing or descends into a value that is not an object

Return values
array<string, mixed> —

the tree without the member

removeNested()

Nested-map remove: for each key, recurse when both the target and the removal spec are objects, else unset the key. A missing key is tolerated here (silently skipped), unlike the array form.

private static removeNested(array<string, mixed> $base, array<string, mixed> $spec) : array<string, mixed>
Parameters
$base : array<string, mixed>
$spec : array<string, mixed>
Return values
array<string, mixed>

setDeepPath()

Set a value at a deep path, creating intermediate objects. When both the existing leaf and the new value are plain objects, DEEP-MERGE; otherwise the new value REPLACES. Returns a new tree (PHP arrays are value types, so the input is never mutated).

private static setDeepPath(array<string, mixed> $node, array<int, string> $segments, mixed $value) : array<string, mixed>
Parameters
$node : array<string, mixed>

the tree that receives the value

$segments : array<int, string>

the path from the root of the tree to the leaf, one key per segment

$value : mixed

the value written at the leaf

Return values
array<string, mixed> —

the tree with the value set

splitPath()

Split a dotted deep-path into segments. Empty path is a shape error.

private static splitPath(string $path) : array<int, string>
Parameters
$path : string
Return values
array<int, string>

typeName()

JS-style type name for $patch shape error messages.

private static typeName(mixed $v) : string
Parameters
$v : mixed
Return values
string
On this page

Search results