nayjest/manipulator
Fast, lightweight PHP object manipulation helpers—like symfony/property-access but simpler (~300 LOC) and no reflection. Instantiate classes, set public properties, and assign values via setters from arrays (snake/camel case), with optional property creation.
Installation:
composer require nayjest/manipulator
Add to composer.json if not using Composer globally:
"require": {
"nayjest/manipulator": "^1.0"
}
Basic Usage:
use Nayjest\Manipulator\Manipulator;
$object = new class { public $name = 'John'; public $age = 30; };
$manipulator = new Manipulator($object);
// Set a property
$manipulator->set('name', 'Jane');
// Get a property
$name = $manipulator->get('name'); // 'Jane'
First Use Case: Dynamically update an Eloquent model or DTO before saving/returning:
$user = User::find(1);
$manipulator = new Manipulator($user);
$manipulator->set('email', 'new@example.com');
$user->save(); // Persists changes
Dynamic Property Manipulation:
$manipulator = new Manipulator($object);
$manipulator->set('property', $value);
$manipulator->get('property');
Bulk Operations:
$manipulator->setMultiple([
'name' => 'Alice',
'age' => 25,
'active' => true
]);
Nested Objects:
$manipulator->set('address.city', 'New York');
$manipulator->get('address.city');
Conditional Updates:
if ($manipulator->has('email')) {
$manipulator->set('email', strtolower($manipulator->get('email')));
}
Service Providers: Bind the manipulator to the container for dependency injection:
$this->app->bind(Manipulator::class, function ($app) {
return new Manipulator($app->make($objectClass));
});
Form Requests:
public function update(Request $request, User $user) {
$manipulator = new Manipulator($user);
$manipulator->setMultiple($request->validated());
$user->save();
}
API Responses:
$manipulator = new Manipulator($resource);
return response()->json($manipulator->getAll());
Middleware: Modify request data before processing:
public function handle($request, Closure $next) {
$manipulator = new Manipulator($request->user());
$manipulator->set('last_seen', now());
return $next($request);
}
No Type Safety: The package manipulates properties dynamically, bypassing PHP’s type system. Ensure type consistency manually:
$manipulator->set('age', (int) $value); // Force integer
No Magic Methods:
Unlike Laravel’s Arrayable, this doesn’t auto-convert objects to arrays. Use getAll() explicitly:
$data = $manipulator->getAll(); // Returns associative array
Nested Property Limits:
Deeply nested paths (e.g., a.b.c.d) may fail silently if intermediate properties are non-object/array. Validate paths:
if (!$manipulator->has('address.city')) {
throw new \InvalidArgumentException('Invalid path');
}
Immutable Objects:
The manipulator works on references but won’t modify truly immutable objects (e.g., stdClass with no setters). Use reflection or ensure mutable objects:
$object = new class { public $prop; };
$manipulator = new Manipulator($object); // Works
Last Release Age: The package hasn’t been updated since 2016. Test thoroughly in your environment, especially with PHP 8+ (e.g., named arguments, union types).
Check Property Existence:
if (!$manipulator->has('property')) {
// Handle missing property
}
Inspect Object State:
var_dump($manipulator->getAll());
Use getProperty() for Reflection:
Access private/protected properties if needed (though this is generally discouraged):
$manipulator->getProperty('protectedProp');
Custom Property Handlers:
Override default behavior by extending Manipulator:
class CustomManipulator extends Manipulator {
public function set($property, $value) {
if ($property === 'sensitive') {
$value = bcrypt($value);
}
parent::set($property, $value);
}
}
Event Hooks: Trigger events before/after manipulation (requires custom implementation):
$manipulator->on('beforeSet', function ($property, $value) {
// Pre-process value
});
Integration with Laravel Events: Dispatch events when properties change:
$manipulator->set('email', $newEmail, function () {
event(new EmailUpdated($user));
});
How can I help you explore Laravel packages today?