Il componente Intl

Un rimpiazzo PHP per l’estensione intl C, che fornisce anche accesso ai dati di localizzazione della libreria ICU.

Nuovo nella versione 2.3: Il componente Intl è stato aggiunto in Symfony 2.3. Nelle precedenti versioni di Symfony, va usato il componente Locale al suo posto.

Attenzione

Il rimpiazzo è limitato al locale “en”. Se si vogliono usare altri locale, si dovrebbe invece installare l’estensione intl.

Installazione

Si può installare il componente in due modi:

Se si installa il componente tramite Composer, saranno fornite automaticamente le seguenti classi e funzioni dell’estensione intl, nel caso in cui l’estensione intl stessa non sia caricata:

Quando l’estensione intl non è disponibile, sono usate le seguenti classi, per sostituire quelle di intl:

  • Symfony\Component\Intl\Collator\Collator
  • Symfony\Component\Intl\DateFormatter\IntlDateFormatter
  • Symfony\Component\Intl\Locale\Locale
  • Symfony\Component\Intl\NumberFormatter\NumberFormatter
  • Symfony\Component\Intl\Globals\IntlGlobals

Composer espone automaticamente tali classi nello spazio dei nomi globale.

Se non si usa Composer, ma il componente ClassLoader di Symfony, occorre esporre a mano le classi, aggiungendo le linee seguenti al proprio autoloader:

if (!function_exists('intl_is_failure')) {
    require '/percorso/delle/funzioni/Icu/funzioni.php';

    $loader->registerPrefixFallback('/percorso/delle/funzioni/Icu');
}

Scrivere e leggere i bundle delle risorse

La classe ResourceBundle non è attualmente supportata da questo componente. Invece, sono inclusi un insieme di lettori e scrittori, per leggere e scrivere array (o oggetti simili ad array) da/a file dei bundle delle risorse. Sono supportate le classi seguenti:

Chi fosse interessato all’uso di tali classi può continuare la lettura. Altrimenti, si può saltare la sezione e andare ad Accesso ai dati ICU.

TextBundleWriter

Symfony\Component\Intl\ResourceBundle\Writer\TextBundleWriter scrive un array o un oggetto simile ad array in un bundle di risorse in testo. Il file .txt risultante può essere convertito in un file binario .res con la classe Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompiler:

use Symfony\Component\Intl\ResourceBundle\Writer\TextBundleWriter;
use Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompiler;

$writer = new TextBundleWriter();
$writer->write('/percorso/del/bundle', 'en', array(
    'Data' => array(
        'voce1',
        'voce2',
        // ...
    ),
));

$compiler = new BundleCompiler();
$compiler->compile('/percorso/del/bundle', '/percorso/del/bundle/binario');

Il comando “genrb” della classe Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompiler deve essere disponibile. Se il comando si trova in una posizione non standard, si può passare il suo percorso al costruttore di Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompiler.

PhpBundleWriter

Symfony\Component\Intl\ResourceBundle\Writer\PhpBundleWriter scrive un array o un oggetto simile ad array in un bundle di risorse .php:

use Symfony\Component\Intl\ResourceBundle\Writer\PhpBundleWriter;

$writer = new PhpBundleWriter();
$writer->write('/percorso/del/bundle', 'en', array(
    'Data' => array(
        'voce1',
        'voce2',
        // ...
    ),
));

BinaryBundleReader

Symfony\Component\Intl\ResourceBundle\Reader\BinaryBundleReader legge file binari e restituisce un array o un oggetto simile ad array. La classe attualmente funziona solo con l’estensione intl installata:

use Symfony\Component\Intl\ResourceBundle\Reader\BinaryBundleReader;

$reader = new BinaryBundleReader();
$data = $reader->read('/percorso/del/bundle', 'en');

echo $data['Data']['voce1'];

PhpBundleReader

Symfony\Component\Intl\ResourceBundle\Reader\PhpBundleReader legge file .php e restituisce un array o un oggetto simile ad array:

use Symfony\Component\Intl\ResourceBundle\Reader\PhpBundleReader;

$reader = new PhpBundleReader();
$data = $reader->read('/percorso/del/bundle', 'en');

echo $data['Data']['voce1'];

BufferedBundleReader

Symfony\Component\Intl\ResourceBundle\Reader\BufferedBundleReader avvolge un altro lettore, ma mantiene le ultime N letture in un buffer, dove N è la dimensione passata al costruttore:

use Symfony\Component\Intl\ResourceBundle\Reader\BinaryBundleReader;
use Symfony\Component\Intl\ResourceBundle\Reader\BufferedBundleReader;

$reader = new BufferedBundleReader(new BinaryBundleReader(), 10);

// legge il file
$data = $reader->read('/percorso/del/bundle', 'en');

// restituisce dati dal buffer
$data = $reader->read('/percorso/del/bundle', 'en');

// legge il file
$data = $reader->read('/percorso/del/bundle', 'fr');

StructuredBundleReader

Symfony\Component\Intl\ResourceBundle\Reader\StructuredBundleReader avvolge un altro lettore e offre un metodo readEntry() per leggere un elemento del bundle risorsa senza doversi preoccupare se le chiavi dell’array siano impostate o meno. Se un percorso non può essere risolto, viene restituito null`:

use Symfony\Component\Intl\ResourceBundle\Reader\BinaryBundleReader;
use Symfony\Component\Intl\ResourceBundle\Reader\StructuredBundleReader;

$reader = new StructuredBundleReader(new BinaryBundleReader());

$data = $reader->read('/percorso/del/bundle', 'en');

// provoca un errore se la chiave "Data" non esiste
echo $data['Data']['entry1'];

// restituice null se la chiave "Data" non esiste
echo $reader->readEntry('/percorso/del/bundle', 'en', array('Data', 'entry1'));

Inoltre, il metodo readEntry() risolve i locale a cascata. Per esempio, il locale a cascata di “en_GB” è “en”. Per elementi a valore singolo (stringhe, numeri ecc.), l’elemento sarà letto dal locale a cascata, se non trovato nel locale specifico. Per elementi a valori multipli (array), il valore del locale specifico e di quello a cascata saranno fusi. Per evitare tale comportamento, si può impostare il parametro $fallback a false:

echo $reader->readEntry(
    '/percorso/del/bundle',
    'en',
    array('Data', 'entry1'),
    false
);

Accesso ai dati ICU

I dati ICU si trovano in vari “bundle risorsa”. Si può accedere a un wrapper PHP di tali bundle, tramite la classe statica Symfony\Component\Intl\Intl. Al momento, sono supportati i dati seguenti:

Nomi di lingue e di script

Le traduzioni di nomi di lingue e di script si trovano nel bundle “language”:

use Symfony\Component\Intl\Intl;

\Locale::setDefault('en');

$languages = Intl::getLanguageBundle()->getLanguageNames();
// => array('ab' => 'Abkhazian', ...)

$language = Intl::getLanguageBundle()->getLanguageName('de');
// => 'German'

$language = Intl::getLanguageBundle()->getLanguageName('de', 'AT');
// => 'Austrian German'

$scripts = Intl::getLanguageBundle()->getScriptNames();
// => array('Arab' => 'Arabic', ...)

$script = Intl::getLanguageBundle()->getScriptName('Hans');
// => 'Simplified'

Tutti i metodi accettano il locale come ultimo parametro, opzionale, con valore predefinito il locale predefinito:

$languages = Intl::getLanguageBundle()->getLanguageNames('de');
// => array('ab' => 'Abchasisch', ...)

Nomi di paesi

Le traduzioni di nomi di paesi si trovano nel bundle “region”:

use Symfony\Component\Intl\Intl;

\Locale::setDefault('en');

$countries = Intl::getRegionBundle()->getCountryNames();
// => array('AF' => 'Afghanistan', ...)

$country = Intl::getRegionBundle()->getCountryName('GB');
// => 'United Kingdom'

Tutti i metodi accettano il locale come ultimo parametro, opzionale, con valore predefinito il locale predefinito:

$countries = Intl::getRegionBundle()->getCountryNames('de');
// => array('AF' => 'Afghanistan', ...)

Locale

Le traduzioni di nomi di locale si trovano nel bundle “locale”:

use Symfony\Component\Intl\Intl;

\Locale::setDefault('en');

$locales = Intl::getLocaleBundle()->getLocaleNames();
// => array('af' => 'Afrikaans', ...)

$locale = Intl::getLocaleBundle()->getLocaleName('zh_Hans_MO');
// => 'Chinese (Simplified, Macau SAR China)'

Tutti i metodi accettano il locale come ultimo parametro, opzionale, con valore predefinito il locale predefinito:

$locales = Intl::getLocaleBundle()->getLocaleNames('de');
// => array('af' => 'Afrikaans', ...)

Valute

Le traduzioni di nomi di valute e altre informazioni relative alle valute si trovano nel bundle “currency”:

use Symfony\Component\Intl\Intl;

\Locale::setDefault('en');

$currencies = Intl::getCurrencyBundle()->getCurrencyNames();
// => array('AFN' => 'Afghan Afghani', ...)

$currency = Intl::getCurrencyBundle()->getCurrencyName('INR');
// => 'Indian Rupee'

$symbol = Intl::getCurrencyBundle()->getCurrencySymbol('INR');
// => '₹'

$fractionDigits = Intl::getCurrencyBundle()->getFractionDigits('INR');
// => 2

$roundingIncrement = Intl::getCurrencyBundle()->getRoundingIncrement('INR');
// => 0

Tutti i metodi (tranne getFractionDigits() e getRoundingIncrement()) accettano il locale come ultimo parametro, opzionale, con valore predefinito il locale predefinito:

$currencies = Intl::getCurrencyBundle()->getCurrencyNames('de');
// => array('AFN' => 'Afghanische Afghani', ...)

Questo è tutto quello che occorre sapere, per ora. Buon divertimento con il codice!