chebur/twig-php-functions-bundle
Installation:
composer require chebur/twig-php-functions-bundle
Add the bundle to config/bundles.php in Symfony:
return [
// ...
Chebur\TwigPhpFunctionsBundle\CheburTwigPhpFunctionsBundle::class => ['all' => true],
];
First Use Case: Use native PHP functions directly in Twig templates. No need for custom filters or extensions.
{{ dump(php_function('count', ['array' => [1, 2, 3]])) }}
Outputs: 3
Where to Look First:
config/packages/chebur_twig_php_functions.yaml for allowed functions (whitelist).src/DependencyInjection/Configuration.php for default settings.php_function() in Twig to validate setup.Whitelisting Functions:
Define allowed PHP functions in config/packages/chebur_twig_php_functions.yaml:
chebur_twig_php_functions:
allowed_functions:
- 'count'
- 'in_array'
- 'array_key_exists'
Restrict usage to approved functions for security.
Dynamic Function Calls: Pass variables directly to PHP functions:
{% set result = php_function('array_merge', {
'array1': [1, 2],
'array2': [3, 4]
}) %}
{{ dump(result) }} {# Outputs: [1, 2, 3, 4] #}
Integration with Laravel:
spatie/laravel-twig).app/Providers/AppServiceProvider.php:
public function register()
{
$this->app->singleton(\Twig\Environment::class, function () {
$loader = new \Twig\Loader\FilesystemLoader(__DIR__.'/../resources/views');
$twig = new \Twig\Environment($loader);
$twig->addExtension(new \Chebur\TwigPhpFunctionsBundle\Twig\PhpFunctionsExtension());
return $twig;
});
}
Conditional Logic: Use PHP functions for complex logic in templates:
{% if php_function('empty', {'haystack': user.input}) %}
<p>Input is empty!</p>
{% endif %}
Performance Considerations: Cache Twig templates aggressively when using PHP functions, as they bypass Twig’s compile-time optimizations.
Security Risks:
system(), exec(), or file_get_contents().php_function('eval', {...})).Type Mismatches: PHP functions expect specific argument types. Twig converts variables to strings by default:
{{ php_function('is_int', {'var': '123'}) }} {# Returns false #}
Fix: Pass variables as arrays with explicit types:
{{ php_function('is_int', {'var': 123}) }} {# Returns true #}
Laravel-Specific Issues:
$twig->addExtension(new \Chebur\TwigPhpFunctionsBundle\Twig\PhpFunctionsExtension());
Debugging:
{{ dump(php_function('debug_backtrace')) }} to inspect the call stack in templates.Undefined function or Call to undefined function errors (common if functions aren’t whitelisted).Custom Extensions:
Extend the bundle by creating a custom Twig extension that wraps php_function():
class CustomPhpFunctionsExtension extends \Twig\Extension\AbstractExtension
{
public function getFunctions()
{
return [
new \Twig\TwigFunction('safe_count', [$this, 'safeCount']),
];
}
public function safeCount(array $array)
{
return \Chebur\TwigPhpFunctionsBundle\Twig\PhpFunctionsRuntime::callPhpFunction(
'count',
['array' => $array]
);
}
}
Configuration Overrides:
Dynamically override allowed functions in Laravel’s config/twig.php:
'extensions' => [
\Chebur\TwigPhpFunctionsBundle\Twig\PhpFunctionsExtension::class => [
'allowed_functions' => ['count', 'array_filter'],
],
],
Testing: Mock PHP functions in tests using the bundle’s runtime:
$runtime = new \Chebur\TwigPhpFunctionsBundle\Twig\PhpFunctionsRuntime(['count']);
$this->assertEquals(3, $runtime->callPhpFunction('count', ['array' => [1, 2, 3]]));
Performance:
For frequently used functions, consider pre-compiling Twig templates with PHP functions replaced by native Twig logic (e.g., {% for %} instead of php_function('array_map')).
How can I help you explore Laravel packages today?