Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Eloquent Serialize Laravel Package

microweber-deps/eloquent-serialize

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require anourvalar/eloquent-serialize
    

    Ensure your Laravel version (6-11) is compatible.

  2. 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)
    );
    
  3. Unserialize and Execute: Reconstruct and run the query:

    $queryBuilder = \EloquentSerialize::unserialize($serializedQuery);
    $results = $queryBuilder->get();
    
  4. Key Files:

    • vendor/anourvalar/eloquent-serialize/src/EloquentSerialize.php (core logic).
    • Check tests/ for edge-case examples.

Implementation Patterns

Core Workflows

  1. 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();
    
  2. 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));
    
  3. 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]);
    
  4. 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());
    

Integration Tips

  • Scopes: Serialize queries after applying scopes to preserve their logic:
    $serialized = \EloquentSerialize::serialize(
        \App\User::query()->active()->with('roles')
    );
    
  • Dynamic Conditions: Use tap() to modify queries before serialization:
    $query = \App\Product::query();
    $query->tap(fn($q) => $q->where('price', '>', request('min_price')));
    $serialized = \EloquentSerialize::serialize($query);
    
  • Relationships: Ensure with() is called before serialization to include eager-loaded data.
  • Model Binding: Serialize queries for use in controllers or services, but avoid binding models directly to serialized queries (unserialize first).

Gotchas and Tips

Pitfalls

  1. Model Changes:

    • Issue: If the model or its relationships change (e.g., column renamed, relationship removed), the unserialized query may fail or return incorrect data.
    • Fix: Version serialized queries or validate models before use:
      $builder = \EloquentSerialize::unserialize($serialized);
      if (!$builder->getModel()->exists) {
          throw new \Exception("Model no longer exists");
      }
      
  2. Dynamic Conditions:

    • Issue: Queries with dynamic conditions (e.g., where('column', request('value'))) will serialize the literal value, not the logic. Unserializing later may fail if request('value') is unavailable.
    • Fix: Use static conditions or reapply dynamic logic after unserializing:
      $builder = \EloquentSerialize::unserialize($serialized);
      $builder->where('column', request('value')); // Reapply dynamic logic
      
  3. Raw Expressions:

    • Issue: Raw SQL expressions (e.g., whereRaw('...')) may not serialize correctly if they reference undefined variables or functions.
    • Fix: Avoid raw expressions or ensure all dependencies are static.
  4. Memory Limits:

    • Issue: Serializing very large queries (e.g., complex joins with many relationships) can hit memory limits.
    • Fix: Limit relationships or use pagination before serialization:
      $serialized = \EloquentSerialize::serialize(
          \App\User::query()->with(['orders' => fn($q) => $q->limit(10)])->limit(100)
      );
      
  5. Laravel Version Mismatches:

    • Issue: Serialized queries may break if unserialized in a different Laravel version (e.g., syntax changes in query builder).
    • Fix: Test serialized queries across versions or document version compatibility.

Debugging

  1. 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));
    
    • Look for query, with, where, etc., to verify structure.
  2. 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);
    }
    
  3. 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
    

Extension Points

  1. 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));
        }
    }
    
  2. 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)
        }
    }
    
  3. 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);
    });
    
  4. 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
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor