Product Decisions This Supports
-
Feature Development:
- Enables lightweight property change tracking for non-Eloquent objects (e.g., DTOs, API responses, or custom value objects) without relying on Laravel’s built-in mechanisms.
- Useful for audit logging, optimistic concurrency control, or conditional caching invalidation in legacy systems or microservices.
- Example: Track changes to a
UserProfileDTO to trigger notifications or log updates without persisting to a database.
-
Roadmap Prioritization:
- Justifies not building a custom solution for simple property observation, freeing engineering bandwidth for higher-priority features (e.g., core business logic, performance optimizations).
- Ideal for short-term fixes or prototyping where a heavier solution (e.g., Doctrine change tracking) is overkill.
-
Build vs. Buy:
- Buy for quick wins in existing projects where maintenance risk is acceptable (e.g., internal tools, non-critical paths).
- Build only if requirements evolve (e.g., need for async events, deep property diffing, or Laravel-specific integrations like queue jobs or notifications).
- Avoid for new projects or greenfield initiatives due to deprecation risk.
-
Use Cases:
- Legacy Systems: Add change detection to older PHP/Laravel apps without refactoring to Eloquent models.
- Batch Processing: Track property changes across large datasets (e.g., ETL pipelines) via
clear() to reset state between iterations.
- Prototyping: Validate assumptions about property change patterns before committing to a heavier solution (e.g., Laravel Observers or Doctrine).
- Non-Persistent Objects: Monitor changes in objects that aren’t tied to a database (e.g., API request/response objects, configuration DTOs).
When to Consider This Package
Adopt if:
- You need simple, synchronous property change detection for plain PHP objects (not Eloquent models or complex DTOs with nested structures).
- Your use case is narrow and bounded (e.g., tracking 1–3 properties in a specific service or controller).
- You’re working in a Laravel/PHP environment but want to avoid Laravel-specific packages (e.g.,
laravel-model-dirty).
- You can tolerate no active maintenance and are okay with the MIT license (but plan to migrate if the package is removed).
- You need a lightweight alternative to manual property tracking (e.g., storing original values in a service or using
__get()/__set()).
- Your project is not starting from scratch and already uses this package (or a similar pattern) elsewhere.
Look elsewhere if:
- You’re tracking changes in Eloquent models: Use Laravel’s native
getOriginal() or replicas() instead.
- You need event-based notifications: Use Laravel’s
Observers, Model Events, or a package like spatie/laravel-activitylog.
- You require deep property diffing (e.g., nested arrays/objects): Use
spatie/array-to-object + custom logic or a package like rubix/ml-diff.
- You need performance at scale: This package isn’t optimized for high-throughput systems (e.g., real-time processing or large batches).
- You’re starting a new project: The risk of package removal may outweigh the benefits; consider building a custom solution or using Laravel’s built-ins.
- You need Laravel-specific features: E.g., integration with queues, notifications, or service providers (this package is framework-agnostic).
- Your objects have complex property access (e.g., private properties, dynamic names, or magic methods): This package may fail silently or require workarounds.
How to Pitch It (Stakeholders)
For Executives:
"This package lets us quickly add property change tracking to our objects with minimal code—think of it as a lightweight 'change detector' for our data. For example, if we need to log when a user’s profile is updated or validate data before saving, we can implement this in hours instead of days. It’s a low-risk, low-effort solution for common edge cases like audit trails or optimistic locking. Since it’s deprecated but stable, we’re not locked into long-term maintenance; we can replace it later if needed. The tradeoff is minimal for short-term gains, especially in legacy systems or non-critical paths."
For Engineering:
*"PropertyObserver gives us a simple way to detect changes to object properties without reinventing the wheel or over-engineering. Key benefits:
- No dependencies beyond Composer: Just add it to your project.
- Flexible: Works for single or multiple properties and clears state between iterations (great for batch processing).
- Framework-agnostic: If we later switch frameworks, this won’t tie us down.
- Lightweight: Minimal overhead for basic use cases.
Tradeoffs:
- It’s not actively maintained, so we’d need to monitor for breaking changes in its dependency (
symfony/property-access).
- It’s not Laravel-specific, so we can’t leverage features like events or queues out of the box.
Best for: Quick fixes, prototyping, or non-Eloquent objects where Laravel’s built-ins don’t fit. For new features, we’d likely build a custom solution or use Laravel’s native tools."*
For Developers:
*"This is a drop-in solution for tracking property changes in plain PHP objects. For example:
$observer = new PropertyObserver();
$observer->saveValue($userDto, 'email'); // Save initial state
// ... later ...
if ($observer->hasChangedValue($userDto, 'email')) {
log("Email updated to: {$userDto->email}");
}
It’s especially useful when:
- You need to track changes in a DTO or non-Eloquent object.
- You’re processing batches and need to reset state per iteration (use
clear()).
- You want to avoid manual property tracking (e.g., storing original values in a service).
Caveats:
- It’s not for Eloquent models (use
getOriginal() instead).
- It’s deprecated, so we should plan to replace it eventually.
- It doesn’t support nested properties or complex objects out of the box."*
For Product Managers:
*"This package helps us deliver features faster by avoiding custom development for simple property change tracking. For example:
- Audit Logging: Automatically log changes to critical fields without manual intervention.
- Optimistic Locking: Detect if an object was modified since the last fetch (e.g., for concurrency control).
- Caching: Invalidate caches when specific properties change (e.g., user settings).
When to avoid it:
- If the use case is core to the product (e.g., a key feature of our app), we should build or use a maintained package.
- If we’re starting a new project, the risk of using a deprecated package may not be worth it.
Alternatives:
- For Eloquent: Use Laravel’s built-in
getOriginal().
- For events: Use Laravel Observers or
spatie/laravel-activitylog.
- For complex diffing: Build a custom solution or use a library like
rubix/ml-diff."*