PHPackages                             spatie/laravel-options - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. spatie/laravel-options

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

spatie/laravel-options
======================

Create arrays of options from different sources

1.3.0(4mo ago)252362.7k↓33%92MITPHPPHP ^8.1CI passing

Since Jul 6Pushed 4mo ago2 watchersCompare

[ Source](https://github.com/spatie/laravel-options)[ Packagist](https://packagist.org/packages/spatie/laravel-options)[ Docs](https://github.com/spatie/laravel-options)[ RSS](/packages/spatie-laravel-options/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (10)Dependencies (30)Versions (13)Used By (2)

Create lists of options from different sources
==============================================

[](#create-lists-of-options-from-different-sources)

[![Latest Version on Packagist](https://camo.githubusercontent.com/43b343ee7bae872d36a67d036322c5956fb6c77565a3d63b0ecded692d0f17c7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7370617469652f6c61726176656c2d6f7074696f6e732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spatie/laravel-options)[![run-tests](https://github.com/spatie/laravel-options/actions/workflows/run-tests.yml/badge.svg)](https://github.com/spatie/laravel-options/actions/workflows/run-tests.yml)[![PHPStan](https://github.com/spatie/laravel-options/actions/workflows/phpstan.yml/badge.svg)](https://github.com/spatie/laravel-options/actions/workflows/phpstan.yml)[![Total Downloads](https://camo.githubusercontent.com/31e7e0cb99c9fb46eb5909732bf24c67bec03b5c41f36b2be8f48a4c5462cafb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7370617469652f6c61726176656c2d6f7074696f6e732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spatie/laravel-options)

A typical web application always has many select fields with options. This package makes it simple to transform enums, models, states and arrays to a unified option structure.

Let's say you have the following enum:

```
enum Hobbit: string
{
    case Frodo = 'frodo';
    case Sam = 'sam';
    case Merry = 'merry';
    case Pippin = 'pippin';
}
```

You can convert this to options like this:

```
Options::forEnum(Hobbit::class)->toArray();
```

Which will return the following array:

```
[
    ['label' => 'Frodo', 'value' => 'frodo'],
    ['label' => 'Sam', 'value' => 'sam'],
    ['label' => 'Merry', 'value' => 'merry'],
    ['label' => 'Pippin', 'value' => 'pippin'],
]
```

Support us
----------

[](#support-us)

[![](https://camo.githubusercontent.com/8ef6385772193a9e82d4fdbb15c4346392218a32a7c83d342edccbd6e61a581a/68747470733a2f2f6769746875622d6164732e73332e65752d63656e7472616c2d312e616d617a6f6e6177732e636f6d2f6c61726176656c2d6f7074696f6e732e6a70673f743d31)](https://spatie.be/github-ad-click/laravel-options)

We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require spatie/laravel-options
```

You can publish the config file with:

```
php artisan vendor:publish --tag="options-config"
```

This is the contents of the published config file:

```
return [
    /*
     * The key used in an option to describe the label of the option
     */
    'label_key' => 'label',

    /*
     * The key used in an option to describe the value of the option
     */
    'value_key' => 'value',
];
```

Usage
-----

[](#usage)

You can create an `Options` object like this (we'll cover other things then enums later on):

```
Options::forEnum(Hobbit::class);
```

You can get an array representation of the options like this:

```
Options::forEnum(Hobbit::class)->toArray();
```

Or a JSON version like this:

```
Options::forEnum(Hobbit::class)->toJson();
```

You can return options as part of a response in your controller, and they will be automatically converted into JSON:

```
class ShowHobbitsController{
    public function __invoke(RingBearer $ringBearer){
        return [
            'ring_bearer' => $ringBearer,
            'hobbit_options' => Options::forEnum(Hobbit::class)
        ]
    }
}
```

### Manipulating options

[](#manipulating-options)

You can sort options by their label like this:

```
Options::forEnum(Hobbit::class)->sort();
```

Or use a closure to sort the options:

```
Options::forEnum(Hobbit::class)->sort(fn(Hobbit $hobbit) => $hobbit->value);
```

You can append additional data to the options like this:

```
Options::forEnum(Hobbit::class)->append(fn(Hobbit $hobbit) => [
    'ring_bearer' => $hobbit === Hobbit::Frodo || $hobbit === Hobbit::Sam
]);
```

This will result in the following options array:

```
[
    ['label' => 'Frodo', 'value' => 'frodo', 'ring_bearer' => true],
    ['label' => 'Sam', 'value' => 'sam', 'ring_bearer' => true],
    ['label' => 'Merry', 'value' => 'merry', 'ring_bearer' => false],
    ['label' => 'Pippin', 'value' => 'pippin', 'ring_bearer' => false],
]
```

You can filter the options that will be included:

```
Options::forEnum(Hobbit::class)->filter(fn(Hobbit $hobbit) => $hobbit === Hobbit::Frodo);
```

Which will create a smaller options array:

```
[
    ['label' => 'Frodo', 'value' => 'frodo'],
]
```

Or reject specific options to be included:

```
Options::forEnum(Hobbit::class)->reject(fn(Hobbit $hobbit) => $hobbit === Hobbit::Frodo);
```

Which will create this options array:

```
[
    ['label' => 'Sam', 'value' => 'sam'],
    ['label' => 'Merry', 'value' => 'merry'],
    ['label' => 'Pippin', 'value' => 'pippin'],
]
```

Depending on the type of options you're creating it is possible to call `only` on them to only include specific options:

```
Options::forEnum(Hobbit::class)->only(Hobbit::Frodo, Hobbit::Sam);
```

This will result in the following options array:

```
[
    ['label' => 'Frodo', 'value' => 'frodo'],
    ['label' => 'Sam', 'value' => 'sam'],
]
```

The same can be done with `except` to exclude specific options:

```
Options::forEnum(Hobbit::class)->except(Hobbit::Frodo, Hobbit::Sam);
```

This will result in the following options array:

```
[
    ['label' => 'Merry', 'value' => 'merry'],
    ['label' => 'Pippin', 'value' => 'pippin'],
]
```

A unique `null` option can be added as such:

```
Options::forEnum(Hobbit::class)->nullable();
```

This will add an option with the value `null`:

```
[
    ['label' => '-', 'value' => null],
    ['label' => 'Frodo', 'value' => 'frodo'],
    ['label' => 'Sam', 'value' => 'sam'],
    ['label' => 'Merry', 'value' => 'merry'],
    ['label' => 'Pippin', 'value' => 'pippin'],
]
```

The label of the `null` option can be changed as such:

```
Options::forEnum(Hobbit::class)->nullable('Gandalf');
```

Another value for null can be set as follows:

```
Options::forEnum(Hobbit::class)->nullable(label: 'Gandalf', value: 'You Shall Not Pass');
```

It is possible to change the keys used in options by changing the `options.php` config file. For example:

```
return [
    /*
     * The key used in an option to describe the label of the option
     */
    'label_key' => 'name',

    /*
     * The key used in an option to describe the value of the option
     */
    'value_key' => 'id',
];
```

Will result in the following options:

```
[
    ['name' => 'Frodo', 'id' => 'frodo'],
    ['name' => 'Sam', 'id' => 'sam'],
    ['name' => 'Merry', 'id' => 'merry'],
    ['name' => 'Pippin', 'id' => 'pippin'],
]
```

### With enums

[](#with-enums)

You can create options for native PHP enums, [Spatie Enums](https://github.com/spatie/enum) and [MyClabs Enums](https://github.com/myclabs/php-enum) like this:

```
Options::forEnum(Hobbit::class);
```

By default, the package will look for a static method called `labels` with the labels for the enum returned as an array:

```
enum Hobbit: string
{
    case Frodo = 'frodo';
    case Sam = 'sam';
    case Merry = 'merry';
    case Pippin = 'pippin';

    public static function labels(): array
    {
       return [
           'frodo' => 'Frodo Baggins',
           'sam' => 'Sam Gamgee',
           'merry' => 'Merry Brandybuck',
           'pippin' => 'Pippin Took',
       ];
    }
}
```

Now the options array will look like this:

```
[
    ['label' => 'Frodo Baggins', 'value' => 'frodo'],
    ['label' => 'Sam Gamgee', 'value' => 'sam'],
    ['label' => 'Merry Brandybuck', 'value' => 'merry'],
    ['label' => 'Pippin Took', 'value' => 'pippin'],
]
```

You can use another method name for the labels as such:

```
Options::forEnum(Hobbit::class, 'hobbitLabels');
```

Or use a closure to resolve the label for the enum:

```
Options::forEnum(Hobbit::class, fn(Hobbit $hobbit) => $hobbit->name. ' from the shire'));
```

It is possible to filter or reject options using the `only` and `except` methods as such:

```
Options::forEnum(Hobbit::class)->only(Hobbit::Frodo, Hobbit::Sam);

Options::forEnum(Hobbit::class)->except(Hobbit::Frodo, Hobbit::Sam);
```

### With models

[](#with-models)

You can create options for Laravel models like this:

```
Options::forModels(Wizard::class);
```

Use a single model like this:

```
Options::forModels(Wizard::first());
```

Or for a collection of models:

```
Options::forModels(Wizard::all());
```

You can also pass a `Builder` instance:

```
Options::forModels(Wizard::query()->where('name', 'gandalf'));
```

By default, the model's key (usually `id`) will be taken as a value and the `name` field as the label.

You can change the value field like this:

```
Options::forModels(Wizard::class, value: 'uuid');
```

Or use a closure for determining the value:

```
Options::forModels(Wizard::class, value: fn(Wizard $wizard) => $wizard->uuid());
```

You can change the label field as such:

```
Options::forModels(Wizard::class, label: 'full_name');
```

Or you can use a closure to resolve the label:

```
Options::forModels(Wizard::class, label: fn(Wizard $wizard) => $wizard->getName());
```

It is possible to filter or reject options using the `only` and `except` methods as such:

```
Options::forModels(Wizard::class)->only(Wizard::where('name', 'gandalf')->first());

Options::forModels(Wizard::class)->except(Wizard::where('name', 'gandalf')->first());
```

### With Select Options

[](#with-select-options)

If you're using options for a model in a lot of places, then each time, manually defining the label and/or value fields can become quite tedious:

```
Options::forModels(
    Wizard::class,
    label: fn(Wizard $wizard) => $wizard->getUuid(),
    value: fn(Wizard $wizard) => $wizard->getName(),
); // A lot of times within your code base
```

You can implement `Selectable` on a model (or any PHP class), which will automatically convert a model into an option with the correct fields:

```
class Wizard extends Model implements Selectable
{
    public function toSelectOption(): SelectOption
    {
        return new SelectOption(
            $this->getName(),
            $this->getUuid()
        )
    }
}
```

Now you can omit the label and value field definitions:

```
Options::forModels(Wizard::class);
```

You can also pass some extra data with the `SelectOption` like the `append` method we saw earlier:

```
public function toSelectOption(): SelectOption
{
    return new SelectOption(
        $this->getName(),
        $this->getUuid(),
        ['color' => $this->color]
    )
}
```

Now the options array will look like this:

```
[
    ['label' => 'Gandalf', 'id' => '...', 'color' => 'gray'],
    ['label' => 'Saruman', 'id' => '...', 'color' => 'white'],
]
```

As said earlier, implementing `Selectable` is not limited to models. You can implement it on any PHP class. In such a case, you can create options like this:

```
Options::forSelectableOptions([
    SelectableOption::find(1),
    SelectableOption::find(2),
    SelectableOption::find(3),
]);
```

### With states

[](#with-states)

It is possible to create options from the [Spatie model states](https://github.com/spatie/laravel-model-states) package like this:

```
Options::forStates(RingState::class);
```

You can pass in a model like this (otherwise, a temporary model is created):

```
Options::forStates(RingState::class, $ring);
```

The package will automatically look for a `label` public method to use as a label:

```
class LostRingState extends RingsState
{
    public function label(): string
    {
        return 'Lost';
    }
}
```

Or a `label` public property:

```
class DestroyedRingState extends RingsState
{
    public string $label = 'destroyed';
}
```

You can change the name of the method or property which will be used as a label as such:

```
Options::forStates(RingState::class, label: 'ringLabel');
```

Or use a closure to resolve the label for the state:

```
Options::forStates(RingState::class, label: fn(RingState $state) => $state->label());
```

It is possible to filter or reject options using the `only` and `except` methods as such:

```
Options::forStates(RingState::class)->only(LostRingState::class, DestroyedRingState::class);

Options::forStates(RingState::class)->except(LostRingState::class, DestroyedRingState::class);
```

### With Arrays

[](#with-arrays)

You can create a set of options from an associative array:

```
Options::forArray([
    'gondor' => 'Gondor',
    'rohan' => 'Rohan',
    'mordor' => 'Mordor',
])
```

You can also use a plain array as such:

```
Options::forArray([
    'Gondor',
    'Rohan',
    'Mordor',
],useLabelsAsValue: true)
```

In this case, the labels and values will be equal.

It is possible to filter or reject options using the `only` and `except` methods as such using the keys of the array:

```
Options::forArray($options)->only('gondor', 'rohan');

Options::forArray($options)->except('gondor', 'rohan');
```

### Without anything

[](#without-anything)

Lastly, you can create an empty options list like this:

```
Options::empty();
```

### Using for validation

[](#using-for-validation)

Options, can be converted to a Laravel validation rule:

```
$request->validate([
    // ['in:frodo,sam,merry,pippin']
    'hobbit' => Options::forEnum(Hobbit::class)->toValidationRule()
]);
```

When options are nullable, the validation rule automatically will become nullable:

```
$request->validate([
    // ['nullable', 'in:frodo,sam,merry,pippin']
    'hobbit' => Options::forEnum(Hobbit::class)->nullable()->toValidationRule()
]);
```

### Iterating

[](#iterating)

It is possible to iterator over a set of options:

```
foreach(Options::forEnum(Hobbit::class) as $option){
    echo "{$option['label']}";
}
```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Ruben Van Assche](https://github.com/rubenvanassche)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

57

—

FairBetter than 98% of packages

Maintenance75

Regular maintenance activity

Popularity53

Moderate usage in the ecosystem

Community22

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 59% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~124 days

Recently: every ~287 days

Total

12

Last Release

133d ago

Major Versions

0.0.2 → 1.0.02022-07-06

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/7535935?v=4)[Spatie](/maintainers/spatie)[@spatie](https://github.com/spatie)

---

Top Contributors

[![rubenvanassche](https://avatars.githubusercontent.com/u/619804?v=4)](https://github.com/rubenvanassche "rubenvanassche (46 commits)")[![freekmurze](https://avatars.githubusercontent.com/u/483853?v=4)](https://github.com/freekmurze "freekmurze (11 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (6 commits)")[![evan-burrell](https://avatars.githubusercontent.com/u/44360092?v=4)](https://github.com/evan-burrell "evan-burrell (5 commits)")[![rodrigopedra](https://avatars.githubusercontent.com/u/5470108?v=4)](https://github.com/rodrigopedra "rodrigopedra (5 commits)")[![AlexVanderbist](https://avatars.githubusercontent.com/u/6287961?v=4)](https://github.com/AlexVanderbist "AlexVanderbist (2 commits)")[![robtesch](https://avatars.githubusercontent.com/u/30407321?v=4)](https://github.com/robtesch "robtesch (2 commits)")[![raksbisht](https://avatars.githubusercontent.com/u/15016564?v=4)](https://github.com/raksbisht "raksbisht (1 commits)")

---

Tags

spatielaraveloptions

###  Code Quality

TestsPest

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/spatie-laravel-options/health.svg)

```
[![Health](https://phpackages.com/badges/spatie-laravel-options/health.svg)](https://phpackages.com/packages/spatie-laravel-options)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

13.0k107.5M1.6k](/packages/spatie-laravel-permission)[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k5.4M50](/packages/spatie-laravel-pdf)[codewithdennis/filament-select-tree

The multi-level select field enables you to make single selections from a predefined list of options that are organized into multiple levels or depths.

329575.9k35](/packages/codewithdennis-filament-select-tree)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3915.5k](/packages/rawilk-profile-filament-plugin)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
