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

Headers Bundle Laravel Package

batch.com/headers-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle:

    composer require batch.com/headers-bundle
    

    Add to config/bundles.php (Symfony 4.4+ auto-discovers, but explicit inclusion is good practice):

    Batch\HeadersBundle\BatchHeadersBundle::class => ['all' => true],
    
  2. Configure Headers: Edit config/packages/batch_headers.yaml (or merge into your existing config):

    batch_headers:
      headers:
        - X-Frame-Options: DENY  # Basic example
    
  3. First Use Case: Immediately enforce security headers (e.g., CSP, XSS protection) across all responses without modifying controllers. Test with:

    php bin/console debug:headers  # Symfony's built-in header inspector
    

Implementation Patterns

Core Workflows

  1. Global Headers: Use the YAML config for headers that apply universally (e.g., Strict-Transport-Security, X-Content-Type-Options). Example:

    batch_headers:
      headers:
        - Referrer-Policy: strict-origin-when-cross-origin
    
  2. Conditional Headers: Leverage condition for dynamic logic (e.g., API vs. frontend routes):

    - name: Access-Control-Allow-Headers
      value: "Content-Type, Authorization"
      condition: "request.getPathInfo() matches '^/api'"
    

    Tip: Use Symfony’s ExpressionLanguage for complex conditions (e.g., request.attributes.get('_controller') == 'App\Controller\ApiController').

  3. Response-Based Conditions: Target headers based on response content (e.g., caching images):

    - name: Cache-Control
      value: "public, max-age=31536000"
      condition: "response.headers.get('Content-Type') matches '^image/'"
    
  4. Environment-Specific Headers: Override headers per environment (e.g., dev vs. prod) using Symfony’s %kernel.environment%:

    - name: X-Debug-Token
      value: "dev-token"
      condition: "'%kernel.environment%' == 'dev'"
    

Integration Tips

  • Event Listeners: Extend functionality by subscribing to kernel.response:

    use Batch\HeadersBundle\Event\HeadersEvent;
    
    public function onHeaders(HeadersEvent $event) {
        $event->addHeader('X-Custom-Header', 'dynamic-value');
    }
    

    Register in services.yaml:

    services:
      App\EventListener\CustomHeaderListener:
        tags:
          - { name: 'kernel.event_listener', event: 'batch.headers', method: 'onHeaders' }
    
  • Laravel-Specific: For Laravel (via Symfony Bridge), alias the bundle in config/app.php:

    'aliases' => [
        'BatchHeaders' => Batch\HeadersBundle\BatchHeadersBundle::class,
    ],
    

    Then configure in config/batch_headers.php (Laravel’s config format).


Gotchas and Tips

Pitfalls

  1. Condition Syntax:

    • matches uses PCRE regex (case-sensitive). For case-insensitive, use matches '/^image/i'.
    • Avoid request.getClientIp() in conditions—it may fail in proxied environments (use request.server.get('HTTP_X_FORWARDED_FOR') instead).
  2. Header Order: Headers are applied in YAML array order. Later entries override earlier ones if the same header is defined twice.

  3. Performance:

    • Complex conditions (e.g., nested ExpressionLanguage logic) add microseconds to response time. Benchmark critical paths.
    • Cache the compiled conditions in production (Symfony’s ExpressionLanguage caches by default).
  4. Symfony Version:

    • Tested on Symfony 4.4+. For older versions, check composer.json for compatibility (e.g., symfony/http-foundation:^4.4).

Debugging

  • Verify Headers: Use Symfony’s CLI tool:

    php bin/console debug:headers --url="http://yoursite.com/api"
    

    Or inspect HTTP responses with browser dev tools (Network tab).

  • Condition Debugging: Enable Symfony’s ExpressionLanguage debugging:

    framework:
      expression_language:
        debug: true
    

    Log conditions to var/log/dev.log:

    use Psr\Log\LoggerInterface;
    
    public function __construct(LoggerInterface $logger) {
        $this->logger = $logger;
    }
    
    public function onHeaders(HeadersEvent $event) {
        $this->logger->debug('Headers conditions evaluated', ['conditions' => $event->getConditions()]);
    }
    

Extension Points

  1. Custom Conditions: Extend the condition parser by implementing Batch\HeadersBundle\Condition\ConditionInterface and register it as a service:

    services:
      App\Condition\CustomCondition:
        tags: ['batch.headers.condition']
    
  2. Header Providers: Dynamically fetch headers from a database or API:

    use Batch\HeadersBundle\Provider\HeaderProviderInterface;
    
    class DatabaseHeaderProvider implements HeaderProviderInterface {
        public function getHeaders(): array {
            return $this->db->fetch('SELECT name, value FROM headers');
        }
    }
    

    Register in services.yaml:

    services:
      App\Provider\DatabaseHeaderProvider:
        tags: ['batch.headers.provider']
    
  3. Override Defaults: Disable the bundle’s auto-registration by setting enabled: false in config, then manually add headers via event listeners.

  4. Laravel-Specific Quirks:

    • Laravel’s Response object may not expose all Symfony methods. Use tap() to ensure compatibility:
      $response->headers->set('X-Foo', 'Bar'); // Laravel
      // or
      $response->getHeaders()->set('X-Foo', 'Bar'); // Symfony-style
      
    • For Blade templates, headers are applied before rendering. Use response()->headers->set() in middleware if needed.

```markdown
## Laravel-Specific Addendum
*(Since the package is Symfony-based but may be used in Laravel via Symfony Bridge)*

### Laravel Integration
1. **Installation**:
   ```bash
   composer require batch.com/headers-bundle symfony/http-foundation
  1. Configuration: Publish the config file (if using Laravel’s config system):

    php artisan vendor:publish --tag=batch_headers_config
    

    Edit config/batch_headers.php (Laravel’s format):

    return [
        'headers' => [
            [
                'name' => 'X-Powered-By',
                'value' => 'Laravel + Symfony',
            ],
        ],
    ];
    
  2. Middleware: Register the bundle’s listener in Laravel’s middleware stack (app/Http/Kernel.php):

    protected $middlewareGroups = [
        'web' => [
            // ...
            \Batch\HeadersBundle\Middleware\HeadersMiddleware::class,
        ],
    ];
    
  3. Dynamic Headers: Use Laravel’s service container to inject headers dynamically:

    use Batch\HeadersBundle\Event\HeadersEvent;
    
    public function onHeaders(HeadersEvent $event) {
        $event->addHeader('X-User-ID', auth()->id());
    }
    

    Bind the listener in AppServiceProvider:

    public function boot() {
        event(new HeadersEvent($this->app['request'], $this->app['response']));
    }
    

Laravel Gotchas

  • Response Object: Laravel’s Response class may not support all Symfony header methods. Cast to Symfony\Component\HttpFoundation\Response if needed:

    $symfonyResponse = $response->getOriginalContent();
    $symfonyResponse->headers->set('X-Foo', 'Bar');
    
  • Blade Directives: Headers added via the bundle won’t appear in {{ dd($response->headers) }} during Blade rendering. Use middleware or tap():

    return response()->tap(function ($response) {
        $response->headers->set('X-Custom', 'Blade-Friendly');
    });
    
  • API Resources: Headers applied to JSON responses may conflict with Laravel’s Resource metadata. Prioritize bundle headers by adding them last in middleware.

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.
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php