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.2.0(11mo ago)253294.8k↓10.1%8[1 PRs](https://github.com/spatie/laravel-options/pulls)2MITPHPPHP ^8.1CI passing

Since Jul 6Pushed 8mo 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 1mo ago

READMEChangelog (10)Dependencies (15)Versions (12)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

52

—

FairBetter than 96% of packages

Maintenance57

Moderate activity, may be stable

Popularity53

Moderate usage in the ecosystem

Community22

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 62% 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 ~107 days

Recently: every ~216 days

Total

11

Last Release

336d 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 (44 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)")[![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-data

Create unified resources and data transfer objects

1.8k28.9M627](/packages/spatie-laravel-data)[spatie/laravel-livewire-wizard

Build wizards using Livewire

4061.0M4](/packages/spatie-laravel-livewire-wizard)[spatie/laravel-support-bubble

A non-intrusive support chat bubble that can be displayed on any page

391173.6k](/packages/spatie-laravel-support-bubble)[hirethunk/verbs

An event sourcing package that feels nice.

513162.9k6](/packages/hirethunk-verbs)[spatie/laravel-rdap

Perform RDAP queries in a Laravel app

72108.3k2](/packages/spatie-laravel-rdap)[worksome/exchange

Check Exchange Rates for any currency in Laravel.

123544.7k](/packages/worksome-exchange)

PHPackages © 2026

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