tecnickcom / tc-lib-unicode
PHP library to process UTF-8 and Unicode text
Fund package maintenance!
Requires
- php: ^8.2
- ext-ctype: *
- ext-mbstring: *
- ext-pcre: *
- tecnickcom/tc-lib-unicode-data: ^3.0
Requires (Dev)
- carthage-software/mago: 1.47.6
- pdepend/pdepend: ^2.16
- phpunit/phpunit: ^11.5 || ^12.5 || ^13.3
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 3.0.7
- 3.0.6
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.11.0
- 2.10.4
- 2.10.3
- 2.10.2
- 2.10.1
- 2.10.0
- 2.9.0
- 2.8.0
- 2.7.0
- 2.6.0
- 2.5.0
- 2.4.0
- 2.3.0
- 2.2.0
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.52
- 2.0.50
- 2.0.49
- 2.0.47
- 2.0.46
- 2.0.45
- 2.0.43
- 2.0.42
- 2.0.41
- 2.0.40
- 2.0.39
- 2.0.38
- 2.0.37
- 2.0.36
- 2.0.35
- 2.0.34
- 2.0.32
- 2.0.31
- 2.0.30
- 2.0.29
- 2.0.28
- 2.0.27
- 2.0.25
- 2.0.24
- 2.0.23
- 2.0.22
- 2.0.20
- 2.0.19
- 2.0.18
- 2.0.17
- 2.0.16
- 2.0.15
- 2.0.14
- 2.0.13
- 2.0.12
- 2.0.11
- 2.0.10
- 2.0.8
- 2.0.7
- 2.0.6
- 1.4.33
- 1.4.32
- 1.4.31
- 1.4.29
- 1.4.28
- 1.4.27
- 1.4.26
- 1.4.25
- 1.4.23
- 1.4.22
- 1.4.21
- 1.4.20
- 1.4.19
- 1.4.18
- 1.4.17
- 1.4.16
- 1.4.15
- 1.4.14
- 1.4.13
- 1.4.12
- 1.4.11
- 1.4.10
- 1.4.9
- 1.4.8
- 1.4.7
- 1.4.6
- 1.4.5
- 1.4.4
- 1.4.1
- 1.4.0
- 1.3.11
- 1.3.10
- 1.3.9
- 1.3.8
- 1.3.7
- 1.3.6
- 1.3.5
- 1.3.4
- 1.3.3
- 1.3.2
- 1.3.0
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.21
- 1.0.20
- 1.0.19
- 1.0.18
- 1.0.17
- 1.0.16
- 1.0.15
- 1.0.14
- 1.0.13
- 1.0.12
- 1.0.11
- 1.0.10
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
This package is auto-updated.
Last update: 2026-09-05 07:37:07 UTC
README
PHP library to process UTF-8 and Unicode text.
💖 Part of the tc-lib-pdf / TCPDF ecosystem (100M+ installs). Sponsor its maintenance →
Overview
tc-lib-unicode converts between UTF-8 strings, character arrays and code point arrays, reorders text with the Unicode Bidirectional Algorithm (UAX #9) and applies script-specific character substitutions.
| Namespace | \Com\Tecnick\Unicode |
| Author | Nicola Asuni info@tecnick.com |
| License | GNU LGPL v3 - see LICENSE |
| API docs | https://tcpdf.org/docs/srcdoc/tc-lib-unicode |
| Packagist | https://packagist.org/packages/tecnickcom/tc-lib-unicode |
Features
Conversion
- Conversions between UTF-8 strings, character arrays and code point arrays
- Latin1, UTF-16BE and hexadecimal string conversions
Bidirectional Support
- Unicode Bidirectional Algorithm (UAX #9), verified against the official
BidiCharacterTest.txtandBidiTest.txtconformance suites - Right-to-left and mixed-direction text processing
- Arabic shaping driven by the Joining_Type property
Character Substitution
- Context-sensitive codepoint-level substitution via
Substitution::replaceChars() - Devanagari: moves left-positional matras (U+093F, U+094E) to precede their base consonant cluster, including conjuncts joined by Virama (U+094D)
- Hangul: composes Hangul Jamo sequences (U+1100-U+11FF, U+A960-U+A97F, U+D7B0-U+D7FF) into precomposed syllables (U+AC00-U+D7A3) per section 3.12 of the Unicode standard
- Thai: returned unchanged, because Thai preposed vowels are already stored in visual order
Requirements
- PHP 8.2 or later
- Extensions:
ctype,mbstring,pcre - Composer
Installation
composer require tecnickcom/tc-lib-unicode
Quick Start
<?php require_once __DIR__ . '/vendor/autoload.php'; $bidi = new \Com\Tecnick\Unicode\Bidi('hello ', null, null, 'R', false); echo $bidi->getString();
Character substitution
Substitution::replaceChars() takes an array of Unicode codepoints and returns a transformed array with script-specific substitutions applied. It is a pure codepoint-level transform with no font or PDF dependency.
<?php require_once __DIR__ . '/vendor/autoload.php'; $sub = new \Com\Tecnick\Unicode\Substitution(); // Devanagari: left matra repositioned before its base consonant cluster // Logical order: [U+0915 KA, U+093F VOWEL SIGN I] // Visual order: [U+093F VOWEL SIGN I, U+0915 KA] $result = $sub->replaceChars([0x0915, 0x093F]); // $result === [0x093F, 0x0915] // Hangul: Jamo composed into a precomposed syllable // [U+1100 KIYEOK, U+1161 JUNGSEONG A, U+11A8 JONGSEONG KIYEOK] → [U+AC01 각] $result = $sub->replaceChars([0x1100, 0x1161, 0x11A8]); // $result === [0xAC01]
Supported scripts and Unicode ranges
| Script | Unicode range(s) | Transformation |
|---|---|---|
| Devanagari | U+0900-U+097F | Left matras repositioned before consonant cluster |
| Hangul Jamo | U+1100-U+11FF, U+A960-U+A97F, U+D7B0-U+D7FF | Jamo composed to precomposed syllables (U+AC00-U+D7A3) |
| Thai | U+0E00-U+0E7F | None: the stored order is the display order |
Codepoints belonging to unsupported scripts are passed through unchanged.
Limitations
- The paragraph separator is emitted at the end of the paragraph output instead of being reset by L1 and reordered by L2, which would place it at the visual left edge of a right-to-left paragraph.
- Rule L3 (combining marks applied to characters shown in a different order) is not implemented.
- Shaping is Arabic only. The other cursive scripts (Syriac, N'Ko, Mandaic, Adlam) are returned unshaped.
BidiandConvertrequire valid UTF-8: malformed byte sequences raise an exception, while code points that cannot be encoded are replaced with '?'.
Development
make deps
make help
make qa
make server
make server serves the example/ directory on http://localhost:8000. Use a custom port with make server PORT=8080.
Packaging
make rpm make deb
For system packages, bootstrap with:
require_once '/usr/share/php/Com/Tecnick/Unicode/autoload.php';
Contributing
Contributions are welcome. Please review CONTRIBUTING.md, CODE_OF_CONDUCT.md, and SECURITY.md.