PHPackages                             timdev/array-undot - 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. timdev/array-undot

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

timdev/array-undot
==================

A utility to normalize arrays with dotted-string keys. \['a.b' =&gt; 'c'\] ==&gt; \['a' =&gt; \['b' =&gt; 'c'\]\]

0.1.2(4y ago)1143MITPHPPHP ~8.0.0 || ~8.1.0

Since Aug 20Pushed 4y ago1 watchersCompare

[ Source](https://github.com/timdev/array-undot)[ Packagist](https://packagist.org/packages/timdev/array-undot)[ RSS](/packages/timdev-array-undot/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (2)Versions (6)Used By (0)

timdev/array-undot
==================

[](#timdevarray-undot)

[![PHP Version Support](https://camo.githubusercontent.com/cf82f5db052cd02e944e34b7bb3b6090fc0f0eb7660ddbaa1894fd80247312e6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f74696d6465762f61727261792d756e646f743f7374796c653d666c6174)](https://camo.githubusercontent.com/cf82f5db052cd02e944e34b7bb3b6090fc0f0eb7660ddbaa1894fd80247312e6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f74696d6465762f61727261792d756e646f743f7374796c653d666c6174)[![License](https://camo.githubusercontent.com/e23c376af985c0a0f709922e8f632a5e4ae062ce6c0d30ad8991e6942dfa9f29/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f74696d6465762f61727261792d756e646f743f7374796c653d666c617426636f6c6f72423d6461726b6379616e)](https://camo.githubusercontent.com/e23c376af985c0a0f709922e8f632a5e4ae062ce6c0d30ad8991e6942dfa9f29/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f74696d6465762f61727261792d756e646f743f7374796c653d666c617426636f6c6f72423d6461726b6379616e)[![Latest Release](https://camo.githubusercontent.com/9a193f5ac449f875755040c249e2430c3db57e294228d258697c7d70e412c57f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f7461672f74696d6465762f61727261792d756e646f743f7374796c653d666c6174266c6162656c3d72656c65617365)](https://camo.githubusercontent.com/9a193f5ac449f875755040c249e2430c3db57e294228d258697c7d70e412c57f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f7461672f74696d6465762f61727261792d756e646f743f7374796c653d666c6174266c6162656c3d72656c65617365)[![Type Coverage](https://camo.githubusercontent.com/cd4de7c6d44d98bd564b6dc25f95c490c6db64bf9b4b135527cb70847f77a336/68747470733a2f2f73686570686572642e6465762f6769746875622f74696d6465762f61727261792d756e646f742f636f7665726167652e737667)](https://camo.githubusercontent.com/cd4de7c6d44d98bd564b6dc25f95c490c6db64bf9b4b135527cb70847f77a336/68747470733a2f2f73686570686572642e6465762f6769746875622f74696d6465762f61727261792d756e646f742f636f7665726167652e737667)[![CIStatus](https://camo.githubusercontent.com/be3210885f79ce27aae9797695ade435aa5b40b613f71a99a0d6a391e4b224c6/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f74696d6465762f61727261792d756e646f742f436f6e74696e756f7573253230496e746567726174696f6e3f7374796c653d666c6174)](https://camo.githubusercontent.com/be3210885f79ce27aae9797695ade435aa5b40b613f71a99a0d6a391e4b224c6/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f74696d6465762f61727261792d756e646f742f436f6e74696e756f7573253230496e746567726174696f6e3f7374796c653d666c6174)

What's This?
------------

[](#whats-this)

It normalizes arrays with dotted-string keys to arrays without any dotted-string keys.

For example, it turns `['a.b' => 'FOO']` into `['a' => ['b' => 'FOO']]`.

Why?
----

[](#why)

I was working on a [mezzio](https://github.com/mezzio/mezzio) project that uses [laminas-config-aggregator](https://github.com/laminas/laminas-config-aggregator) to merge a bunch of configuration data into a big nested array. Sometimes, I'd want to change a single value somewhere deep in the structure from a local config file.

```
// myapp.local.php
return [
    // sometimes it's nicer (reading and writing) to do this:
    'path.to.some.key' => 'value',

    // as opposed to this:
    'path' => [
        'to' => [
            'some' => [
                'key' => 'value'
            ]
        ]
  ]
];
```

Behavior
--------

[](#behavior)

`Undotter::undot()` recursively traverses (depth-first) its argument, building a new array as it goes.

```
use \TimDev\ArrayUndot\Undotter;

/* Example 1: The basic idea: */
Undotter::undot(['a.b' => 'FOO']);
// => ['a' => ['b' => 'FOO']]

/* Example 2: Dotted keys don't need to be at the top level: */
Undotter::undot(['top' => ['a' => ['b.c' => 'FOO']]]);
// => ['top' => ['a' => ['b' => ['c' => 'FOO']]]]

/* Example 3: Conflict-Resolution depends on the order of elements in the input: */
Undotter::undot([
    'a' => ['b' => 'FOO'],
    'a.b' => 'BAR'
]);
// => ['a' => ['b' => 'BAR']]

// ... but if the order is swapped
Undotter::undot([
    'a.b' => 'BAR',
    'a' => ['b' => 'FOO']
]);
// => ['a' => ['b' => 'FOO']]

/* Example 4:  If the conflicting values are both arrays, they're merged (using the same logic as ConfigAggregator): */
Undotter::undot([
    'a' => ['b' => ['foo' => 1, 'bar' => 2, 'baz' => 3]],
    'a.b' => ['baz' => 4, 'qux' => 5]
]);
// =>
//    [
//        'a' => [
//            'b' => [
//                'foo' => 1,
//                'bar', => 2,
//                'baz' => 4,
//                'qux' => 5
//            ]
//        ]
//    ]
```

With Laminas ConfigAggregator
-----------------------------

[](#with-laminas-configaggregator)

`Undotter` is invokable, which makes it easy to use as a post-processor with [laminas-config-aggregator](https://github.com/laminas/laminas-config-aggregator). That's handy, since it allows you to un-dot your array *before* ConfigAggregator writes its cache.

For an example, see the [testMergesSubArrays()](https://github.com/timdev/array-undot/blob/78b3bcea760f3a14510a4de3ef62de26de9ae1b1/tests/UndotterTest.php#L65-L108) test method.

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 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 ~60 days

Total

3

Last Release

1612d ago

PHP version history (3 changes)0.1.0PHP ^8.0

0.1.1PHP ~8.0.0

0.1.2PHP ~8.0.0 || ~8.1.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/4eb475c7f4d3d1df5053f83417bf4e756a35b59d1686cd7d379055da2828017f?d=identicon)[timdev](/maintainers/timdev)

---

Top Contributors

[![timdev](https://avatars.githubusercontent.com/u/513999?v=4)](https://github.com/timdev "timdev (14 commits)")

### Embed Badge

![Health badge](/badges/timdev-array-undot/health.svg)

```
[![Health](https://phpackages.com/badges/timdev-array-undot/health.svg)](https://phpackages.com/packages/timdev-array-undot)
```

###  Alternatives

[athari/yalinqo

YaLinqo, a LINQ-to-objects library for PHP

4561.2M5](/packages/athari-yalinqo)[malukenho/mcbumpface

Bumping into packages

116714.7k24](/packages/malukenho-mcbumpface)[inovector/mixpostapp

Standalone application with the Laravel Package of Mixpost Lite pre-installed and configured

1232.9k](/packages/inovector-mixpostapp)[joserick/laravel-livewire-discover

Discover and autoload multiples components of livewire by convention (componentNamespace)

2736.6k2](/packages/joserick-laravel-livewire-discover)[neysi/directprint

Easy and direct file print from PHP

218.3k](/packages/neysi-directprint)

PHPackages © 2026

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