Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

Don’t Use strtolower(): Why Laravel’s String Functions Are Better

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.

What's Wrong with PHP's Native String Functions?

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.

Why Laravel's Str Helper Is a Better Choice

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"

How to Test This Yourself

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();

Why the Laravel Str Helper Is Superior

  1. UTF-8 Compatibility: Laravel's string methods handle international characters correctly out of the box.
  2. Consistent and Fluent API: The Str helper provides clear and intuitive methods.
  3. Method Chaining: Easily chain multiple string operations together for cleaner, readable code.
  4. Extra Features: The helper includes useful functions like Str::slug(), Str::limit(), and Str::contains(), all fully UTF-8 aware.
  5. Integration with Laravel: Leveraging Laravel's built-in tools ensures better compatibility and maintainability.

Alternative: Using PHP's Multibyte Functions Directly

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"
What I'm building

Delegate tasks. Get software.

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

Subscribe to my newsletter

Get new posts when I publish them.

I respect your privacy. Unsubscribe at any time.

Leave a Reply

Your email address will not be published. Required fields are marked *