PHPackages                             wpdesk/wp-persistence - 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. wpdesk/wp-persistence

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

wpdesk/wp-persistence
=====================

3.0.2(4y ago)048.1k↓44.7%13PHPPHP &gt;=7.0CI failing

Since Feb 1Pushed 1mo agoCompare

[ Source](https://github.com/WP-Desk/wp-persistence)[ Packagist](https://packagist.org/packages/wpdesk/wp-persistence)[ RSS](/packages/wpdesk-wp-persistence/feed)WikiDiscussions master Synced 2w ago

READMEChangelogDependencies (6)Versions (19)Used By (13)

WP Desk Persistence Library
===========================

[](#wp-desk-persistence-library)

The WP Desk Persistence Library is a robust, lightweight PHP utility designed for WordPress and WooCommerce environments. It abstracts and unifies access to different persistence layers under a clean, consistent interface. By extending the PSR-11 container standards, it enables seamless reading, writing, and deletion of data across arrays, databases, post meta, transients, and WooCommerce sessions.

The library also provides decorators to optimize performance through deferred writes (batch saving) and automatic serialization.

Key Features
------------

[](#key-features)

- **PSR-11 Compliance**: Extends `psr/container` to ensure standards compatibility and ease of dependency injection.
- **Unified Interface**: Write and delete values using a single, clear API regardless of whether the backend is an option, transient, post metadata, or WooCommerce session.
- **Multiple Adapters**: Out-of-the-box support for:
    - In-memory arrays and references.
    - WordPress Options, Transients, and Post Meta.
    - WooCommerce Sessions, Settings APIs, and Shipping Methods.
- **Performance-Oriented Decorators**:
    - Delayed writes to queue database updates in memory before applying them in a single batch operation.
    - Serialization wrappers to safely store complex structures like arrays or objects in simple scalar database options.
- **Robust Exception Handling**: Transparently maps lookup failures to PSR-compliant exceptions and supports fallback values.

Requirements
------------

[](#requirements)

The minimum system requirements read from composer.json are:

- **PHP Version**: `7.0` or higher
- **Key Libraries**:
    - `psr/container`: `~1.0.0`
- **WordPress Environment**: Recommended when using WordPress adapters.
- **WooCommerce Environment**: Required when using WooCommerce-specific session or settings adapters.

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

[](#installation)

Install the library using Composer:

```
composer require wpdesk/wp-persistence
```

### Autoloader Compatibility

[](#autoloader-compatibility)

To ensure that the correct version of the library is loaded in WordPress environments where multiple plugins might bundle different versions of the same dependency, it is highly recommended to use [wpdesk/wp-autoloader](https://github.com/wpdesk/wp-autoloader).

```
// Standard Composer autoloader initialization
require_once 'vendor/autoload.php';
```

Usage
-----

[](#usage)

Below are examples demonstrating how to use the different containers and decorators in this package.

### Basic CRUD Operations

[](#basic-crud-operations)

You can use WordpressOptionsContainer to store basic configuration values.

```
use WPDesk\Persistence\Adapter\WordPress\WordpressOptionsContainer;

// Initialize the option-backed container with an optional namespace prefix
$container = new WordpressOptionsContainer('my_plugin_');

// Save a scalar value
$container->set('api_key', 'xyz123abc');

// Check if a value exists
if ($container->has('api_key')) {
    // Retrieve the value
    $apiKey = $container->get('api_key');
}

// Safely get a value with a fallback default without throwing exceptions
$timeout = $container->get_fallback('request_timeout', 30);

// Delete a key
$container->delete('api_key');

// Setting a value to null also deletes it
$container->set('api_key', null);
```

### Transparent Serialization

[](#transparent-serialization)

Standard WordPress options cannot store complex structures natively without manual serialization. The SerializedPersistentContainer automates this process.

```
use WPDesk\Persistence\Adapter\WordPress\WordpressOptionsContainer;
use WPDesk\Persistence\Decorator\SerializedPersistentContainer;

$baseContainer = new WordpressOptionsContainer('plugin_settings_');
$serializedContainer = new SerializedPersistentContainer($baseContainer);

$settings = [
    'notifications' => true,
    'retry_limit' => 5,
    'allowed_types' => ['post', 'page']
];

// Stores serialized data under option 'plugin_settings_config'
$serializedContainer->set('config', $settings);

// Automatically unserializes to a PHP array on retrieval
$retrievedSettings = $serializedContainer->get('config');
```

### Deferred Writes (Delaying DB Queries)

[](#deferred-writes-delaying-db-queries)

To avoid executing a database query on every `set` or `delete` call, wrap your container in DelayPersistentContainer. This implements the DeferredPersistentContainer interface.

```
use WPDesk\Persistence\Adapter\WordPress\WordpressOptionsContainer;
use WPDesk\Persistence\Decorator\DelayPersistentContainer;

$options = new WordpressOptionsContainer('user_pref_');
$deferred = new DelayPersistentContainer($options);

// Changes are kept in memory and do not query the database yet
$deferred->set('theme', 'dark');
$deferred->set('sidebar_collapsed', true);
$deferred->delete('old_temporary_flag');

if ($deferred->is_changed()) {
    // Persist all queued memory modifications to the database at once
    $deferred->save();
}

// Discard all unsaved memory adjustments
$deferred->reset();
```

### Delayed Persistence to a Single Unified Value

[](#delayed-persistence-to-a-single-unified-value)

To store multiple distinct settings keys as key-value pairs inside a single database field, use DelaySinglePersistentContainer. It implements AllDataAccessContainer.

```
use WPDesk\Persistence\Adapter\WordPress\WordpressOptionsContainer;
use WPDesk\Persistence\Decorator\DelaySinglePersistentContainer;

$options = new WordpressOptionsContainer();

// All keys manipulated here will end up in a single serialized option named 'my_plugin_unified_settings'
$singleOptionContainer = new DelaySinglePersistentContainer($options, 'my_plugin_unified_settings');

$singleOptionContainer->set('enabled', true);
$singleOptionContainer->set('debug_mode', false);

// Writes a single serialized array containing all values to the option
$singleOptionContainer->save();

// Read all key-value pairs
$allSettings = $singleOptionContainer->get_all();
```

### Reference Array Persistence

[](#reference-array-persistence)

You can bind a container to a referenced PHP array via ReferenceArrayContainer. Manipulating the container alters the reference target directly.

```
use WPDesk\Persistence\Adapter\ReferenceArrayContainer;

$settingsArray = [];
$container = new ReferenceArrayContainer($settingsArray);

$container->set('option_a', 'value_a');

// $settingsArray now contains ['option_a' => 'value_a']
```

### WooCommerce Session Container

[](#woocommerce-session-container)

Store values directly inside the WooCommerce customer session using WooCommerceSessionContainer.

```
use WPDesk\Persistence\Adapter\WooCommerce\WooCommerceSessionContainer;

if (null !== WC()->session) {
    $sessionContainer = new WooCommerceSessionContainer(WC()->session);

    // Save temporary state for the user's cart or session
    $sessionContainer->set('selected_delivery_window', 'morning');

    $window = $sessionContainer->get('selected_delivery_window');
}
```

Value Resolution Table
----------------------

[](#value-resolution-table)

This table illustrates the responses of `has()` and `get()` for various types of values stored in the containers.

Stored ValueGet ResultHas Result`'test'``'test'``true``[]``[]``true``''``''``true``99``99` (or string `'99'`)`true``0``0` (or string `'0'`)`true``true``true` (or string `'1'`)`true``false``false` (or empty string `''`)`true`*not set*Throws ElementNotExistsException`false``null`Throws ElementNotExistsException`false`Backward Compatibility / Legacy APIs
------------------------------------

[](#backward-compatibility--legacy-apis)

When upgrading the library, please note the following legacy changes and structural updates:

### Upgrading to 3.0.0

[](#upgrading-to-300)

- **Null Handling**: Historically, setting a key to `null` stored the literal value `null`. Since version 3.0.0, passing `null` to `set()` is treated as a removal operation, invoking `delete()`. Calling `get()` or `has()` on a key that was set to `null` will throw an ElementNotExistsException and return `false`, respectively.
- **Interface Methods**: The PersistentContainer interface now requires the `get_fallback` method. Custom implementations of this interface must define this method or consume FallbackFromGetTrait.

### Upgrading to 2.0.0

[](#upgrading-to-200)

- **Namespace Standardization**: The root namespace path was standardized. The segment `Wordpress` was renamed to `WordPress`. Ensure your class use-statements and configuration namespaces are updated to utilize `WPDesk\Persistence\Adapter\WordPress\`.
- **Class Renaming**: The class `MemoryContainer` was deprecated and renamed to ArrayContainer. Change all references of `MemoryContainer` to ArrayContainer.

Running Tests
-------------

[](#running-tests)

Unit and integration tests are configured using PHPUnit. The test suites are defined in phpunit-unit.xml and phpunit-integration.xml.

You can execute the test suites using the following Composer commands:

### Unit Tests

[](#unit-tests)

```
# Run unit tests with coverage reporting
composer phpunit-unit

# Run unit tests quickly without code coverage
composer phpunit-unit-fast
```

### Integration Tests

[](#integration-tests)

```
# Run integration tests with coverage reporting
composer phpunit-integration

# Run integration tests quickly without code coverage
composer phpunit-integration-fast
```

License
-------

[](#license)

This library is licensed under the MIT License. See LICENSE.md for details.

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance58

Moderate activity, may be stable

Popularity27

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity65

Established project with proven stability

 Bus Factor1

Top contributor holds 58.8% 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 ~116 days

Recently: every ~164 days

Total

11

Last Release

1591d ago

Major Versions

1.0 → 2.0-beta2020-03-10

2.1.4 → 3.02021-01-18

PHP version history (2 changes)1.0PHP &gt;=5.6

3.0PHP &gt;=7.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/16497f8884c0767d3a114cc1cf8daaa639bac052178b03c59d59dfa95569d50b?d=identicon)[dyszczo](/maintainers/dyszczo)

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

![](https://www.gravatar.com/avatar/97ac8b53a77161e994c106cc2136cf0601d404e5fd4a3295884d692c767636c7?d=identicon)[bjaskulski](/maintainers/bjaskulski)

![](https://www.gravatar.com/avatar/8e4b1bce6dad69911f85ab3abc19f8432db4a34a3b8a27043b90e82eab83e506?d=identicon)[eryk.mika](/maintainers/eryk.mika)

---

Top Contributors

[![dyszczo](https://avatars.githubusercontent.com/u/1263190?v=4)](https://github.com/dyszczo "dyszczo (20 commits)")[![potreb](https://avatars.githubusercontent.com/u/2514438?v=4)](https://github.com/potreb "potreb (10 commits)")[![bart-jaskulski](https://avatars.githubusercontent.com/u/56613051?v=4)](https://github.com/bart-jaskulski "bart-jaskulski (3 commits)")[![Astronneu](https://avatars.githubusercontent.com/u/52426037?v=4)](https://github.com/Astronneu "Astronneu (1 commits)")

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/wpdesk-wp-persistence/health.svg)

```
[![Health](https://phpackages.com/badges/wpdesk-wp-persistence/health.svg)](https://phpackages.com/packages/wpdesk-wp-persistence)
```

###  Alternatives

[symfony/dependency-injection

Allows you to standardize and centralize the way objects are constructed in your application

4.2k464.3M10.6k](/packages/symfony-dependency-injection)[illuminate/contracts

The Illuminate Contracts package.

707133.3M15.2k](/packages/illuminate-contracts)[illuminate/container

The Illuminate Container package.

31083.8M2.5k](/packages/illuminate-container)[api-platform/core

Build a fully-featured hypermedia or GraphQL API in minutes!

2.6k52.2M377](/packages/api-platform-core)[ecotone/ecotone

Enterprise architecture layer for Laravel and Symfony — CQRS, Event Sourcing, Durable Workflows (Sagas, Orchestrators), Projections, and Outbox messaging via PHP attributes.

568591.1k63](/packages/ecotone-ecotone)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

762297.9k53](/packages/civicrm-civicrm-core)

PHPackages © 2026

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