<sect1 id="zend.loader.load">

    <title>Caricamento dinamico di file e classi</title>

    <para>
        La classe Zend_Loader include metodi per aiutare il caricamento dinamico di file.
    </para>

    <tip>
        <title>Zend_Loader contro require_once()</title>
        <para>
            I metodi di <code>Zend_Loader</code> sono la scelta migliore se il nome del file da caricare è variabile.
            Per esempio, se è basato su un parametro immesso da un utente o l'argomento di un metodo.
            Se si sta caricando un file o una classe dove il nome è costante, non c'è alcun beneficio nell'utilizzo di <code>Zend_Loader</code> rispetto all'uso delle funzioni PHP tradizionali come
            <ulink url="http://php.net/require_once"><code>require_once()</code></ulink>.
        </para>
    </tip>

    <sect2 id="zend.loader.load.file">

        <title>Caricamento di file</title>

        <para>
            Il metodo statico <code>Zend_Loader::loadFile()</code> carica un file PHP.
            Il file caricato può contenere qualsiasi codice PHP.
            Questo metodo è un wrapper per la funzione PHP
            <ulink url="http://php.net/include"><code>include()</code></ulink>.
            Genera un'eccezione <code>Zend_Exception</code> in caso di errore ad esempio se il file specificato non esiste.
        </para>

        <example id="zend.loader.load.file.example">
            <title>Esempio del metodo loadFile()</title>
            <programlisting role="php"><![CDATA[<?php
Zend_Loader::loadFile($filename, $dirs=null, $once=false);]]>
            </programlisting>
    </example>

        <para>
            Il parametro <code>$filename</code> specifica il nome del file da caricare, che non deve contenere alcuna indicazione di un percorso.
            Un controllo di sicurezza è eseguito su <code>$filename</code>.
            <code>$filename</code> può contenere unicamente caratteri alfanumerici, trattini ("-"), underscore ("_") o punti (".").
            Nessuna di queste restrizioni è applicata al parametro <code>$dirs</code>.
        </para>

        <para>
            Il parametro <code>$dirs</code> specifica le cartelle nelle quali cercare il file.
            Se <code>NULL</code>, la ricerca è eseguita solo nei percorsi contenuti in <code>include_path</code>.
            Se una stringa o un array, la ricerca è eseguita nella cartella o nelle cartelle specificate, quindi in <code>include_path</code>.
        </para>

        <para>
            Il parametro <code>$once</code> è un booleano.
            Se <code>TRUE</code>, <code>Zend_Loader::loadFile()</code> utilizza la funzione PHP
            <ulink url="http://php.net/include"><code>include_once()</code></ulink>
            per caricare il file, altrimenti è utilizzata la funzione PHP
            <ulink url="http://php.net/include_once"><code>include()</code></ulink>.
        </para>

    </sect2>

    <sect2 id="zend.loader.load.class">

        <title>Caricamento di classi</title>

        <para>
            Il metodo statico <code>Zend_Loader::loadClass($class, $dirs)</code> carica un file PHP ed esegue un controllo sull'esistenza della classe.
        </para>

        <example id="zend.loader.load.class.example">
            <title>Esempio del metodo loadClass()</title>
            <programlisting role="php"><![CDATA[<?php
Zend_Loader::loadClass('Container_Tree',
    array(
        '/home/production/mylib',
        '/home/production/myapp'
    )
);]]>
            </programlisting>
        </example>

        <para>
            La stringa che specifica la classe è convertita in un percorso relativo sostituendo i separatori di cartella ai caratteri di underscore ("_") ed appendendo l'estensione '.php'.
            Nell'esempio precedente 'Container_Tree' diventa 'Container\\Tree.php'.
        </para>

        <para>
            Se <code>$dirs</code> è una stringa o un array, <code>Zend_Loader::loadClass()</code> esegue la ricerca nelle cartelle nell'ordine indicato.
            Il primo file trovato viene caricato.
            Se il file non esiste in <code>$dirs</code> allora la ricerca è eseguita in <code>include_path</code>.
        </para>

        <para>
            Se il file non è trovato o la classe non esiste dopo il caricamento, <code>Zend_Loader::loadClass()</code> genera un'eccezione <code>Zend_Exception</code>.
        </para>

        <para>
            Il metodo <code>Zend_Loader::loadFile()</code> è utilizzato per il caricamento del file, dunque il nome della classe può contenere solo caratteri alfanumerici, trattini ("-"), underscore ("_") o punti (".").
        </para>

    </sect2>

    <sect2 id="zend.loader.load.isreadable">

        <title>Verifica del permesso di lettura di un file</title>

        <para>
            Il metodo statico <code>Zend_Loader::isReadable($pathname)</code> restituisce <code>TRUE</code> se il file al percorso specificato esiste ed è leggibile, altrimenti <code>FALSE</code>.
        </para>

        <example id="zend.loader.load.isreadable.example">
            <title>Esempio del metodo isReadable()</title>
            <programlisting role="php"><![CDATA[<?php
if (Zend_Loader::isReadable($filename)) {
    // fai qualcosa con $filename
}]]>
            </programlisting>
        </example>

        <para>
            Il parametro <code>$filename</code> specifica il nome del file da verificare.
            Può contenere l'indicazione di un percorso.
            Questo metodo è un wrapper per la funzione PHP
            <ulink url="http://php.net/is_readable"><code>is_readable()</code></ulink>.
            La funzione PHP non esegue la ricerca nelle cartelle indicate da <code>include_path</code>,
            contrariamente a <code>Zend_Loader::isReadable()</code>.
        </para>

    </sect2>

    <sect2 id="zend.loader.load.autoload">

        <title>Utilizzo dell'autoloader</title>

        <para>
            La classe <code>Zend_Loader</code> contiene un metodo che è possibile registrare nella libreria PHP SPL autoloader.
            <code>Zend_Loader::autoload()</code> è il metodo di callback.
            Per comodità, <code>Zend_Loader</code> fornisce la funzione <code>registerAutoload()</code> per registrare automaticamente il proprio metodo <code>autoload()</code>.
            Se l'estensione <code>spl_autoload</code> non è presente nell'ambiente PHP, il metodo <code>registerAutoload()</code> genera un'eccezione <code>Zend_Exception</code>.
        </para>

        <example id="zend.loader.load.autoload.example">
            <title>Esempio di registrazione del metodo di callback autoloader</title>
            <programlisting role="php"><![CDATA[<?php
Zend_Loader::registerAutoload();]]>
            </programlisting>
        </example>

        <para>
            Dopo aver registrato il metodo di callback autoload del Framework Zend, è possibile referenziare le classi del framework senza la necessità di caricarle esplicitamente.
            Il metodo <code>autoload()</code> utilizza <code>Zend_Loader::loadClass()</code> in automatico ogni volta che una classe è referenziata.
        </para>

        <para>
            Se si estende la classe <code>Zend_Loader</code> è possibile passare un parametro opzionale al metodo <code>registerAutoload()</code> per specificare la classe dalla quale registrare il metodo <code>autoload()</code>.
        </para>

        <example id="zend.loader.load.autoload.example-extended">
            <title>Esempio di registrazione del metodo di callback autoloader di una classe estesa</title>
            <para>
                A causa della semantica del referenziamento delle classi statiche in PHP, è necessario implementare il codice per entrambi i metodi <code>loadClass()</code> ed <code>autoload()</code>, ed il metodo <code>autoload()</code> deve chiamare <code>self::loadClass()</code>.
                Se il proprio metodo <code>autoload()</code> delega al metodo genitore la chiamata a <code>self::loadClass()</code>, allora chiama il metodo con lo stesso nome nella classe genitore, non nella sottoclasse.
            </para>
            <programlisting role="php"><![CDATA[<?php
class Mio_Loader extends Zend_Loader
{
    public static function loadClass($class, $dirs = null)
    {
        parent::loadClass($class, $dirs);
    }

    public static function autoload($class)
    {
        try {
            self::loadClass($class);
            return $class;
        } catch (Exception $e) {
            return false;
        }
    }
}

Zend_Loader::registerAutoload('Mio_Loader');]]>
            </programlisting>
        </example>

        <para>
            E' possibile rimuovere un autoload callback.
            Il metodo <code>registerAutoload()</code> ha un secondo parametro opzionale, che corrisponde a <code>TRUE</code> per impostazione predefinita.
            Se il parametro ha valore <code>FALSE</code> allora il callback è rimosso dalla pila degli autoload SPL al posto di essere registrato.
        </para>

    </sect2>

</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
