data_forget
Remove a nested key from an array or object using dot notation.
data_forget(mixed &$target, string|array|int|null $key): mixed- Added in Laravel 10.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$target | mixed | The array or object to remove from, passed by reference and mutated in place. |
$key | string|array|int|null | The dot-notation path to remove. An * segment removes the trailing key from every element at that level. |
Return value
mixedThe modified target. The target is also mutated in place because it is taken by reference.
data_forget() is the removal half of the data_* family. It walks the dot path and unsets the final segment, on arrays and on public object properties alike, mutating the target in place through a reference parameter.
When to reach for it
The usual job is stripping fields out of a structure you are about to hand somewhere else: dropping password and token before logging a request, removing internal bookkeeping keys before returning a payload, or clearing a field from every row of a nested list in one call.
Wildcards
An * segment removes the trailing key from each element at that level. data_forget($data, 'products.*.price') leaves every product in place and only drops its price.
It removes the key, not the parent
Forgetting products.desk.price leaves products.desk behind as an empty array. Nothing collapses or prunes upward; if you want the parent gone, forget the parent.
Missing paths are silent
A path that does not resolve is simply a no-op — no exception, no warning, no return value you can test. That makes it safe to call speculatively, but it also means a typo in the path removes nothing and reports nothing.
Example
When to use it
- Strip password and token fields from a request payload before writing it to a log.
- Drop one attribute from every row of a nested list with a single wildcard call.
- Remove internal bookkeeping keys from a structure before returning it as JSON.
Frequently asked questions
Does data_forget remove the parent key when it becomes empty?
No, the parent stays as an empty array or object. Forgetting products.desk.price leaves products.desk as an empty array, so call data_forget on the parent path if you want that gone too.
How do I know whether data_forget actually removed anything?
You cannot from the return value — it returns the target whether or not the path matched, and a missing path is a silent no-op. Check with data_get() or Arr::has() before or after the call if the outcome matters.
Can data_forget remove properties from an object?
Yes, it unsets public object properties as well as array keys, and a single path may traverse both. Private and protected properties are not reachable from outside the class and are left alone.
More examples
Redacting before logging
Two calls remove a single scalar and one key across a list. The rows themselves survive, so the log still shows how many cards were involved and which brands.
<?php
$payload = [
'user' => [
'email' => '[email protected]',
'password' => 'hunter2',
],
'cards' => [
['brand' => 'visa', 'number' => '4111111111111111'],
['brand' => 'amex', 'number' => '371449635398431'],
],
];
data_forget($payload, 'user.password');
data_forget($payload, 'cards.*.number');
echo json_encode($payload), "\n";
// {"user":{"email":"[email protected]"},"cards":[{"brand":"visa"},{"brand":"amex"}]}Empty parents are left behind
Removing the last child does not remove its now-empty parent, and a mistyped path produces no error at all. Both behaviours are quiet enough to hide a bug in a long pipeline.
<?php
$data = ['products' => ['desk' => ['price' => 100]]];
data_forget($data, 'products.desk.price');
var_dump($data);
// array(1) { ["products"]=> array(1) { ["desk"]=> array(0) {} } }
// A path that does not exist is silently ignored.
data_forget($data, 'products.chair.price');
var_dump(array_keys($data['products']));
// array(1) { [0]=> string(4) "desk" }
// To drop the parent, forget the parent.
data_forget($data, 'products.desk');
var_dump($data['products']);
// array(0) {}Cleaning a resource in an application
A resource is a good place for this because the removals are declared once and apply to every serialised order, including the nested line items. Needs a booted application for the Request and JsonResource.
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class OrderResource extends JsonResource
{
public function toArray(Request $request): array
{
$data = parent::toArray($request);
// Internal columns that must never reach the client.
data_forget($data, 'internal_notes');
data_forget($data, 'lines.*.cost_price');
return $data;
}
}
Discussion