PHPackages                             loilo/simple-config - 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. loilo/simple-config

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

loilo/simple-config
===================

Simple persistent configuration for your app or module

1.1.0(6y ago)1101[1 PRs](https://github.com/loilo/simple-config/pulls)MITPHPPHP &gt;= 7.1

Since Jul 23Pushed 5y agoCompare

[ Source](https://github.com/loilo/simple-config)[ Packagist](https://packagist.org/packages/loilo/simple-config)[ RSS](/packages/loilo-simple-config/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependencies (12)Versions (3)Used By (0)

 [![Simple Config logo: two interleaved gears, representing a typical "settings" icon](simple-config.svg)](simple-config.svg)

Simple Config
=============

[](#simple-config)

[![Tests](https://camo.githubusercontent.com/a2c680422a787ed31938770b79b9ce2fc3a3fcf3339865ab078e3faf11ca445d/68747470733a2f2f62616467656e2e6e65742f6769746875622f636865636b732f6c6f696c6f2f73696d706c652d636f6e6669672f6d6173746572)](https://github.com/loilo/simple-config/actions)[![Version on packagist.org](https://camo.githubusercontent.com/38f16d16987e2823194b630d759997db03f28b1999739df77645679580157522/68747470733a2f2f62616467656e2e6e65742f7061636b61676973742f762f6c6f696c6f2f73696d706c652d636f6e666967)](https://packagist.org/packages/loilo/simple-config)

> Simple persistent configuration for your app or module, heavily inspired by Sindre Sorhus' [conf](https://www.npmjs.com/package/conf) package.

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

[](#installation)

```
composer require loilo/simple-config
```

Usage
-----

[](#usage)

```
use Loilo\SimpleConfig\Config;

$config = new Config();

$config->set('foo', 'bar');
$config->get('foo') === 'bar';

// Use dot notation to access nested options
$config->set('baz.qux', true);
$config->get('baz') === [ 'qux' => true ];

$config->delete('foo');
$config->get('foo') === null;
```

### Methods

[](#methods)

There are four methods on the `Config` object that you may use to work with the data store — `get`, `set`, `has` and `delete`:

- To **check for presence of an option**, use `has`:

    ```
    $config->has('option')
    ```
- To **read an option**, use `get`:

    ```
    $config->get('option')
    ```

    You may also pass a second argument to use as a fallback if the option is not found (defaults to `null`):

    ```
    $config->get('nonexistent_option', 'fallback value')
    ```
- To **read the whole configuration**, use `get` with no arguments:

    ```
    $config->get()
    ```
- To **write an option** (immediately synced with the config file), use `set`:

    ```
    $config->set('option', 'value')
    ```
- To **write multiple options**, use `set` with an associative array:

    ```
    $config->set([
        'option-1' => 'value-1',
        'option-2' => 'value-2'
    ])
    ```
- To **remove an option**, use `delete`:

    ```
    $config->delete('option')
    ```
- To **clear the config file**, use `delete` with no arguments:

    ```
    $config->delete()
    ```

### Static Access

[](#static-access)

Since app-wide configuration usually only ever requires one `Config` instance, you may not want to manually pass around that instance everywhere.

In most frameworks, a dependency injection container solves this task for you. However, for cases where no such mechanism is set up, this package provides the `StaticConfig` class.

It's an abstract class which you can extend in your project. The only thing you have to provide is a method to actually create a `Config` object. The simplest possible implementation therefore looks like this:

```
use Loilo\SimpleConfig\StaticConfig;
use Loilo\SimpleConfig\Config;

class AppConfig extends StaticConfig
{
    public static function createConfig(): Config
    {
        return new Config();
    }
}
```

Now you can work with your configuration like this:

```
AppConfig::set('foo', 'bar');
AppConfig::get('foo') === 'bar';
```

### Options

[](#options)

The `Config` object can be initialized with an associative array of options documented below.

```
$config = new Config([
  // options go here
]);
```

### `defaults`

[](#defaults)

**Type:** `array`
**Default:** `null`

Default values for config items

> **Note 1:** Default values are applied with shallow (not recursive) merging: only missing *top level* options in the data are supplemented by defaults.
>
> **Note 2:** Defaults are never written to the config file so if you change your app's defaults and users have not overridden them explicitly, they will also change for all users.

### `schema`

[](#schema)

**Type:** `array`
**Default:** `null`

A [JSON Schema](https://json-schema.org) to validate your config data. [JSON Schema draft-07](http://json-schema.org/latest/json-schema-validation.html) is used as far as it's supported by the underlying [validator package](https://github.com/justinrainbow/json-schema).

> **Note 1:** Your top-level schema definition is enforced to be of `"type": "object"`.
>
> **Note 2:** Default values defined in your schema are applied during validation, but are not returned when requested via `Config::get()`. This is a limitation of the underlying validator, as there's currently no JSON schema validator in PHP that applies default values to validated data and then allows access to them.
>
> **Note 3:** If your schema defines any mandatory top-level fields, you'll need to provide [defaults](#defaults) that satisfy the schema. This avoids schema violation errors when initializing an empty configuration.

### `configName`

[](#configname)

**Type:** `string`
**Default:** `"config"`

Name of the config file (without extension).

Useful if you need multiple config files for your app or module (e.g. different config files between two major versions).

### `projectName`

[](#projectname)

**Type:** `string`
**Default:** The `name` field in the `composer.json` closest to where `new Config()` is called.

You only need to specify this if you don't have a `composer.json` file in your project.

### `configDir`

[](#configdir)

**Type:** `string`
**Default:** System default [user config directory](https://github.com/loilo/storage-paths#result)

The place where your config file is stored. You may override this to store configuration locally in your app's folder.

> **Note:** If you define this, the `projectName` option will be ignored.

### `format`

[](#format)

**Type:** `array`

Settings regarding the configuration format. This is an associative array with the following possible keys:

- `serialize`

    **Type:** `callable`
    **Default:** `function ($data) { return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); }`

    Function to serialize the config object to a UTF-8 string when writing the config file.

    You would usually not need this, but it could be useful if you want to use a format other than JSON.
- `deserialize`

    **Type:** `callable`
    **Default:** `function ($string) {  return json_decode($string, true); }`

    Function to deserialize the config object from a UTF-8 string when reading the config file.

    You would usually not need this, but it could be useful if you want to use a format other than JSON.
- `extension`

    **Type:** `string`
    **Default:** `"json"`

    File extension of the config file. This may be reasonable to set if you changed your `serialize`/`deserialize` options.

    > **Note:** If you encrypt the configuration with a [password](#password), the config file will be saved in a binary format and this option will be ignored.

### `password`

[](#password)

**Type:** `string`
**Default:** `null`

A password to encrypt/decrypt the configuration file with. This can secure sensitive data, however it's naturally only as secure as your way of managing the password itself.

> **Note:** If you encrypt the configuration with a password, the config file will be saved in a binary format and the [`format.extension`](#format) option will be ignored.

### `dotNotation`

[](#dotnotation)

**Type:** `boolean`
**Default:** `true`

Whether to access options by dot notation.

```
$config->set([
    'foo' => [
        'bar' => [
            'foobar' => 'qux'
        ]
    ]
]);

// With dot notation enabled:
$config->get('foo.bar.foobar') === 'qux';
$config->get('foo')['bar']['foobar'] === 'qux';

// With dot notation disabled:
$config->get('foo.bar.foobar') === null;
$config->get('foo')['bar']['foobar'] === 'qux';
```

### `clearInvalidConfig`

[](#clearinvalidconfig)

**Type:** `boolean`
**Default:** `true`

If set to `true`, the configuration is cleared if reading it raises an exception of any sort:

ExceptionCause[`IOException`](https://github.com/symfony/symfony/blob/4.0/src/Symfony/Component/Filesystem/Exception/IOException.php)The config file exists but could not be read.[`EnvironmentIsBrokenException`](https://github.com/defuse/php-encryption/blob/v2.0.0/src/Exception/EnvironmentIsBrokenException.php)
[`WrongKeyOrModifiedCiphertextException`](https://github.com/defuse/php-encryption/blob/v2.0.0/src/Exception/WrongKeyOrModifiedCiphertextException.php)File decryption failed (when using a [password](#password)).[`DeserializationException`](src/Exception/DeserializationException.php)Deserialization failed (e.g. if the [deserialization function](#deserialize) changed or if someone or something meddled with the file).[`InvalidConfigException`](src/Exception/InvalidConfigException.php)The configuration is invalid according to the [schema](#schema).Enabling this option is a good default, as the config file is not intended to be hand-edited, so this usually means the config is corrupt and there's nothing your app can do about it anyway. However, if you let the user edit the config file directly, mistakes might happen and it could be useful to throw an error when the config is invalid instead of clearing it.

Disabling this option will cause the exceptions listed above to be re-thrown and handled manually.

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity55

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

Total

2

Last Release

2487d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b1da49bad9203cc40a34d975dc00c80af09452bee1da6413e2f1b8214b539675?d=identicon)[loilo](/maintainers/loilo)

---

Top Contributors

[![loilo](https://avatars.githubusercontent.com/u/1922624?v=4)](https://github.com/loilo "loilo (9 commits)")

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/loilo-simple-config/health.svg)

```
[![Health](https://phpackages.com/badges/loilo-simple-config/health.svg)](https://phpackages.com/packages/loilo-simple-config)
```

###  Alternatives

[cognesy/instructor-php

The complete AI toolkit for PHP: unified LLM API, structured outputs, agents, and coding agent control

310107.9k1](/packages/cognesy-instructor-php)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[netgen/layouts-core

Netgen Layouts enables you to build and manage complex web pages in a simpler way and with less coding. This is the core of Netgen Layouts, its heart and soul.

3689.4k10](/packages/netgen-layouts-core)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

7310.3k29](/packages/open-dxp-opendxp)[lingaro/magento2-codegen

Magento 2 Code Generator

966.5k](/packages/lingaro-magento2-codegen)

PHPackages © 2026

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