Arr::set() and data_set() seem to be returning different array structures setting the same nested property. Arr::set() is returning an array at the level of the property you are setting where as data_set() is returning the entire array with the nested property set as expected.
Given the following array
[
'editor' => [
'page' => [
'body' => [],
'rows' => [],
'title' => 'Fragment Base',
'template' => [],
'description' => '',
],
],
];
When I try to set any nested value inside editor, it returns me an array at that level
Example: I try to set rows using Arr::set($array, 'editor.page.rows', ['my test array']) and it returns me an array of
[
'body' => [],
'rows' => ['my test array'],
'title' => 'Fragment Base',
'template' => [],
'description' => '',
]
However, using data_set($array, 'editor.page.rows', ['my test array']), the returned array is expected.
[
'editor' => [
'page' => [
'body' => [],
'rows' => ['my test array'],
'title' => 'Fragment Base',
'template' => [],
'description' => '',
],
],
];

Hey there,
Unfortunately we don't support this version anymore. Please check out our support policy on which versions we are currently supporting. Can you please try to upgrade to the latest version and see if your problem persists? We'll help you out and re-open this issue if so.
Thanks!
Thanks for the quick response! I just tested on Laravel 8.3 and the problem persists. Updating the above issue with the correct version number.
@therobfonz these are two different functions which don't mimic each other's behavior.
Correct, however, the documentation for each method has the example like I have outlined above and shows the same results
https://laravel.com/docs/8.x/helpers#method-data-set
https://laravel.com/docs/8.x/helpers#method-array-set
When I use the documentation example in Laravel 8.3 for Arr::set() as noted
$array = ['products' => ['desk' => ['price' => 100]]];
Arr::set($array, 'products.desk.price', 200);
// ['products' => ['desk' => ['price' => 200]]]
it only returns
['price' => 200']
not the array noted as the documented example output. This could just be a documentation issue, but if the documentation is supposed to be the correct output, it would be a bug.
@therobfonz
I tested in a fresh Laravel 8 app and I can somehow replicate the unexpected behavior:
~~~php
// ./routes/console.php
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Arr;
Artisan::command('app:test', function () {
$array = [
'editor' => [
'page' => [
'body' => [],
'rows' => [],
'title' => 'Fragment Base',
'template' => [],
'description' => '',
],
],
];
$return = Arr::set($array, 'editor.page.rows', ['my test array']);
\dd($array, $return);
});
~~~
Which outputs different results for the $array and $return variables:
~bash
$ php artisan app:test
array:1 [
"editor" => array:1 [
"page" => array:5 [
"body" => []
"rows" => array:1 [
0 => "my test array"
]
"title" => "Fragment Base"
"template" => []
"description" => ""
]
]
]
array:5 [
"body" => []
"rows" => array:1 [
0 => "my test array"
]
"title" => "Fragment Base"
"template" => []
"description" => ""
]
~
I also would expect both values to be the same. I tried tweaking the code to try getting the same value but with no luck.
I must confess that I never relied on the return value and always used it like this:
~~~php
$array = [/some data/];
Arr::set($data, 'my.key', 'value');
return $data;
~~~
As I expected it to change the parameter by reference. So maybe not relying on its return value is the way to go.
So, this is an interesting curiosity; however, I'm not sure we will really take any action on it. Making any change to it would be a breaking change for seemingly little benefit. Like the comment above, I've never relied on the returned value and the method doc blocks don't even describe what the return value is "supposed" to be. I actually wasn't even aware these methods had a return value until this issue was raised. 馃槅
So, for now, I think we will probably take no action. The safest course IMO is to use Arr::set and then use Arr::get afterwards to get exactly what you want from the array.
Thanks for the explanation Taylor. I'll proceed as you have outlined above.
Most helpful comment
So, this is an interesting curiosity; however, I'm not sure we will really take any action on it. Making any change to it would be a breaking change for seemingly little benefit. Like the comment above, I've never relied on the returned value and the method doc blocks don't even describe what the return value is "supposed" to be. I actually wasn't even aware these methods had a return value until this issue was raised. 馃槅
So, for now, I think we will probably take no action. The safest course IMO is to use Arr::set and then use Arr::get afterwards to get exactly what you want from the array.