Skip to content

06 Framework Integration

Rumen Damyanov edited this page Jul 29, 2025 · 1 revision

Framework Integration

This guide shows how to integrate php-assets with popular PHP frameworks.

Why Framework-Agnostic?

The php-assets package follows a simple, framework-agnostic approach by design:

  • Simplicity: Just use Asset::add() - no magic, no hidden complexity
  • Universal compatibility: Works with Laravel, Symfony, CodeIgniter, or any PHP framework
  • Easy debugging: No framework-specific layers to troubleshoot
  • Minimal maintenance: No need to maintain separate adapters for different frameworks
  • Standard PHP: Uses only basic PHP features (strings, arrays, file operations)

Laravel Integration

Basic Setup

<?php

// In a controller
use Rumenx\Assets\Asset;

class HomeController extends Controller
{
    public function index()
    {
        Asset::add('css/app.css');
        Asset::add('js/app.js');

        return view('home');
    }
}

Service Provider Configuration

<?php

// app/Providers/AssetServiceProvider.php
use Illuminate\Support\ServiceProvider;
use Rumenx\Assets\Asset;

class AssetServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Production CDN configuration
        if (app()->environment('production')) {
            Asset::setDomain(config('app.cdn_url'));
            Asset::setCachebuster(public_path('build/assets.json'));
        }

        // Development debug assets
        if (app()->environment('local')) {
            Asset::add('css/debug.css');
        }
    }
}

Blade Templates

{{-- resources/views/layouts/app.blade.php --}}
<!DOCTYPE html>
<html>
<head>
    <title>Laravel App</title>
    {!! Asset::css() !!}
    {!! Asset::js('header') !!}
</head>
<body>
    @yield('content')

    {!! Asset::js() !!}
    {!! Asset::js('footer') !!}
</body>
</html>

Middleware for Global Assets

<?php

// app/Http/Middleware/LoadAssets.php
use Rumenx\Assets\Asset;

class LoadAssets
{
    public function handle($request, Closure $next)
    {
        // Global assets
        Asset::add('css/app.css');
        Asset::add('js/app.js');

        // Admin assets for admin routes
        if ($request->is('admin/*')) {
            Asset::add('css/admin.css');
            Asset::add('js/admin.js');
        }

        return $next($request);
    }
}

Symfony Integration

Controller Setup

<?php

// src/Controller/HomeController.php
use Rumenx\Assets\Asset;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class HomeController extends AbstractController
{
    public function index(): Response
    {
        Asset::add('css/app.css');
        Asset::add('js/app.js');

        return $this->render('home/index.html.twig');
    }
}

Service Configuration

<?php

// src/Service/AssetService.php
use Rumenx\Assets\Asset;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

class AssetService
{
    public function __construct(private ParameterBagInterface $params)
    {
        $this->configure();
    }

    private function configure(): void
    {
        $env = $this->params->get('kernel.environment');

        if ($env === 'prod') {
            Asset::setDomain($this->params->get('app.cdn_url'));
            Asset::setCachebuster($this->params->get('kernel.project_dir') . '/public/build/assets.json');
        }
    }
}

Twig Templates

{# templates/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
    <title>Symfony App</title>
    {{ asset_css()|raw }}
    {{ asset_js('header')|raw }}
</head>
<body>
    {% block content %}{% endblock %}

    {{ asset_js()|raw }}
    {{ asset_js('footer')|raw }}
</body>
</html>

Twig Extension

<?php

// src/Twig/AssetExtension.php
use Rumenx\Assets\Asset;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class AssetExtension extends AbstractExtension
{
    public function getFunctions(): array
    {
        return [
            new TwigFunction('asset_css', [$this, 'getCss'], ['is_safe' => ['html']]),
            new TwigFunction('asset_js', [$this, 'getJs'], ['is_safe' => ['html']]),
        ];
    }

    public function getCss(string $group = null): string
    {
        return Asset::css($group);
    }

    public function getJs(string $group = null): string
    {
        return Asset::js($group);
    }
}

CodeIgniter Integration

Controller Setup

<?php

// app/Controllers/Home.php
use Rumenx\Assets\Asset;

class Home extends BaseController
{
    public function index()
    {
        Asset::add('css/app.css');
        Asset::add('js/app.js');

        return view('home');
    }
}

Helper Function

<?php

// app/Helpers/asset_helper.php
use Rumenx\Assets\Asset;

if (!function_exists('add_asset')) {
    function add_asset($file, $group = null)
    {
        return Asset::add($file, $group);
    }
}

if (!function_exists('render_css')) {
    function render_css($group = null)
    {
        return Asset::css($group);
    }
}

if (!function_exists('render_js')) {
    function render_js($group = null)
    {
        return Asset::js($group);
    }
}

Views

<!-- app/Views/layouts/main.php -->
<!DOCTYPE html>
<html>
<head>
    <title>CodeIgniter App</title>
    <?= render_css() ?>
    <?= render_js('header') ?>
</head>
<body>
    <?= $this->renderSection('content') ?>

    <?= render_js() ?>
    <?= render_js('footer') ?>
</body>
</html>

Plain PHP Integration

Application Setup

<?php

// config/assets.php
use Rumenx\Assets\Asset;

// Environment detection
$env = $_ENV['APP_ENV'] ?? 'development';

if ($env === 'production') {
    Asset::setDomain('https://cdn.example.com/');
    Asset::setCachebuster(__DIR__ . '/../public/build/assets.json');
}

// Global assets
Asset::add('css/normalize.css');
Asset::add('css/app.css');
Asset::add('js/app.js');

Layout Template

<!-- templates/layout.php -->
<!DOCTYPE html>
<html>
<head>
    <title><?= $title ?? 'My App' ?></title>
    <?= Asset::css() ?>
    <?= Asset::js('header') ?>
</head>
<body>
    <?= $content ?>

    <?= Asset::js() ?>
    <?= Asset::js('footer') ?>
</body>
</html>

Slim Framework Integration

Slim Setup

<?php

use Rumenx\Assets\Asset;
use Slim\Factory\AppFactory;

$app = AppFactory::create();

// Middleware for asset configuration
$app->add(function ($request, $handler) {
    Asset::add('css/app.css');
    Asset::add('js/app.js');

    return $handler->handle($request);
});

$app->get('/', function ($request, $response) {
    $html = '
    <!DOCTYPE html>
    <html>
    <head>
        <title>Slim App</title>
        ' . Asset::css() . '
    </head>
    <body>
        <h1>Hello Slim!</h1>
        ' . Asset::js() . '
    </body>
    </html>';

    $response->getBody()->write($html);
    return $response;
});

CakePHP Integration

Helper

<?php

// src/View/Helper/AssetHelper.php
use Cake\View\Helper\Helper;
use Rumenx\Assets\Asset;

class AssetHelper extends Helper
{
    public function add($file, $group = null)
    {
        return Asset::add($file, $group);
    }

    public function css($group = null)
    {
        return Asset::css($group);
    }

    public function js($group = null)
    {
        return Asset::js($group);
    }
}

Templates

<!-- templates/layout/default.php -->
<!DOCTYPE html>
<html>
<head>
    <title>CakePHP App</title>
    <?= $this->Asset->css() ?>
</head>
<body>
    <?= $this->fetch('content') ?>
    <?= $this->Asset->js() ?>
</body>
</html>

Best Practices

  1. Keep it simple: Don't over-engineer the integration
  2. Environment-aware: Configure differently for each environment
  3. Global assets: Load common assets globally
  4. Route-specific: Add specific assets per route/controller
  5. Template consistency: Use consistent template patterns

Migration from Framework-Specific Solutions

From Laravel Mix

// Instead of mix() helper
echo mix('css/app.css');

// Use php-assets
Asset::add('css/app.css');
echo Asset::css();

From Symfony AssetMapper

// Instead of asset() function
{{ asset('css/app.css') }}

// Use php-assets
Asset::add('css/app.css');
echo Asset::css();

Related Examples

Clone this wiki locally