Download the PHP package sirix/redaction without Composer
On this page you can find all versions of the php package sirix/redaction. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download sirix/redaction
More information about sirix/redaction
Files in sirix/redaction
Package redaction
Short Description PHP library for data redaction, masking, and sanitization with optional Monolog integration.
License MIT
Informations about the package redaction
Redaction
A PHP library for data redaction, masking, and sanitization with optional Monolog and Mezzio/Laminas integration.
This library provides a small core that can redact sensitive data in arrays and objects using pluggable rules. You can use it anywhere in your app (HTTP payloads, DTOs, database debug dumps, etc.), and optionally plug it into Monolog via a tiny bridge. For framework users, a PSR‑11 factory and a Mezzio/Laminas ConfigProvider are included.
- PHP 8.2–8.5
- Optional:
ext-intl(forUnicodeStartEndRuleonly) - Optional: Monolog ^3.0 (for the bridge only)
- Optional: Mezzio/Laminas (for auto‑wiring via ConfigProvider)
- License: MIT
Installation
Install the core library:
Quick start (core library)
Optional: Monolog integration
Example output (stdout):
Note: Exact output format depends on your handler/formatter. The masking shown reflects the default rules plus the ones configured above.
The Monolog processor redacts LogRecord::context only. It does not redact message or extra by default.
Framework/DI integration (Mezzio/Laminas, PSR‑11)
This package ships with:
- A PSR‑11 factory:
Sirix\Redaction\Factory\RedactorFactory - A Mezzio/Laminas config provider:
Sirix\Redaction\Bridge\Mezzio\ConfigProvider
With Laminas/Mezzio, you can wire the service automatically via the ConfigProvider. Add the provider to your application config if not discovered automatically:
Then type‑hint RedactorInterface in your services/controllers, and let the container inject it. In 2.0, this interface is intentionally small and exposes only redact():
If you are not using Mezzio/Laminas, register the factory in your PSR‑11 container of choice, passing the redactor.options structure as shown above.
The PSR-11 factory uses sirix/container-resolver and reads configuration strictly. Existing invalid values throw configuration/container exceptions instead of being silently ignored or coerced. For example, use 5000, not '5000', for integer limits.
Production safety
When redacting untrusted or large payloads, especially in logging pipelines, configure traversal limits:
Without limits, the redactor walks the full input structure. When maxItemsPerContainer is exceeded, containers are truncated and an overflow placeholder is appended ('...' by default). When maxTotalNodes is exceeded, traversal stops after the first exceeded node and any remaining siblings are omitted/truncated.
Object cycles are detected in object-processing modes. PHP array reference cycles should be guarded with maxDepth.
Long-running applications
The redactor is safe to reuse as a shared service when it is fully configured at bootstrap time. In 2.0, runtime traversal state is kept per redact() call, and configuration is represented by immutable RedactorOptions. Fluent with* methods are convenience helpers that return a configured copy; calling them without assigning the return value leaves the original instance unchanged.
Do not store request/job-specific closures on a shared redactor. Limit callbacks configured on shared services should be stateless or backed by long-lived services. If request-specific behavior is required, create a separate configured instance/copy for that request or job.
For untrusted payloads in RoadRunner, Swoole/OpenSwoole, ReactPHP/Amp, queue workers, or persistent Mezzio/Laminas apps, configure traversal limits.
Memory optimization
The Redactor uses a copy-on-write traversal strategy:
- No copying by default for unchanged scalars/arrays and skipped objects: When no rules apply to an array branch, the original array branch is returned as-is, avoiding unnecessary copies.
- Lazy array copying: Arrays are copied only when a change is first detected. A target array is created only upon the first modified element.
- Explicit object projection: In Copy mode, objects are projected to a plain
stdClasscopy. In PublicArray mode, objects are projected to an array of public properties. The default Skip mode avoids traversing object properties. - Immutability preserved: The top-level input you pass to redact() is never mutated. When changes occur, they are applied to the lazily created copies.
- Limits and cycles: Depth/item/node limits and object cycle detection are applied during traversal. When a limit is hit, the overflow placeholder is used for truncated parts by default.
This reduces peak memory usage when little or no redaction occurs while keeping input data immutable.
How it works
- The redactor recursively walks through scalars in your data and applies a rule when a key matches.
- A top-level scalar has no key and is returned unchanged.
- For arrays, the same flat rules map is used at every depth; rules match by key name regardless of nesting. Nested per-path rule maps are not supported.
- Objects are handled according to an object view mode (default: Skip):
- Copy: returns a plain stdClass copy and recursively processes both public and non-static private/protected properties.
- PublicArray: returns an array of public properties only.
- Skip: replaces the object with a compact string like "[object Foo\Bar]" and does not traverse properties.
- Object cycles are detected. When depth/item/node limits are exceeded, an optional callback is invoked and the overflow placeholder is used to replace or mark truncated parts. If
overflowPlaceholderisnull, exceeded branches are replaced withnulland truncated containers omit the marker instead of returning raw unprocessed data. Limit callbacks are best-effort: exceptions thrown by callbacks are ignored so redaction does not fail open. For array reference cycles, configuremaxDepth.
Default rules
By default, the core Redactor loads a curated set of rules for common sensitive fields (card numbers/PAN, CVV, expiry, names, emails, phone, IPs, addresses, tokens, 3‑D Secure fields, etc.). See src/Rule/Default/DefaultRules.php for the complete list.
To disable default rules and use only your own:
Built‑in rule types
These rules live under Sirix\Redaction\Rule and can be created directly or via factory helpers:
StartEndRule($visibleStart, $visibleEnd)- available viaSharedRuleFactory::startEnd($visibleStart, $visibleEnd). Masks the middle part of a string, keeping the given number of bytes at the start/end.EmailRuleavailable viaSharedRuleFactory::email(). Masks the local part of an email, keeping the first 3 characters and the full domain.PhoneRuleavailable viaSharedRuleFactory::phone(). Masks digits in the middle of a phone number, keeping the first 4 and last 2 digits when possible.FullMaskRuleavailable viaSharedRuleFactory::fullMask(). Replaces the entire value with the replacement character(s).FixedValueRule($replacement)available viaSharedRuleFactory::fixedValue($replacement). Always outputs the provided constant string (e.g.,*or**/****).NameRuleavailable viaSharedRuleFactory::name(). Masks personal names leaving just initials and/or a few characters as defined by the rule.NullRuleavailable viaSharedRuleFactory::null(). Sets the value to null.OffsetRule($offset)available viaSharedRuleFactory::offset($offset). Masks the first N bytes (from the start) according to the offset.UnicodeStartEndRule($visibleStart, $visibleEnd)available viaSharedRuleFactory::unicodeStartEnd($visibleStart, $visibleEnd). Opt-in grapheme-aware variant for Unicode strings; requiresext-intl.
Shared rule factory (optional)
For convenience, you can use factory helpers:
Default rules and helper methods return fresh rule instances, avoiding static rule caches in long-running processes.
Regex key matcher performance guidance
Regex key matchers are evaluated only when they are configured. Existing exact-key/default-rule setups keep the exact-map fast path and do not pay regex matching overhead.
When matchers are configured, rule resolution is linear in the number of matchers for each scalar keyed value that does not match a custom exact rule first:
For best performance and predictable latency:
- Prefer exact-key rules for known stable keys.
- Keep the matcher list short; each additional matcher can add a
preg_match()call per scalar key. -
Combine related sensitive-key alternatives into one regex instead of several separate matchers:
- Put highly specific exact custom rules in the string-keyed map; exact custom rules are checked before matchers.
- Avoid broad or pathological regex patterns on very large payloads. Regex patterns are validated at matcher construction time, but expensive valid patterns can still affect runtime.
- Use traversal limits (
max_depth,max_items_per_container,max_total_nodes) for untrusted or very large inputs. - Benchmark representative payloads before adding many matchers to hot paths such as high-volume logging.
If you need a custom masking strategy, implement RedactionRuleInterface. Rules receive a dedicated immutable RedactionRuleContextInterface snapshot with rule-level options (replacement, template, and lengthLimit) instead of the full redactor service:
Redactor options
For bootstrap/container configuration, prefer immutable RedactorOptions:
For local variations, use immutable with* methods:
withReplacement(string $char): character(s) used to construct masks (default*).withTemplate(string $template): a safesprintftemplate applied to the mask string (default'%s'). It must contain exactly one plain%s; width specifiers and multiple placeholders are rejected.withLengthLimit(?int $limit): if set, truncates built-in rule output to at most this many bytes. Mask-building rules avoid creating unnecessarily large intermediate masks when this limit is set.UnicodeStartEndRuleinterprets the same value as grapheme characters.withObjectViewMode(ObjectViewModeEnum $mode): how to represent objects during redaction. Defaults toObjectViewModeEnum::Skip.withMaxDepth(?int $depth): maximum recursion depth for arrays/objects.nullmeans unlimited.withMaxItemsPerContainer(?int $count): limit the number of items per array/object. When exceeded, the container is truncated and an overflow placeholder is appended if configured.withMaxTotalNodes(?int $count): global cap on visited nodes (array elements, object properties, child nodes). Once exceeded, traversal stops after the first exceeded node.nullmeans unlimited.withOnLimitExceededCallback(?callable $cb): callback invoked when any limit is hit, a cycle is detected, or a matched rule throws. Receives an info array with keys liketype,depth,nodesVisited, and context-specific fields. Callback exceptions are ignored to keep redaction fail-closed.withOverflowPlaceholder(?string $value): value used to replace or mark truncated parts when limits are exceeded. Defaults to'...'; passnullto omit overflow markers while replacing exceeded branches withnull.
Notes:
- These options influence built-in rules and the core traversal/limit behavior.
- If a matched rule throws, the sensitive value is replaced with
overflowPlaceholderornullwhen placeholders are disabled. - Limits apply to arrays and objects uniformly; object cycles are detected to avoid infinite recursion.
Unicode and multibyte strings
The default built-in rules are byte-oriented. They use PHP byte-level operations such as strlen() and substr(), and lengthLimit is a byte limit. This keeps masking fast and predictable for logs, tokens, card numbers, IDs, emails, and other operational fields, but it can split multibyte UTF-8 characters when used on free text or human names.
For Unicode text, use UnicodeStartEndRule explicitly:
UnicodeStartEndRule uses grapheme-aware intl functions, so its visible counts and lengthLimit are measured in user-perceived characters. It requires the intl PHP extension and throws LogicException if the extension is unavailable.
If you need field-specific locale behavior beyond start/end masking, provide a custom RedactionRuleInterface implementation.
Testing & QA
This repository includes a PHPUnit test suite and tooling configs.
- Run tests:
composer test - Static analysis:
composer phpstan - Code style check:
composer cs-check - Auto‑fix style:
composer cs-fix
Versioning
- PHP: ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0
- Optional extension:
ext-intlforUnicodeStartEndRule - Optional Monolog: ^3.0 (for the bridge)
License
MIT © Sirix
All versions of redaction with dependencies
psr/container Version ^1.0 || ^2.0.2
sirix/container-resolver Version ^1.0