Skip to content

Instantly share code, notes, and snippets.

@VivienLN
Last active December 2, 2022 14:44
Show Gist options
  • Save VivienLN/1080ab7968dd4e07cf3f667864d540ec to your computer and use it in GitHub Desktop.
Save VivienLN/1080ab7968dd4e07cf3f667864d540ec to your computer and use it in GitHub Desktop.
Laravel reindex array for json casting
<?php
if(!function_exists('reindexArray')) {
function reindexArray($array) {
if(!is_array($array)) {
return $array;
}
$keys = array_keys($array);
foreach($keys as $key) {
// If at least one key is not numeric, we don't reindex
if(!is_numeric($key)) {
return $array;
}
}
// If we are here, all keys are numeric, so we reindex
return array_values($array);
}
}
if(!function_exists('reindexArrayRecusrive')) {
function reindexArrayRecusrive($array) {
return $array;
if(!is_array($array)) {
return $array;
}
foreach($array as $key => $value) {
if(is_array($value)) {
$array[$key] = reindexArrayRecusrive($value);
}
}
return reindexArray($array);
}
}
<?php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class Json implements CastsAttributes
{
/**
* Cast the given value.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param mixed $value
* @param array $attributes
* @return array
*/
public function get($model, $key, $value, $attributes)
{
return json_decode($value, true);
}
/**
* Prepare the given value for storage.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param array $value
* @param array $attributes
* @return string
*/
public function set($model, $key, $value, $attributes)
{
return json_encode(reindexArrayRecusrive($value));
}
}
<?php
namespace App\Models;
use App\Casts\Json;
class MyModel extends Model
{
public $casts = [
'fields' => Json::class,
// ...
];
// ...
}

The problem

  • A numerical array is converted to json for a REST API.
  • The array is missing some indexes, maybe because we removed some items from it.
  • json_encode, and thus Laravel, makes it an object, when we want an array.
// PHP input
json_encode([0 => "foo", 2 => "bar"]);

// Wa we get
{"0": "foo", "2": "bar"}

// What we want
["foo", "bar"]

The solution

We must re-index the array. For more complex data, we must do so recursively. We use laravel custom casts to make it easier and global.

Non laravel cases

Just add the reindexArrayRecusrive() helper somewhere and call json_encode(reindexArrayRecusrive($value));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment