galawork / data-helpers
Framework-agnostic helpers for structured data access, mutation, and mapping using dot-notation paths with wildcards. Works with Laravel, Symfony/Doctrine, or standalone PHP.
Fund package maintenance!
event4u-app
matze4u
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 1
pkg:composer/galawork/data-helpers
Requires
- php: ^8.2
- composer-plugin-api: ^2.0
- ext-simplexml: *
Requires (Dev)
- composer/composer: ^2.0
- doctrine/collections: ^2.0|^3.0
- doctrine/orm: ^2.0|^3.0
- ergebnis/phpstan-rules: ^2.12
- fakerphp/faker: ^1.24
- graham-campbell/result-type: ^1.1
- illuminate/cache: ^9.0|^10.0|^11.0
- illuminate/database: ^9.0|^10.0|^11.0
- illuminate/http: ^9.0|^10.0|^11.0
- illuminate/support: ^9.0|^10.0|^11.0
- jangregor/phpstan-prophecy: ^2.2
- nesbot/carbon: ^2.72|^3.0
- pestphp/pest: ^2.0|^3.0
- phpat/phpat: ^0.12.0
- phpbench/phpbench: ^1.4
- phpstan/phpstan: ^2.0
- phpstan/phpstan-mockery: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- rector/rector: ^2.1
- spaze/phpstan-disallowed-calls: ^4.6
- symfony/cache: ^6.0|^7.0
- symfony/config: ^6.0|^7.0
- symfony/dependency-injection: ^6.0|^7.0
- symfony/http-foundation: ^6.0|^7.0
- symfony/http-kernel: ^6.0|^7.0
- symfony/property-access: ^6.0|^7.0
- symfony/property-info: ^6.0|^7.0
- symfony/serializer: ^6.0|^7.0
- symfony/validator: ^6.0|^7.0
- symplify/coding-standard: ^12.4
- symplify/easy-coding-standard: ^12.6
- timeweb/phpstan-enum: ^4.0
- vlucas/phpdotenv: ^5.6
Suggests
- ext-yaml: For YAML serialization support (faster, requires PECL installation)
- nesbot/carbon: Required for EnvHelper::carbon() method to parse date/time environment variables
- symfony/yaml: For YAML serialization support (pure PHP, easier to install)
README
Data Helpers
A powerful, framework-agnostic PHP library for accessing, transforming, and mapping complex nested data structures with ease.
Stop writing nested loops and array checks. Access, transform, and map complex data structures with simple, expressive syntax.
// From this messy API response... $apiResponse = [ 'data' => [ 'departments' => [ ['users' => [['email' => 'alice@example.com'], ['email' => 'bob@example.com']]], ['users' => [['email' => 'charlie@example.com']]], ], ], ]; // ...to this clean result in a few lines $accessor = new DataAccessor($apiResponse); $emails = $accessor->get('data.departments.*.users.*.email'); // ['alice@example.com', 'bob@example.com', 'charlie@example.com']
Framework-agnostic โข Works with Laravel, Symfony/Doctrine, or standalone PHP โข Zero required dependencies
๐ Full Documentation โข Getting Started โข API Reference
๐ Support the Development - Help us build better tools for the PHP community
๐ก Why Data Helpers?
๐ฏ Stop Writing Nested Loops
// โ Without Data Helpers $emails = []; foreach ($data['departments'] ?? [] as $dept) { foreach ($dept['users'] ?? [] as $user) { if (isset($user['email'])) { $emails[] = $user['email']; } } } // โ With Data Helpers $emails = $accessor->get('departments.*.users.*.email');
๐ Key Benefits
- Type-Safe - PHPStan Level 9 compliant with 3500+ tests
- Fast - SimpleDto with #[UltraFast] is up to 34.0x faster than Other Serializer
- Framework-Agnostic - Works with Laravel, Symfony, Doctrine, or plain PHP
- Zero Dependencies - No required dependencies, optional framework integrations
- No-Code Mapping - Store templates in database, create with drag-and-drop editors
๐ฆ Installation
composer require event4u/data-helpers
Requirements: PHP 8.2+
Framework support (all optional):
- ๐ด Laravel 9+ - Collections, Eloquent Models
- โซ Symfony/Doctrine 6+ - Collections, Entities
- ๐ง Standalone PHP - Works out of the box
๐ Installation Guide โข Configuration
โก Core Components
1๏ธโฃ DataAccessor - Read Nested Data
Access deeply nested data with dot notation and wildcards:
$data = [ 'users' => [ ['email' => 'alice@example.com'], ['email' => 'bob@example.com'], ], ]; $accessor = new DataAccessor($data); $emails = $accessor->get('users.*.email'); // $emails = ['alice@example.com', 'bob@example.com']
๐ DataAccessor Documentation
2๏ธโฃ DataMutator - Modify Nested Data
Safely modify nested structures:
$data = ['user' => ['profile' => []]]; DataMutator::make($data) ->set('user.profile.name', 'Alice') ->merge('user.profile', ['age' => 30]); // $data is now modified: ['user' => ['profile' => ['name' => 'Alice', 'age' => 30]]]
๐ DataMutator Documentation
4๏ธโฃ DataFilter - Query Data
Filter and query data with SQL-like API:
$products = [ ['id' => 1, 'name' => 'Laptop', 'category' => 'Electronics', 'price' => 1200], ['id' => 2, 'name' => 'Mouse', 'category' => 'Electronics', 'price' => 25], ['id' => 3, 'name' => 'Monitor', 'category' => 'Electronics', 'price' => 400], ]; $result = DataFilter::query($products) ->where('category', '=', 'Electronics') ->where('price', '>', 100) ->orderBy('price', 'DESC') ->get(); // Result: [Laptop ($1200), Monitor ($400)]
5๏ธโฃ SimpleDto - Immutable Dtos
Create type-safe, immutable Data Transfer Objects with automatic type casting:
use event4u\DataHelpers\SimpleDto\Attributes\AutoCast; #[AutoCast] // Enable automatic type casting (opt-in for performance) class ReadmeUserDto extends SimpleDto { public function __construct( public readonly string $name, public readonly string $email, public readonly int $age, ) {} } // Automatic type conversion with #[AutoCast] $user = ReadmeUserDto::fromArray([ 'name' => 'John', 'email' => 'john@example.com', 'age' => '30' // String "30" โ int 30 (automatic) ]); // Without #[AutoCast]: Strict types, better performance class StrictUserDto extends SimpleDto { public function __construct( public readonly string $name, public readonly int $age, // Must be int, no conversion ) {} }
6๏ธโฃ LiteDto - Ultra-Fast Dtos
Create ultra-fast, minimalistic DTOs with essential features:
use event4u\DataHelpers\LiteDto\LiteDto; use event4u\DataHelpers\LiteDto\Attributes\MapFrom; use event4u\DataHelpers\LiteDto\Attributes\Hidden; class UserDto extends LiteDto { public function __construct( public readonly string $name, #[MapFrom('email_address')] public readonly string $email, #[Hidden] public readonly string $password, ) {} } $user = UserDto::from([ 'name' => 'John', 'email_address' => 'john@example.com', 'password' => 'secret', ]); $array = $user->toArray(); // ['name' => 'John', 'email' => 'john@example.com'] // password is hidden
Performance: LiteDto is 7.6x faster than SimpleDto Normal (~2.3ฮผs vs ~18.5ฮผs)
3๏ธโฃ DataMapper - Transform Data
Map between different data structures with templates:
$source = [ 'user' => ['name' => 'John Doe', 'email' => 'john@example.com'], 'orders' => [ ['id' => 1, 'status' => 'shipped', 'total' => 100], ['id' => 2, 'status' => 'pending', 'total' => 50], ['id' => 3, 'status' => 'shipped', 'total' => 200], ], ]; $result = DataMapper::from($source) ->template([ 'customer_name' => '{{ user.name }}', 'customer_email' => '{{ user.email }}', 'shipped_orders' => [ 'WHERE' => [ '{{ orders.*.status }}' => 'shipped', ], 'ORDER BY' => [ '{{ orders.*.total }}' => 'DESC', ], '*' => [ 'id' => '{{ orders.*.id }}', 'total' => '{{ orders.*.total }}', ], ], ]) ->map() ->getTarget();
๐ก No-Code Data Mapping: Templates can be stored in a database and created with a drag-and-drop editor - perfect for import wizards, API integrations, and ETL pipelines without writing code!
๐ฏ Advanced Features
No-Code Data Mapping
Store templates in database and create mappings without programming:
// Load template from database (created with drag-and-drop editor) $template = Mappings::find(3)->template; $result = DataMapper::from($source) ->template($template) ->map() ->getTarget();
Perfect for:
- ๐ฅ Import Wizards - Let users map CSV/Excel columns to your data model
- ๐ API Integration - Configure API mappings without code changes
- ๐ข Multi-Tenant Systems - Each tenant can have custom data mappings
- ๐ Dynamic ETL - Build data transformation pipelines visually
- ๐ Form Builders - Map form submissions to different data structures
๐ Template-Based Mapping Guide
Complex Nested Mapping
Map complex nested structures to Eloquent Models or Doctrine Entities:
// Automatic relation detection for Eloquent/Doctrine $company = new Company(); $result = DataMapper::from($jsonData) ->target($company) ->template([ 'name' => '{{ company.name }}', 'departments' => [ '*' => [ 'name' => '{{ company.departments.*.name }}', 'budget' => '{{ company.departments.*.budget }}', ], ], ]) ->map() ->getTarget();
- โ Automatic Relation Detection
- โ Type Casting (string โ int/float/bool)
- โ Snake_case โ camelCase conversion
- โ Nested Wildcards
Pipeline API
Transform data with composable filters:
use Tests\Utils\Docu\TrimStrings; use Tests\Utils\Docu\LowercaseEmails; use Tests\Utils\Docu\SkipEmptyValues; $source = ['name' => ' John ', 'email' => 'JOHN@EXAMPLE.COM']; $mapping = ['name' => '{{ name }}', 'email' => '{{ email }}']; $result = DataMapper::from($source) ->template($mapping) ->pipeline([ new TrimStrings(), new LowercaseEmails(), new SkipEmptyValues(), ]) ->map() ->getTarget(); // $result = ['name' => 'John', 'email' => 'john@example.com']
Template Expressions
Use Twig-like expressions with 18+ built-in filters:
$mapping = [ 'name' => '{{ user.firstName | ucfirst }} {{ user.lastName | ucfirst }}', 'email' => '{{ user.email | lower | trim }}', 'role' => '{{ user.role | upper ?? "USER" }}', ];
๐ Template Expressions
Query Builder
Laravel-style fluent interface for building queries:
$result = DataMapper::query() ->source('products', $data) ->where('category', 'Electronics') ->where('price', '>', 100) ->orderBy('price', 'DESC') ->groupBy('category', ['total' => ['COUNT']]) ->get();
๐ Query Builder Documentation
๐ Documentation
Comprehensive documentation with guides, examples, and API reference is available at:
๐ event4u-app.github.io/data-helpers
The documentation includes:
- ๐ Getting Started Guides - Installation, configuration, and quick start tutorials
- ๐ง Main Classes - Detailed guides for DataAccessor, DataMutator, DataMapper, and DataFilter
- ๐ฏ SimpleDto - Type-safe Dtos with validation, casting, and collections
- โก LiteDto - Ultra-fast, minimalistic Dtos (7.6x faster than SimpleDto)
- ๐ Advanced Features - Template expressions, query builder, pipelines, and reverse mapping
- ๐ Framework Integration - Laravel, Symfony, and Doctrine integration guides
- ๐ก 90+ Code Examples - Runnable examples for every feature
- ๐ Performance Benchmarks - Optimization tips and benchmark results
- ๐ Complete API Reference - Full API documentation for all classes and methods
๐งช Testing & Quality
- โ 3500+ tests with comprehensive coverage
- โ PHPStan Level 9 - Highest static analysis level
- โ 100% type coverage - All methods fully typed
- โ Continuous Integration - Automated testing across PHP 8.2, 8.3, 8.4
๐ Contributing Guide โข Development Setup
โก Performance
All operations are highly optimized:
- Simple access: ~0.2ฮผs
- Nested access: ~0.3ฮผs
- Wildcards: ~5ฮผs
- SimpleDto #[UltraFast] is up to 34.0x faster than Other Serializer
๐ Performance Benchmarks โข Optimization Tips
๐ค Contributing
Contributions are welcome! Please see the Contributing Guide for details.
# Install dependencies composer install # Run tests composer test # Run quality checks composer quality
๐ Sponsoring
This package is part of the event4u ecosystem - a comprehensive event management platform. Your sponsorship helps us:
- ๐ Develop event4u - The next-generation event management app
- ๐ฆ Maintain open-source packages - Like this Data Helpers library
- ๐ง Build new tools - More packages and utilities for the PHP community
- ๐ Improve documentation - Better guides and examples
- ๐ Fix bugs faster - Dedicated time for maintenance and support
Support the Development
Every contribution, no matter how small, makes a difference and is greatly appreciated! ๐
๐ License
MIT License. See LICENSE for details.
๐ Show Your Support
If this package helps you, please consider:
- โญ Giving it a star on GitHub
- ๐ Sponsoring the development
- ๐ข Sharing it with others