PHPackages                             lyhty/macros - 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. [Database &amp; ORM](/categories/database)
4. /
5. lyhty/macros

ActiveLibrary[Database &amp; ORM](/categories/database)

lyhty/macros
============

Helpful macros for your Laravel project.

v6.0.0(1y ago)0169[1 issues](https://github.com/lyhty/macros/issues)1MITPHPPHP ^8.2CI failing

Since Jul 17Pushed 1y agoCompare

[ Source](https://github.com/lyhty/macros)[ Packagist](https://packagist.org/packages/lyhty/macros)[ Docs](https://matti.suoraniemi.com/lyhty/macros)[ RSS](/packages/lyhty-macros/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (10)Dependencies (6)Versions (23)Used By (1)

 [![](https://camo.githubusercontent.com/3773cff9f291be2f7a5ded06b8f97ba3a2304f26313cf6f73c19b236afcee2bc/68747470733a2f2f6d617474692e73756f72616e69656d692e636f6d2f73746f726167652f6c796874792d6d6163726f732e706e67)](https://camo.githubusercontent.com/3773cff9f291be2f7a5ded06b8f97ba3a2304f26313cf6f73c19b236afcee2bc/68747470733a2f2f6d617474692e73756f72616e69656d692e636f6d2f73746f726167652f6c796874792d6d6163726f732e706e67)

[![Latest Version on Packagist](https://camo.githubusercontent.com/056c2a30142db6130d2ec6a9e977a67cc8d52efa783e82d67fdd9df0a76e5220/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c796874792f6d6163726f732e7376673f6c6162656c3d266c6f676f3d7061636b6167697374266c6f676f436f6c6f723d7768697465267374796c653d666c61742d737175617265)](https://packagist.org/packages/lyhty/macros)[![PHP](https://camo.githubusercontent.com/a851d1ec94692e757a8689398d16cb280f35f8892768183b874d0f9d743d2f5e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6c796874792f6d6163726f733f6c6162656c3d266c6f676f3d706870266c6f676f436f6c6f723d7768697465267374796c653d666c61742d737175617265)](https://packagist.org/packages/lyhty/macros)[![Laravel](https://camo.githubusercontent.com/ae586ea7917c7a64381ff9fefc6a11a1cd60534de92513caa5110c889504fcd0/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d266d6573736167653d2535453131253230253743253230253545313226636f6c6f723d726564267374796c653d666c61742d737175617265266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465)](https://packagist.org/packages/lyhty/macros)[![Total Downloads](https://camo.githubusercontent.com/e640c6228353d635d643599b2b34e3581f1889d35de0672c856120bd9ea24086/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6c796874792f6d6163726f732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/lyhty/macros)[![StyleCI](https://camo.githubusercontent.com/ec86f08823d23fb57bb440b4129afaf1b0bf0a42b4065f62d330aa48296a04ee/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f3531343431363533342f736869656c64)](https://github.styleci.io/repos/514416534)[![License](https://camo.githubusercontent.com/a702573aa9faa6adb786c1b41287cf5f0f7a69fbcdb29990bb9d24bceb42abd2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6c796874792f6d6163726f732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/lyhty/macros)

This package provides some additional, convenient macros for you to use with your Laravel project.

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

[](#installation)

Install the package with Composer:

```
composer require lyhty/macros

```

The package registers itself automatically.

Macros
------

[](#macros)

Here's a brief documentation on the macros the package provides.

- [`Illuminate\Database\Eloquent\Builder`](#illuminatedatabaseeloquentbuilder)
    - [`selectKey`](#builderselectkey)
    - [`whereLike` &amp; `orWhereLike`](#builderwherelike--orwherelike)
- [`Illuminate\Database\Query\Builder`](#illuminatedatabasequerybuilder)
    - [`selectRawArr`](#builderselectrawarr)
- [`Illuminate\Support\Collection`](#illuminatesupportcollection)
    - [`mergeMany`](#collectionmergemany)
    - [`pick` (was `pluckMany`)](#collectionpick-was-pluckmany)
    - [`whereExtends`](#collectionwhereextends)
    - [`whereImplements`](#collectionwhereimplements)
    - [`whereUses`](#collectionwhereuses)
- [`Illuminate\Support\Arr`](#illuminatesupportarr)
    - [`associate`](#arrassociate)
    - [`combine`](#arrcombine)
    - [`fillKeys`](#arrfillkeys)
    - [`implode`](#arrimplode)
    - [`join`](#arrjoin)
    - [`zip`](#arrzip)
    - [`unzip`](#arrunzip)
- [`Illuminate\Support\Str`](#illuminatesupportstr)
    - [`explodeReverse`](#strexplodereverse)
    - [`wrapWith`](#strwrapwith)
- [`Illuminate\Support\Stringable`](#illuminatesupportstringable)
    - [`explodeReverse`](#stringableexplodereverse)
    - [`wrapWith`](#stringablewrapwith)
- [`Carbon\CarbonPeriod`](#carboncarbonperiod)
    - [`collect`](#carbonperiodcollect)

### `Illuminate\Database\Eloquent\Builder`

[](#illuminatedatabaseeloquentbuilder)

#### `Builder::selectKey`

[](#builderselectkey)

Select the key of the model in the query (uses Model's `getKey` method).

```
$query = User::query()->selectKey();

$query->toSql(); // "select `id` from `users`"
```

### `Illuminate\Database\Query\Builder`

[](#illuminatedatabasequerybuilder)

#### `Builder::whereLike` &amp; `orWhereLike`

[](#builderwherelike--orwherelike)

> ⚠️ This macro relies on `Str::explodeReverse` macro. If you want to disable the latter macro, this macro will no longer function.

> ⚠️ The `Builder::orWhereLike` macro relies on `Builder::whereLike` macro. If you want to disable the `whereLike` macro, be sure to disable the `orWhereLike` macro as well.

```
$query = User::query()
    ->whereLike('name', 'Matti Suo', 'right')
    ->orWhereLike('name', 'ranie')
    ->orWhereLike('name', 'mi', 'left');

$query->toSql();
// "select * from `users` where (`users`.`name` LIKE ?) or (`users`.`name` LIKE ?) or (`users`.`name` LIKE ?)"
// First ? being "Matti Suo%", second "%ranie%" and third "%mi"

$query = User::query()->whereLike('games.name', 'Apex Leg', 'right');

$query->toSql();
// select * from `users` where (exists
//   (select * from `games` where `users`.`id` = `games`.`user_id` and `games`.`name` LIKE ?)
// )
// ? being "Apex Leg%"

$query = User::query()->whereLike(['games.console.name', 'games.platforms.name'], 'Xbox');

$query->toSql();
// select * from `users` where (exists (select * from `games` where `users`.`id` = `games`.`user_id` and (exists
// (select * from `consoles` where `games`.`console_id` = `consoles`.`id` and (`consoles`.`name` LIKE ?)) or exists
// (select * from `platforms` inner join `platform_game` on `platforms`.`id` = `platform_game`.`platform_id` where
// `games`.`id` = `platform_game`.`game_id` and (`platforms`.`name` LIKE ?)))))
// ? being "Xbox"
```

#### `Builder::selectRawArr`

[](#builderselectrawarr)

Add raw select statements as an array, instead of as a one ugly string (`selectRaw`).

```
$query = User::query()->selectRawArr([
    'concat(`id`, "-", `name`) as id_name',
    'concat(`email`, "-", `name`) as email_name'
]);
// 🤩

$query->first()->toArray(); // ["id_name" => "1-Matti", "email_name" => "matti@suoraniemi.com-Matti"]

// Instead of:
$query = User::query()->selectRaw('concat(`id`, "-", `name`) as id_name, concat(`email`, "-", `name`) as email_name');
// 🤢
```

### `Illuminate\Support\Collection`

[](#illuminatesupportcollection)

#### `Collection::mergeMany`

[](#collectionmergemany)

Merge multiple arrays/collections to the collection in one go.

```
$data = new Collection([1,2,3]);

$data->mergeMany([4], [5], [6]); // [1, 2, 3, 4, 5, 6]
```

#### `Collection::pick` (was `pluckMany`)

[](#collectionpick-was-pluckmany)

Pick several keys from the collection items. The first value should be an array of keys you want to pick up from the collection items. The second value determines whether keys will be preserved and in which format:

- `PICK_WITH_FULL_KEYS (>= 2)`:
    - Keeps even the possibly nested values in their original depths.
- `PICK_WITH_PARTIAL_KEYS (1)`:
    - Flattens the results while keeping the keys.
- `PICK_WITHOUT_KEYS (0)`:
    - No keys will be preserved

```
$data = User::query()->get();

$data->pick(['id', 'name', 'metadata.loggedIn'])->toArray();
// [[1, "Matti Suoraniemi", true], [2, "Foo Bar", false]]

$data->pick(['id', 'name', 'metadata.loggedIn'], 1)->toArray();
// [
//   ["id" => 1, "name" => "Matti Suoraniemi", "loggedIn" => true],
//   ["id" => 2, "name" => "Foo Bar", "loggedIn" => false]
// ]

$data->pick(['id', 'name', 'metadata.loggedIn'], 2)->toArray();
// [
//   ["id" => 1, "name" => "Matti Suoraniemi", "metadata" => ["loggedIn" => true]],
//   ["id" => 2, "name" => "Foo Bar", "metadata" => ["loggedIn" => false]]
// ]
```

#### `Collection::whereExtends`

[](#collectionwhereextends)

Filter classes and/or objects that extend the given class.

```
use Illuminate\Database\Eloquent\Model;

$data = new Collection([
    \App\Models\User::class,
    \App\Models\Game::class,
    \App\Models\Console::class,
    \App\Models\Hobby::class,
]);

$data->whereExtends(Model::class)->count(); // 4
```

#### `Collection::whereImplements`

[](#collectionwhereimplements)

Filter classes and/or objects that implement the given interface.

```
use App\Contracts\PlayableOnConsole;

$data = new Collection([
    \App\Models\User::class,
    \App\Models\Game::class,
    \App\Models\Console::class,
    \App\Models\Hobby::class,
]);

$data->whereImplements(PlayableOnConsole::class)->toArray(); // ["App\Models\Game"]
```

#### `Collection::whereUses`

[](#collectionwhereuses)

Filter classes and/or objects that use the given trait.

```
use Illuminate\Notifications\Notifiable;

$data = new Collection([
    \App\Models\User::class,
    \App\Models\Game::class,
    \App\Models\Console::class,
    \App\Models\Hobby::class,
]);

$data->whereUses(Notifiable::class)->toArray(); // ["App\Models\User"]
```

### `Illuminate\Support\Arr`

[](#illuminatesupportarr)

#### `Arr::associate`

[](#arrassociate)

Converts an array into a fully associative array by converting any values with an integer key to the value being the key filled with the given fill value. Values that have a string key already won't be touched.

```
Arr::associate(['foo']); // ["foo" => null]
Arr::associate(['foo', 'bar' => []], []); // ["foo" => [], "bar" => []]
Arr::associate(['foo', 'bar' => []], fn () => Arr::random(['foo', 'bar'])); // ["foo" => "foo", "bar" => []]
Arr::associate([fn () => Str::reverse('foo'), 'bar' => []]); // ["oof" => null, "bar" => []]
```

#### `Arr::combine`

[](#arrcombine)

Similar to `array_combine`, but allows to have more keys than values. Keys without value will be set as null.

```
Arr::combine(['foo', 'zoo'], ["bar", "gar"]); // ["foo" => "bar", "zoo" => "gar"]
Arr::combine(['foo', 'zoo'], ["bar"]); // ["foo" => "bar", "zoo" => null]
```

#### `Arr::fillKeys`

[](#arrfillkeys)

Fills given keys with given value. You can also set that only keys that already exist in the array can become filled. In other words, if the key `foo` is to be filled with value `bar`, but the key `foo` doesn't already exist in the array, the array will remain unchanged.

```
$array = ['foo' => 'bar', 'zoo' => 'gar'];

Arr::fillKeys($array, ['foo', 'zoo'], null); // ["foo" => null, "zoo" => null]
Arr::fillKeys($array, ['foo', 'zoo', 'boo'], null); // ["foo" => null, "zoo" => null, "boo" => null]
Arr::fillKeys($array, ['foo', 'zoo', 'boo'], null, true); // ["foo" => null, "zoo" => null]
```

#### `Arr::implode`

[](#arrimplode)

Implodes given array with given separator to a `\Illuminate\Support\Stringable` instance.

```
$array = ['foo', 'bar'];

(string) Arr::implode($array, ' ')->upper(); // "FOO BAR"
```

#### `Arr::join`

[](#arrjoin)

Collection's nice join method brought to Arr.

```
Arr::join(['foo', 'bar', 'zoo'], ', ', ' and '); // "foo, bar and zoo"
```

#### `Arr::zip`

[](#arrzip)

Zips the key and value together with the given zipper.

```
Arr::zip(['foo' => 'bar', 'zoo' => 'gar'], ':'); // ["foo:bar", "zoo:gar"]
```

#### `Arr::unzip`

[](#arrunzip)

Unzips keys to key and value with the given zipper.

```
Arr::unzip(['foo:bar', 'zoo:gar'], ':'); // ["foo" => "bar", "zoo" => "gar"]
```

#### `Str::explodeReverse`

[](#strexplodereverse)

Explodes the given string from the end instead of the start and returns it as a `Illuminate\Support\Collection` class instance.

```
Str::explodeReverse('games.platforms.name', '.', 2)->toArray(); // ['games.platforms', 'name']

// Whereas normal explode function would do:
explode('.', 'games.platforms.name', 2); // ['games', 'platforms.name']
```

### `Illuminate\Support\Str`

[](#illuminatesupportstr)

#### `Str::wrapWith`

[](#strwrapwith)

Wraps the string with given character(s).

```
Str::wrapWith('foo', ':'); // ":foo:"
Str::wrapWith('bar', ''); // ""
Str::wrapWith('!zoo', '!'); // "!zoo!"
```

> ⚠️ As Laravel 9 introduced `Str::wrap` macro, as of v4.0 this macro is now called `Str::wrapWith` to avoid conflicts. Note: the behavior between these two macros is different:

```
Str::wrapWith(':foo', ':'); // ":foo:"
Str::wrap(':foo', ':'); // "::foo:"
```

### `Illuminate\Support\Stringable`

[](#illuminatesupportstringable)

#### `Stringable::explodeReverse`

[](#stringableexplodereverse)

> ⚠️ This macro relies on `Str::explodeReverse` macro. If you want to disable that macro, this macro will no longer function.

See [Illuminate\\Support\\Str::explodeReverse](#illuminatesupportstrexplodereverse)

```
Str::of('games.platforms.name')->explodeReverse('.', 2)->toArray(); // ['games.platforms', 'name']

// Whereas normal explode function would do:
Str::of('games.platforms.name')->explode('.', 2)->toArray(); // ['games', 'platforms.name']
```

#### `Stringable::wrapWith`

[](#stringablewrapwith)

> ⚠️ As Laravel 9 introduced `Str::wrap` macro, as of v4.0 this macro is now called `Str::wrapWith` to avoid conflicts.

> ⚠️ This macro relies on `Str::wrapWith` macro. If you want to disable that macro, this macro will no longer function.

See [Illuminate\\Support\\Str::wrapWith](#strwrapwith)

```
(string) Str::of('foo')->upper()->wrapWith(':'); // ":FOO:"
(string) Str::of('bar')->upper()->wrapWith(''); // ""
(string) Str::of('!zoo')->upper()->wrapWith('!'); // "!ZOO!"
```

### `Carbon\CarbonPeriod`

[](#carboncarbonperiod)

#### `CarbonPeriod::collect`

[](#carbonperiodcollect)

```
$dates = CarbonPeriod::between('yesterday', 'today')->collect();

$dates->first()->toDateTimeString(); // "2022-06-14 00:00:00"
```

License
-------

[](#license)

Lyhty Macros is open-sourced software licensed under the [MIT license](LICENSE).

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance48

Moderate activity, may be stable

Popularity12

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 100% 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 ~48 days

Recently: every ~140 days

Total

22

Last Release

390d ago

Major Versions

v1.x-dev → v2.0.02022-08-10

v2.x-dev → v3.0.02022-08-10

v3.x-dev → v4.0.02023-10-06

v4.x-dev → v5.0.02023-10-09

v5.1.0 → v6.0.02025-04-22

PHP version history (6 changes)v1.0.0PHP ^7.4|^8.0

v3.2.0PHP ^7.4 | ^8.0

v4.0.0PHP ^8.0

v5.0.0PHP ^8.1

v5.1.0PHP ^8.1 | ^8.2

v6.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/2cd5d6f2caaea83278fd1552c5bdc1b30b4164890ba0801a718dc20efa93738c?d=identicon)[TruecapeDev](/maintainers/TruecapeDev)

---

Top Contributors

[![sirmathays](https://avatars.githubusercontent.com/u/37704147?v=4)](https://github.com/sirmathays "sirmathays (49 commits)")

---

Tags

collectioneloquentlaravelmacroablemacroslaravelmacro

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/lyhty-macros/health.svg)

```
[![Health](https://phpackages.com/badges/lyhty-macros/health.svg)](https://phpackages.com/packages/lyhty-macros)
```

###  Alternatives

[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[laravel-doctrine/orm

An integration library for Laravel and Doctrine ORM

8425.3M87](/packages/laravel-doctrine-orm)[clickbar/laravel-magellan

This package provides functionality for working with the postgis extension in Laravel.

423715.4k1](/packages/clickbar-laravel-magellan)[cybercog/laravel-clickhouse

ClickHouse migrations for Laravel

163166.8k](/packages/cybercog-laravel-clickhouse)[baril/bonsai

An implementation of the Closure Tables pattern for Eloquent.

3593.5k](/packages/baril-bonsai)[toponepercent/baum

Baum is an implementation of the Nested Set pattern for Eloquent models.

3154.7k](/packages/toponepercent-baum)

PHPackages © 2026

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