symfony/polyfill-mbstring
Partial native PHP polyfill for the mbstring extension, enabling multibyte string functions when ext-mbstring isn’t available. Part of Symfony’s Polyfill suite; provides compatible helpers to improve portability across environments.
Installation: Add the polyfill to your Laravel project via Composer:
composer require symfony/polyfill-mbstring
Laravel’s autoloader will handle the rest—no manual configuration is required.
First Use Case:
Use mb_scrub() or mb_str_pad() in your code where multibyte string handling is needed. For example:
// Scrub control characters from user input
$cleanInput = mb_scrub($userInput);
// Pad a multibyte string (e.g., for RTL languages)
$paddedText = mb_str_pad('مرحبا', 10, '-', STR_PAD_LEFT);
Where to Look First:
Str::of()) that internally use mb_* functions.Validator::extend()) for multibyte string operations.Sanitization Workflows:
Use mb_scrub() to clean user-generated content (e.g., comments, form submissions) before processing:
$sanitizedComment = mb_scrub($request->input('comment'));
Integrate with Laravel’s validation pipeline:
Validator::extend('scrubbed', function ($attribute, $value, $parameters) {
return mb_scrub($value) === $value;
});
Localization and RTL Support:
Use mb_str_pad() for fixed-width text alignment in multilingual UIs:
// For RTL languages (e.g., Arabic)
$rtlText = mb_str_pad('مرحبا', 20, ' ', STR_PAD_LEFT);
Combine with Laravel’s localization helpers:
$translated = __($rtlText);
API Payload Handling: Sanitize API inputs to prevent encoding-related corruption:
$payload = mb_scrub($request->getContent());
Database and File Operations: Ensure multibyte strings are handled correctly when interacting with databases or files:
// Example: Truncate multibyte strings in a database query
$truncated = mb_substr($longText, 0, 100);
Validation and Sanitization Pipeline:
// In a Form Request
public function validateResolved()
{
$this->merge([
'comment' => mb_scrub($this->comment),
]);
}
Blade Template Integration:
Use mb_* functions in Blade for dynamic text processing:
<div class="text-container">
{{ mb_str_pad($rtlText, 30, ' ', STR_PAD_LEFT) }}
</div>
Testing Multibyte Strings: Write PHPUnit tests to verify behavior:
public function testMbScrubRemovesControlChars()
{
$this->assertEquals('Hello', mb_scrub("\x00Hello\x0B"));
}
public function testMbStrPadRtl()
{
$this->assertEquals(10, mb_strlen(mb_str_pad('مرحبا', 10, '-', STR_PAD_LEFT)));
}
Leverage Laravel’s Built-ins:
Laravel’s Str helper and Validator already use mb_* functions internally. No additional setup is needed for basic use cases.
Custom Validation Rules: Extend Laravel’s validation with multibyte-aware rules:
use Illuminate\Support\Facades\Validator;
Validator::extend('mb_length', function ($attribute, $value, $parameters) {
return mb_strlen($value) <= $parameters[0];
});
Middleware for Sanitization: Create middleware to scrub inputs globally:
public function handle($request, Closure $next)
{
$request->merge([
'comment' => mb_scrub($request->input('comment')),
]);
return $next($request);
}
Database Considerations:
Ensure your database collation supports multibyte characters (e.g., utf8mb4_unicode_ci in MySQL).
Performance Overhead:
The polyfill is ~5–10x slower than native mbstring. Avoid using it in performance-critical loops (e.g., bulk data processing). Benchmark with:
php -r "for ($i=0; $i<100000; $i++) { mb_scrub('test'); }"
Unsupported Functions:
The polyfill does not cover all mbstring functions. Unsupported functions include:
mb_http_output()mb_detect_encoding()mb_convert_kana()
Use native mbstring or alternative libraries for these.Edge Cases in mb_scrub():
$invalidUtf8 = "\xFF\xFE€";
$scrubbed = mb_scrub($invalidUtf8); // Should not crash
RTL Padding Quirks:
mb_str_pad() may behave unexpectedly with complex scripts (e.g., Arabic with diacritics). Test thoroughly:
$arabic = 'مرحبا';
$padded = mb_str_pad($arabic, 10, ' ', STR_PAD_LEFT);
// Verify visual alignment in RTL contexts
PHP Version Quirks:
mb_* declarations are isolated in bootstrap72.php (fixed in v1.38.1). Ensure compatibility if using PHP 7.2.iconv for //IGNORE (fixed in v1.38.0). Test on Alpine Linux or similar environments.Check for Native mbstring:
Verify if mbstring is already enabled to avoid unnecessary overhead:
if (!extension_loaded('mbstring')) {
// Polyfill is active
}
Debugging mb_scrub():
Log unexpected behavior to identify edge cases:
$input = "\x00Test\x0B";
$scrubbed = mb_scrub($input);
\Log::debug("Input: " . bin2hex($input) . ", Output: " . bin2hex($scrubbed));
Visual Debugging for RTL:
Use Laravel’s dd() or dump() to inspect padded strings:
dd(mb_str_pad('مرحبا', 10, '-', STR_PAD_LEFT));
No Configuration Required: The polyfill auto-loads and requires no manual configuration in Laravel.
Dependency Conflicts:
Ensure no other packages are overriding mb_* functions. Check for conflicts with:
composer why symfony/polyfill-mbstring
Environment-Specific Behavior:
iconv fallback works.Custom Polyfill Logic: Extend the polyfill by creating a wrapper class:
class CustomMbString extends \Symfony\Component\Polyfill\Mbstring\Mbstring
{
public static function customScrub($str)
{
// Add custom logic
return parent::scrub($str);
}
}
Override Specific Functions:
Use Laravel’s service container to replace mb_* functions:
$app->bind('mb_scrub', function () {
return function ($str) {
// Custom implementation
return mb_scrub($str);
};
});
Benchmarking: Compare polyfill vs. native performance:
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
mb_scrub('test');
}
$time = microtime(true) - $start;
\Log::info("Polyfill time: {$time}s");
Fallback Strategies:
Implement a fallback to native mbstring if available:
function safeMbScrub($str)
{
if (extension_loaded('mbstring')) {
return mb_scrub($
How can I help you explore Laravel packages today?