Arr::pull
Reads a value from an array and removes that key in one step.
public static function pull(&$array, $key, $default = null)Parameters
| Parameter | Type | Description |
|---|---|---|
$&$array | array | The array to read from and mutate. Passed by reference, so it must be a variable. |
$$key | string|int | The key to pull. Dot notation is supported because the implementation delegates to Arr::get and Arr::forget. |
$$defaultoptional | mixed= null | Returned when the key is absent. Resolved through value(), so a Closure is invoked lazily. |
Return value
mixedThe value that was stored at the key, or the default when the key does not exist.
Errors
Raises an error if the first argument is not a variable, since it is taken by reference.
Arr::pull is Arr::get followed by Arr::forget. It answers the very common pattern of taking one field out of a payload so the rest can be handled generically.
When to reach for it
- Splitting a validated payload: pull the relationship or upload field out, then mass-assign what remains.
- Consuming an options array where each handler removes the option it understands and the leftovers signal unknown options.
- Extracting a token or nonce from a data array so it is not persisted along with everything else.
What trips people up
The array is taken by reference, so it must be a variable. Arr::pull($this->config(), 'key') or pulling straight from a function's return value is a fatal error, not a silent no-op.
It mutates. If the array is used elsewhere after the call, that caller now sees a different array. When you only want to read, use Arr::get; when you only want to remove, use Arr::forget.
Dot notation removes the leaf, not the branch. Pulling 'meta.sku' takes the sku value and leaves meta behind as an empty array. Pull 'meta' if you want the whole level gone.
Pulling a key that never existed does not create it — the default is returned and the array is untouched.
Example
When to use it
- Take a relationship field out of a validated payload before mass-assigning the rest.
- Strip a one-time token from a data array so it never reaches storage.
- Consume known options from a settings array and treat whatever remains as unrecognised.
Frequently asked questions
Does Arr::pull support dot notation?
Yes, because it delegates to Arr::get and Arr::forget internally. Note that pulling 'meta.sku' removes only the sku leaf and leaves an empty meta array behind.
Why do I get an error passing a method call to Arr::pull?
The first parameter is declared by reference, so PHP requires a variable. Assign the result to a local variable first, then pull from that.
What is the difference between Arr::pull and Arr::get?
Arr::pull removes the key after reading it and mutates the array you pass; Arr::get only reads and leaves the array unchanged.
More examples
Splitting a payload before mass assignment
After the pull, $data holds only title and body — the columns that actually exist on the table — while $tags is handled separately. Using Arr::get here would leave 'tags' in $data and break the create() call.
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
class PostController extends Controller
{
public function store(Request $request)
{
$data = $request->validate([
'title' => ['required', 'string'],
'body' => ['required', 'string'],
'tags' => ['array'],
]);
// Take the relationship data out so $data is safe to mass assign.
$tags = Arr::pull($data, 'tags', []);
$post = Post::create($data);
$post->tags()->sync($tags);
return redirect()->route('posts.show', $post);
}
}Pull versus get and forget
The counts show the difference plainly: Arr::get leaves the array at three keys, Arr::pull drops it to two. The leftover-keys pattern in the last line is how option parsers detect arguments they did not recognise.
<?php
use Illuminate\Support\Arr;
$options = ['driver' => 'redis', 'ttl' => 60, 'tags' => ['a', 'b']];
// Read without mutating.
$driver = Arr::get($options, 'driver');
echo count($options), PHP_EOL;
// Read and remove.
$ttl = Arr::pull($options, 'ttl');
echo count($options), PHP_EOL;
// Whatever is left is what nobody consumed.
print_r(array_keys($options));
/*
3
2
Array
(
[0] => driver
[1] => tags
)
*/
Discussion