Skip to main content
Tutorial

Building a REST API in Laravel That Handles Arabic Text Properly

5 min read

Fix Arabic text encoding in Laravel REST APIs with concrete database and PHP fixes from a developer who spent 4 hours debugging collation errors

Laravel APIArabic text encodingPHP 8.1MySQL 8.0API developmentUAE developer

At 2 a.m. on a Thursday, I was staring at a Laravel API response where Arabic text looked like garbage. "اينمك" instead of "أين مكانك?"—a restaurant location query for a client in Abu Dhabi. This wasn't my first time dealing with Arabic integration, but it reminded me why I keep detailed notes. Turns out PHP 8.1's default mbstring settings were fighting with MySQL 8.0's collation in a way I hadn't expected.

Database Configuration Gotchas

Let's get the boring stuff out of the way first: your MySQL database needs to actually want these accented characters. UTF8MB4 support isn't just checking a box—it requires four specific settings:

  • Character set for the connection (SET NAMES 'utf8mb4')
  • Tables created with COLLATE=utf8mb4_unicode_ci
  • Columns individually set to utf8mb4_unicode_ci
  • The database configuration in Laravel's .env needing DB_CHARSET=utf8mb4 and DB_COLLATION=utf8mb4_unicode_ci

Yes, that means three different layers (connection, table, column) all have to agree. I wasted 4 hours once because a client's migration had forgotten to specify collation on a JSON column—everything looked fine in Postman until someone tested with ة or ل.

Using Raw SQL for Problem Columns

sql
ALTER DATABASE yourDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE yourTable CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

I know Eloquent has tools for this, but sometimes you need brute force when dealing with legacy data from systems that treated Arabic as an afterthought.

Laravel's Hidden Encoder

The framework's JsonResponse class likes to play games. By default, it'll encode your Arabic strings through json_encode, which does UTF-8 handling... unless you're using PHP 8.1's weirdly strict mode. Add these two lines to your AppServiceProvider:

php
'response' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,
'DEFAULT_CHARSET' => 'UTF-8'

Also check your bootstrap/app.php has ->withFacades()—missing that once made Storage URLs break Arabic file names in a real estate project I did for Dubai properties.

Don't Trust Postman's Preview

You'll swear your API is broken until you realize Postman shows raw UTF-8 bytes sometimes. Always test with actual app code from your React Native client (or whatever front end you're using). The Tawasul Limo team had a week-long argument about Arabic directionality that boiled down to "didn't test on the actual iOS app."

Handling Input from Arab Clients

Arabian business users have specific needs. A logistics company in Sharjah once wanted to handle phone numbers like ٠٥٠٥٥٥٥٥٥ (Arabic numerals) but their sales reps sometimes typed 0505555555. We used Normalizer::normalize() from the symfony/polyfill-intl-normalizer package to standardize inputs:

php
use Normalizer;

function normalizeArabic($text) {
    return Normalizer::normalize($text, Normalizer::FORM_KC);
}

This became part of our validation pipeline. For form requests, I often reference Zod Schema Validation: How I Validate API Inputs on Every Project when building the front end too.

Common Validation Needs

  1. Minimum 3 Arabic chars for business names
  2. Mobile number pattern matching both Arabic/Persian numbers
  3. Full-width punctuation cleanup
  4. Sanitizing zero-width joiners from paste input

Encoding Traps After PHP 8.0 Upgrade

Upgrading from PHP 7.4 to 8.1 bit me on two projects. The php8.1-intl extension became required for proper handling—composer install wouldn't warn you, but suddenly str_contains would silently fail with Arabic text. Don't believe the upgrade guides that say "mbstring covers everything."

Had to manually add:

bash
sudo apt install -y php8.1-intl

And restart PHP-FPM. This showed up as a missing intl_get_error_code() during some date parsing with Arabic month names. I ended up writing a blog post about PHP 8.1's encoding changes that gets shared more than I'd expected.

Frequently Asked Questions

Why does Laravel still show question marks in Arabic text?

Your database connection isn't using UTF8MB4. Check DB_CHARSET in .env AND the actual MySQL config. I've had clients with MySQL set correctly but Laravel's cache was holding old settings—try php artisan config:clear.

Can I use varchar(255) for Arabic phone numbers?

Yes but be cautious. Arabic numerals take 4 bytes per digit in UTF-8, so same storage as 255 English chars. But a 12-character Arabic number can take same space as 255 letters—something to watch with indexes. We hit this on a UAE banking app and had to optimize index lengths.

How to handle Arabic URL slugs in Laravel?

Use Str::slug($text, '', 'ar') but watch out for invalid characters. Better to store slugs in ASCII but display Arabic in page titles/meta. DAS Holding's Arabic URLs work this way—slug is always Latin for simplicity.

Does Sanctum work with Arabic in tokens?

Yes for token names, but remember to use rawurlencode() when passing Arabic in URLs. We had a refresh token error with Tawasul Limo because a client's app wasn't encoding Arabic spaces properly.

Contact me through sarahprofile.com/contact for custom APIs or book a free consultation here if you're building a bilingual product in Abu Dhabi or Dubai.

S

Sarah

Senior Full-Stack Developer & PMP-Certified Project Lead — Abu Dhabi, UAE

7+ years building web applications for UAE & GCC businesses. Specialising in Laravel, Next.js, and Arabic RTL development.

Work with Sarah