Speeding Up Laravel Tests with tmpfs (MySQL in RAM)
If your Laravel test suite is painfully slow and does a lot of database work (multi-tenancy, migrations, seeding), the bottleneck is almost…
When developing applications for an international audience, always prefer Laravel's Str helper or PHP's mb_* functions over PHP's native string functions. This simple choice can save you from frustrating bugs and guarantee your text looks professional in any language.
PHP's built-in functions like strtolower(), strtoupper(), and ucwords() were created when ASCII was the primary encoding. Because of this, they don't properly handle UTF-8 characters, causing issues with non-English text.
Here's a concrete example that demonstrates the issue:
// PHP's native functions
$frenchText = "ÉCOLE FRANÇAISE";
echo strtolower($frenchText); // Outputs: "École franÇaise" - notice the Ç remains uppercase!
echo ucwords(strtolower($frenchText)); // Outputs: "École FranÇaise" - incorrect capitalization
// Special character example
$germanText = "GROßARTIG"; // German word with ß (sharp s)
echo strtolower($germanText); // May not convert correctly in some PHP configurations
echo ucwords(strtolower($germanText)); // May produce inconsistent results
The issue is that PHP's native string functions operate on a byte-by-byte basis rather than understanding Unicode character boundaries, resulting in incorrect transformations for many non-ASCII characters.
Laravel includes a robust Str helper class that utilizes PHP's multibyte string functions (mb_*) with proper UTF-8 encoding. This helper provides a clean and intuitive way to handle UTF-8 text correctly.
use Illuminate\Support\Str;
// Laravel's Str helper
$frenchText = "ÉCOLE FRANÇAISE";
echo Str::lower($frenchText); // Correctly outputs: "école française"
echo Str::title(Str::lower($frenchText)); // Correctly outputs: "École Française"
// Special character example
$germanText = "GROßARTIG";
echo Str::lower($germanText); // Correctly outputs: "großartig"
echo Str::title(Str::lower($germanText)); // Correctly outputs: "Großartig"
To verify these differences, you can run a simple test script:
// Test both approaches
function compareStringHandling() {
$testStrings = [
'ÉCOLE FRANÇAISE',
'САНКТ-ПЕТЕРБУРГ', // Russian
'GROßE FREUDE', // German
'ΚΑΛΗΜΈΡΑ ΚΌΣΜΕ', // Greek
'SANTÉ & ART DE VIVRE'
];
echo "<table border='1'>
<tr><th>Original</th><th>PHP Native</th><th>Laravel Str</th></tr>";
foreach ($testStrings as $str) {
echo "<tr>";
echo "<td>" . htmlspecialchars($str) . "</td>";
echo "<td>" . htmlspecialchars(ucwords(strtolower($str))) . "</td>";
// Use Laravel's Str helper - make sure to include Laravel or the Illuminate\Support package
echo "<td>" . htmlspecialchars(\Illuminate\Support\Str::title(\Illuminate\Support\Str::lower($str))) . "</td>";
echo "</tr>";
}
echo "</table>";
}
// Call the function to see results
compareStringHandling();
Str helper provides clear and intuitive methods.Str::slug(), Str::limit(), and Str::contains(), all fully UTF-8 aware.If you're not using Laravel, you can still achieve proper UTF-8 handling with PHP's multibyte string functions:
// Set internal encoding to UTF-8
mb_internal_encoding('UTF-8');
$frenchText = "ÉCOLE FRANÇAISE";
echo mb_strtolower($frenchText); // Correctly outputs: "école française"
echo mb_convert_case(mb_strtolower($frenchText), MB_CASE_TITLE); // Correctly outputs: "École Française"
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com