Download the PHP package italix/i18n without Composer

On this page you can find all versions of the php package italix/i18n. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package i18n

Italix I18n

PHP Version

Translation and formatting on ICU. Plural categories that are correct in Russian, numbers and money the way each locale writes them, and a key extractor that refuses to guess.

Why the rules come from ICU, and why ext-intl is still only suggested

Plural categories are a property of a language, not of a number. Russian has four, Arabic six, Japanese one, and $n === 1 ? 'a' : 'b' is wrong for most of the world — including for 21 in Russian, which takes the one category. So the answers are always ICU's.

They do not always come from ICU at runtime. The official php:8.x images ship without intl, so requiring it was the friction everybody met in their first five minutes. When the extension is present IcuEngine asks it; when it is not, PortableEngine reads tables baked from ICU by ix i18n:bake and answers the same thing. Formatter::engine_code() says which one is answering, and using_engine('portable') forces the other — on a machine with intl the portable branch would otherwise never execute, and code that never executes is code that does not work.

The portable engine refuses what it cannot do honestly — collation, spellout, display names, non-Gregorian calendars — rather than approximating it. Those calls raise a message naming the extension. Everything this README shows below works on both.

Three ways a lookup goes wrong, and none of them break the page

what you get where you find it
missing key the key itself problems()
unparseable message the raw message problems()
missing parameter the placeholder problems()

A screen showing admin.users.title is obviously broken; one showing nothing is a mystery nobody can locate. And throwing would turn a typo in a translation file into a 500 on a page that was otherwise fine.

ix lang:check reports the same information across the whole codebase.

The apostrophe

ICU treats ' as a quoting character, so "L'utente non esiste" loses letters if it goes through the parser. A message with no braces has nothing for ICU to do and is returned as-is — which is why Italian and French messages survive.

Formatting

percent() does not round by default, and that is a deliberate departure. ICU's own percent formatter uses zero fraction digits, so 0.075 comes out as 8% — measured. A rate quietly rounded from 7.5 to 8 is the kind of wrong that reaches an invoice. Pass $decimals_n to narrow it.

Relative time is computed, not worded

PHP's ext-intl does not expose ICU's RelativeDateTimeFormatterIntlRelativeDateTimeFormatter does not exist. Wording it here would mean shipping translations for every language this library claims to support, which is a promise it cannot keep. So it computes and your catalogue words it:

Locales

The chain falls back to a related language before the default one: an Austrian visitor is better served by German than by English.

Catalogues

lang/{locale}/{group}.php, each returning a nested array. messages.php is the default group and contributes no prefix, so the common case reads admin.title rather than messages.admin.title and a project that never needs a second group never meets the concept.

Nesting is flattened once at load. A boolean in a language file is refused, not cast — PHP turns true into "1" and false into "", and either reaches production looking like a translation.

Printing into a page: the two halves of a message

A message has a template, which lives in a file in your repository, and parameters, which routinely come from a column somebody filled in through a form. Only one of the two is trusted, and get() returns a single string that cannot tell them apart:

The second is what a developer reaches for on the day a translator writes <strong>{customer}</strong> and the page shows &lt;strong&gt; in plain sight. It looks like a rendering fix.

e() and choice_e() return Italix\Encode\Html, so composition is decided by the type rather than by the caller remembering: H::e() around one is a no-op, and H::j() around one throws — a JavaScript literal is not an HTML context, and quietly accepting one there is how &amp; ends up inside a string the browser shows to a user.

get(), choice() and format_message() are unchanged and still return plain strings. That is deliberate: the same catalogue serves e-mail subjects, PDFs, CSV files and CLI output, where HTML encoding would be a bug.

Counts go through the encoder like everything else. The obvious worry — that '3' breaks the plural selector — was measured and is false: plural, number, currency and percent all coerce a numeric string identically to the number, scientific notation included. The special case that had been written for it was deleted.

One request routinely needs two languages — the page in the operator's, the e-mail in the recipient's. in() is the primitive and returns a copy, so the surrounding page never moves. Through the facade, where a shared partial has no $t to switch:

The restore is in a finally, because an exception on the way out is exactly the path that would otherwise leave the rest of the request in the recipient's language — and it is the path nobody writes a test for.

group() is the bulk form, for handing a whole branch to something that is not PHP — a client-side validator that needs the sentence for every code a rule can return. Messages come back unformatted, because the parameters are known at the other end.

The extractor

It does not evaluate anything. $t->get($key) and $t->get('admin.' . $suffix) are reported as dynamic. A tool that guessed would produce a missing list containing keys that do not exist, and that list would then be ignored — which is worse than not having one.

The receiver has to be named ($t, $translator, $i18n, $lang, configurable). Matching a bare ->get('…') reported $view->get('main') and $form->get('email') as missing translations — found by running it against a real codebase, not by reasoning about it.

Extractor::untranslated($en, $it) is the translator's worklist; identical() surfaces messages that are the same in both, which is either a real cognate or a line somebody copied and never translated. The tool cannot tell them apart and does not pretend to.

Requirements

php >= 7.4, ext-mbstring, italix/contracts, italix/encode. ext-intl is suggested: with it you get every locale and every formatter, without it the baked tables. Tested against ICU 66.

italix/contracts is a require because Translator implements Italix\Contracts\Translator — an interface that is missing at load time is a fatal error, not a degraded feature. It carries interfaces only and requires nothing itself.

italix/encode is a require rather than a suggest because e() returns one of its types, and a method that fatals when somebody calls it is not an optional feature. It requires only php >= 7.4 itself, so nothing transitive arrives — but it does ship bin/encode-lint, which will appear in vendor/bin whether or not your project has templates.


All versions of i18n with dependencies

PHP Build Version
Package Version
Requires php Version >=7.4
ext-mbstring Version *
italix/contracts Version ^2.0
italix/encode Version ^1.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package italix/i18n contains the following files

Loading the files please wait ...