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

Contract Laravel Package

hyperf/contract

Core contracts for Hyperf: a set of lightweight PHP interfaces that define common behaviors across the framework (DI, events, middleware, serialization, etc.). Helps decouple components, improve testability, and keep implementations swappable.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation Require the package via Composer:

    composer require hyperf/contract
    

    No configuration is needed—it provides only interfaces.

  2. First Use Case Define a service class implementing a Hyperf contract, such as Hyperf\Contract\CacheInterface:

    use Hyperf\Contract\CacheInterface;
    
    class RedisCache implements CacheInterface
    {
        public function get($key, $default = null)
        {
            // Redis logic
        }
    
        public function set($key, $value, $ttl = null)
        {
            // Redis logic
        }
    }
    
  3. Where to Look First

    • Contracts Directory: Explore src/Contract for available interfaces.
    • Hyperf Documentation: Refer to Hyperf’s official docs for integration examples.
    • IDE Autocomplete: Use Hyperf\Contract\ namespace to discover relevant interfaces.

Implementation Patterns

Dependency Injection (DI)

Leverage Hyperf’s DI container to bind contracts to implementations:

// In a service provider or config file
$container->bind(
    Hyperf\Contract\CacheInterface::class,
    \App\Cache\RedisCache::class
);
  • Annotations: Use @Inject or @Bind in classes for automatic resolution:
    use Hyperf\Di\Annotation\Inject;
    
    class OrderService
    {
        #[Inject]
        public CacheInterface $cache;
    }
    

Middleware & Filters

Implement lifecycle hooks using contracts like OnRequest:

use Hyperf\Contract\OnRequest;
use Psr\Http\Message\ResponseInterface;

class AuthMiddleware implements OnRequest
{
    public function process($request, Closure $next): ResponseInterface
    {
        if (!$request->hasHeader('Authorization')) {
            return new Response(401);
        }
        return $next($request);
    }
}

Register middleware in config/autoload/middlewares.php:

return [
    'http' => [
        AuthMiddleware::class,
    ],
];

Service Abstraction

Define modular boundaries with contracts (e.g., QueueWorkerInterface):

use Hyperf\Contract\QueueWorkerInterface;

class PaymentProcessor implements QueueWorkerInterface
{
    public function handle($job, $data)
    {
        // Process payment
    }
}

Register workers in config/autoload/queues.php:

return [
    'default' => [
        'worker' => PaymentProcessor::class,
    ],
];

Cross-Cutting Concerns

Use contracts for logging, caching, or auth:

use Hyperf\Contract\LoggerInterface;

class OrderService
{
    public function __construct(private LoggerInterface $logger)
    {
    }

    public function create()
    {
        $this->logger->info('Order created');
    }
}

Testing

Mock contracts in unit tests:

use Hyperf\Contract\CacheInterface;
use PHPUnit\Framework\TestCase;

class OrderServiceTest extends TestCase
{
    public function testCache()
    {
        $cache = $this->createMock(CacheInterface::class);
        $cache->method('get')->willReturn('cached_value');

        $service = new OrderService($cache);
        $this->assertEquals('cached_value', $service->getCachedData());
    }
}

Gotchas and Tips

Pitfalls

  1. Hyperf-Specific Assumptions

    • Some contracts assume Hyperf’s DI or coroutine system (e.g., Hyperf\Contract\ContextInterface). Avoid using these in non-Hyperf contexts.
    • Fix: Stick to PSR-compliant or framework-agnostic contracts (e.g., Psr\Cache\CacheItemPoolInterface).
  2. DI Container Conflicts

    • Laravel’s container won’t resolve Hyperf contracts natively. Use a custom bridge or adapter pattern:
      $container->bind(
          Hyperf\Contract\CacheInterface::class,
          function ($container) {
              return new LaravelCacheAdapter($container->make(\Illuminate\Contracts\Cache\Store::class));
          }
      );
      
  3. Missing Implementations

    • The package provides only interfaces. You must implement them (e.g., Hyperf\Contract\ConfigInterface requires a concrete Config class).
    • Tip: Use Hyperf’s built-in implementations as a reference (e.g., Hyperf\Config\Config).
  4. Version Skew

    • Hyperf’s contracts may evolve faster than Laravel’s ecosystem. Pin versions strictly:
      "hyperf/contract": "3.1.*"
      
  5. Coroutines in Non-Hyperf Code

    • Contracts like Hyperf\Contract\CoroutineInterface are Hyperf-specific. Avoid in Laravel.
    • Alternative: Use PHP’s Generator or Amp for async tasks.

Debugging Tips

  1. Contract Not Resolved?

    • Check if the binding exists:
      php bin/hyperf container:list
      
    • Ensure the implementing class is autoloaded.
  2. Middleware Not Triggering

    • Verify registration in middlewares.php and that the class implements OnRequest/OnException.
  3. Queue Workers Ignored

    • Confirm the worker is listed in queues.php and the class implements QueueWorkerInterface.
  4. IDE Not Recognizing Contracts

    • Add this to phpstorm.meta.php:
      namespace Hyperf\Contract {
          interface CacheInterface {}
          // ... other interfaces
      }
      

Extension Points

  1. Custom Contracts Extend Hyperf’s contracts for domain-specific needs:

    namespace App\Contracts;
    
    use Hyperf\Contract\CacheInterface;
    
    interface DomainCacheInterface extends CacheInterface
    {
        public function getDomainData(string $domain);
    }
    
  2. Adapter Pattern Create Laravel-compatible adapters for Hyperf contracts:

    class LaravelCacheAdapter implements Hyperf\Contract\CacheInterface
    {
        public function __construct(private \Illuminate\Contracts\Cache\Store $cache) {}
    
        public function get($key, $default = null)
        {
            return $this->cache->get($key, $default);
        }
    }
    
  3. Dynamic Bindings Use closures for runtime bindings:

    $container->bind(
        Hyperf\Contract\LoggerInterface::class,
        fn() => new MonologLogger()
    );
    
  4. Testing Helpers Create a base test case with pre-configured mocks:

    abstract class HyperfTestCase extends TestCase
    {
        protected function mockCache(): CacheInterface
        {
            return $this->createMock(CacheInterface::class);
        }
    }
    

Performance Considerations

  • Avoid Over-Abstraction: Only use contracts where they add value (e.g., swappable implementations). Directly inject concrete classes for simple cases.
  • Lazy Loading: Bind contracts lazily to defer initialization:
    $container->bind(
        Hyperf\Contract\CacheInterface::class,
        fn() => new RedisCache()
    );
    
  • Interface Pollution: Limit the number of contracts per module to keep the codebase manageable.

Configuration Quirks

  1. Autoloading Ensure composer dump-autoload is run after adding new contracts.

  2. Namespace Conflicts Avoid naming collisions (e.g., App\Contracts\CacheInterface vs. Hyperf\Contract\CacheInterface). Use distinct namespaces.

  3. Hyperf-Specific Config Some contracts rely on Hyperf’s config system (e.g., Hyperf\Contract\ConfigInterface). Mock these in tests:

    $config = $this->createMock(ConfigInterface::class);
    $config->method('get')->willReturnMap([
        ['cache.driver', 'redis'],
    ]);
    
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