Skip to content

[12.x] Typed getters for Arr helper #55567

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: 12.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions src/Illuminate/Collections/Arr.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,38 @@ public static function add($array, $key, $value)
return $array;
}

/**
* Get an array item from an array using "dot" notation.
*/
public static function array(ArrayAccess|array $array, string|int|null $key, ?array $default = null): array
{
$value = Arr::get($array, $key, $default);

if (! is_array($value)) {
throw new InvalidArgumentException(
sprintf('Array value for key [%s] must be an array, %s given.', $key, gettype($value))
);
}

return $value;
}

/**
* Get a boolean item from an array using "dot" notation.
*/
public static function boolean(ArrayAccess|array $array, string|int|null $key, ?bool $default = null): bool
{
$value = Arr::get($array, $key, $default);

if (! is_bool($value)) {
throw new InvalidArgumentException(
sprintf('Array value for key [%s] must be a boolean, %s given.', $key, gettype($value))
);
}

return $value;
}

/**
* Collapse an array of arrays into a single array.
*
Expand Down Expand Up @@ -286,6 +318,22 @@ public static function flatten($array, $depth = INF)
return $result;
}

/**
* Get a float item from an array using "dot" notation.
*/
public static function float(ArrayAccess|array $array, string|int|null $key, ?float $default = null): float
{
$value = Arr::get($array, $key, $default);

if (! is_float($value)) {
throw new InvalidArgumentException(
sprintf('Array value for key [%s] must be a float, %s given.', $key, gettype($value))
);
}

return $value;
}

/**
* Remove one or many array items from a given array using "dot" notation.
*
Expand Down Expand Up @@ -433,6 +481,22 @@ public static function hasAny($array, $keys)
return false;
}

/**
* Get an integer item from an array using "dot" notation.
*/
public static function integer(ArrayAccess|array $array, string|int|null $key, ?int $default = null): int
{
$value = Arr::get($array, $key, $default);

if (! is_integer($value)) {
throw new InvalidArgumentException(
sprintf('Array value for key [%s] must be an integer, %s given.', $key, gettype($value))
);
}

return $value;
}

/**
* Determines if an array is associative.
*
Expand Down Expand Up @@ -906,6 +970,22 @@ public static function sortRecursiveDesc($array, $options = SORT_REGULAR)
return static::sortRecursive($array, $options, true);
}

/**
* Get a string item from an array using "dot" notation.
*/
public static function string(ArrayAccess|array $array, string|int|null $key, ?string $default = null): string
{
$value = Arr::get($array, $key, $default);

if (! is_string($value)) {
throw new InvalidArgumentException(
sprintf('Array value for key [%s] must be a string, %s given.', $key, gettype($value))
);
}

return $value;
}

/**
* Conditionally compile classes from an array into a CSS class list.
*
Expand Down
100 changes: 100 additions & 0 deletions tests/Support/SupportArrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,106 @@ public function testGet()
$this->assertSame('bar', Arr::get(['' => ['' => 'bar']], '.'));
}

public function testItGetsAString()
{
$test_array = ['string' => 'foo bar', 'integer' => 1234];

// Test string values are returned as strings
$this->assertSame(
'foo bar', Arr::string($test_array, 'string')
);

// Test that default string values are returned for missing keys
$this->assertSame(
'default', Arr::string($test_array, 'missing_key', 'default')
);

// Test that an exception is raised if the value is not a string
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessageMatches('#^Array value for key \[integer\] must be a string, (.*) given.#');
Arr::string($test_array, 'integer');
}

public function testItGetsAnInteger()
{
$test_array = ['string' => 'foo bar', 'integer' => 1234];

// Test integer values are returned as integers
$this->assertSame(
1234, Arr::integer($test_array, 'integer')
);

// Test that default integer values are returned for missing keys
$this->assertSame(
999, Arr::integer($test_array, 'missing_key', 999)
);

// Test that an exception is raised if the value is not an integer
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessageMatches('#^Array value for key \[string\] must be an integer, (.*) given.#');
Arr::integer($test_array, 'string');
}

public function testItGetsAFloat()
{
$test_array = ['string' => 'foo bar', 'float' => 12.34];

// Test float values are returned as floats
$this->assertSame(
12.34, Arr::float($test_array, 'float')
);

// Test that default float values are returned for missing keys
$this->assertSame(
56.78, Arr::float($test_array, 'missing_key', 56.78)
);

// Test that an exception is raised if the value is not a float
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessageMatches('#^Array value for key \[string\] must be a float, (.*) given.#');
Arr::float($test_array, 'string');
}

public function testItGetsABoolean()
{
$test_array = ['string' => 'foo bar', 'boolean' => true];

// Test boolean values are returned as booleans
$this->assertSame(
true, Arr::boolean($test_array, 'boolean')
);

// Test that default boolean values are returned for missing keys
$this->assertSame(
true, Arr::boolean($test_array, 'missing_key', true)
);

// Test that an exception is raised if the value is not a boolean
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessageMatches('#^Array value for key \[string\] must be a boolean, (.*) given.#');
Arr::boolean($test_array, 'string');
}

public function testItGetsAnArray()
{
$test_array = ['string' => 'foo bar', 'array' => ['foo', 'bar']];

// Test array values are returned as arrays
$this->assertSame(
['foo', 'bar'], Arr::array($test_array, 'array')
);

// Test that default array values are returned for missing keys
$this->assertSame(
[1, 'two'], Arr::array($test_array, 'missing_key', [1, 'two'])
);

// Test that an exception is raised if the value is not an array
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessageMatches('#^Array value for key \[string\] must be an array, (.*) given.#');
Arr::array($test_array, 'string');
}

public function testHas()
{
$array = ['products.desk' => ['price' => 100]];
Expand Down