microweber-deps/eloquent-serialize
Installation:
composer require anourvalar/eloquent-serialize
Ensure your Laravel version (6-11) is compatible.
First Use Case: Serialize a query to a string for later use (e.g., caching, sharing, or delayed execution):
$serializedQuery = \EloquentSerialize::serialize(
\App\User::query()->where('active', true)->limit(10)
);
Unserialize and Execute: Reconstruct and run the query:
$queryBuilder = \EloquentSerialize::unserialize($serializedQuery);
$results = $queryBuilder->get();
Key Files:
vendor/anourvalar/eloquent-serialize/src/EloquentSerialize.php (core logic).tests/ for edge-case examples.Caching Queries: Serialize queries before expensive operations (e.g., API responses, reports) and cache the result:
$cacheKey = 'user_list_active';
$serialized = cache()->get($cacheKey);
if (!$serialized) {
$serialized = \EloquentSerialize::serialize(\App\User::query()->where('active', true));
cache()->put($cacheKey, $serialized, now()->addHours(1));
}
$results = \EloquentSerialize::unserialize($serialized)->get();
Delayed Execution: Queue serialized queries for background processing (e.g., nightly reports):
$serialized = \EloquentSerialize::serialize(\App\Order::query()->where('status', 'pending'));
Dispatch(new ProcessQueryJob($serialized));
API Versioning: Store serialized queries in a database to support backward-compatible API endpoints:
// Store serialized query for v1 of an endpoint
$v1Query = \EloquentSerialize::serialize(\App\Post::query()->where('published', true));
DB::table('api_queries')->insert(['version' => '1.0', 'query' => $v1Query]);
Reusable Query Builders: Create a "query factory" for complex, reusable queries:
class UserQueryFactory {
public static function getActiveUsersWithPhones() {
return \EloquentSerialize::serialize(
\App\User::query()->where('active', true)->with('phones')
);
}
}
// Later...
$query = \EloquentSerialize::unserialize(UserQueryFactory::getActiveUsersWithPhones());
$serialized = \EloquentSerialize::serialize(
\App\User::query()->active()->with('roles')
);
tap() to modify queries before serialization:
$query = \App\Product::query();
$query->tap(fn($q) => $q->where('price', '>', request('min_price')));
$serialized = \EloquentSerialize::serialize($query);
with() is called before serialization to include eager-loaded data.Model Changes:
$builder = \EloquentSerialize::unserialize($serialized);
if (!$builder->getModel()->exists) {
throw new \Exception("Model no longer exists");
}
Dynamic Conditions:
where('column', request('value'))) will serialize the literal value, not the logic. Unserializing later may fail if request('value') is unavailable.$builder = \EloquentSerialize::unserialize($serialized);
$builder->where('column', request('value')); // Reapply dynamic logic
Raw Expressions:
whereRaw('...')) may not serialize correctly if they reference undefined variables or functions.Memory Limits:
$serialized = \EloquentSerialize::serialize(
\App\User::query()->with(['orders' => fn($q) => $q->limit(10)])->limit(100)
);
Laravel Version Mismatches:
Inspect Serialized Output:
Use json_encode() to debug the serialized string:
$serialized = \EloquentSerialize::serialize(\App\User::query()->where('id', 1));
dd(json_encode(json_decode($serialized), JSON_PRETTY_PRINT));
query, with, where, etc., to verify structure.Unserialize Errors: Wrap unserialization in a try-catch to handle malformed queries:
try {
$builder = \EloquentSerialize::unserialize($serialized);
} catch (\Exception $e) {
\Log::error("Failed to unserialize query: " . $e->getMessage());
return response()->json(['error' => 'Invalid query'], 400);
}
Query Dump: Use Laravel’s query logging to debug unserialized queries:
\DB::enableQueryLog();
$results = \EloquentSerialize::unserialize($serialized)->get();
\DB::getQueryLog(); // Inspect the final executed query
Custom Serialization: Extend the package by implementing your own serializer for specific needs:
class CustomSerializer {
public static function serialize(\Illuminate\Database\Eloquent\Builder $query) {
// Custom logic (e.g., exclude certain conditions)
return \EloquentSerialize::serialize($query->where('active', true));
}
}
Query Validation: Add middleware or a trait to validate serialized queries before execution:
trait ValidatedQuery {
public function validate() {
if (!$this->getModel()->exists) {
throw new \Exception("Invalid model");
}
// Add more checks (e.g., table exists, columns exist)
}
}
Performance Optimization: Cache unserialized query builders to avoid reparsing:
$cacheKey = 'query_builder_' . md5($serialized);
$builder = cache()->remember($cacheKey, now()->addMinutes(5), function() use ($serialized) {
return \EloquentSerialize::unserialize($serialized);
});
Security: Sanitize serialized queries if they come from untrusted sources (e.g., user input) to prevent SQL injection:
$builder = \EloquentSerialize::unserialize($serialized);
$builder->where('id', '>', 0); // Force safe conditions
How can I help you explore Laravel packages today?