terça-feira, 11 de março de 2008

Carregar arquivos de classes automaticamente...

Como costume, separamos as classes em arquivos diferentes, e isso por um lado é bom, pois facilita a organização. Por outro lado, a proliferação de arquivos pode gerar dificuldade na carga das classes necessárias para alguns fins. Este problema ocorre especialmente quando se usa o esquema de instanciação de classes dinâmicas, ou seja, quando criamos objetos de classes especificadas em tempo de execução, como em esquemas de plugins.

O PHP possui um recurso muito interesante, e pouco explorado, que é a carga automática de arquivos sob demanda. Na prática é a carga de um arquivo quando uma classe não-carregada é instanciada - isso na tentativa de carregar o arquivo que contém a definição da classe em questão. É claro que neste arquivo a dita-cuja não estiver presente, será emitido um erro.
O recurso é o __autoload(). Atenção: lembre-se que os métodos que iniciam com dois underscores são chamadas de 'funções mágicas').

A __autoload() (bem descrita no http://br2.php.net/manual/pt_BR/language.oop5.autoload.php), é definido pelo usuário e recebe como parâmetro o nome da classe que está sendo instanciada. Dentro desta função, você pode fazer o que for necessário para achar o arquivo. Com isso você tem a liberdade de procurar em vários diretórios o arquivo que bata com o padrão de nome definido.

Três problemas que vejo no uso do __autoload() são:
  • Em primeiro lugar, o fato de não explicitar a inclusão do arquivo abre precedentes de risco de segurança, uma vez que alguém pode criar um arquivo no padrão em um diretório que será procurado pelo script antes de onde realmente reside o referido, e com isso comprometer a integridade do sistema.
    • Mas isso é difícil de acontecer
  • O segundo motivo é a dificuldade de manter um código que usa uma classe que só-Deus-sabe onde está localizada.
    • Para evitar isso, é necessário uma boa organização do código e da localização das classes.
  • Por fim, o terceiro e mais importante, na minha opinião, é que se for necessário o uso do __autoload() mais de uma vez no mesmo projeto, o interpretador emitirá um erro fatal - ou seja, ele não vai funcionar. Isso pode ocorrer especialmente quando se usa frameworks de apoio de terceiros, onde eles podem ter feito uso do __autoload().
    • Para solucionar este problema, foi criada a função 'spl_autoload_register()', que funciona igual ao '__autoload()', só que permite o 'empilhamento' das funções que serão invocadas quando na instanciação de uma classe não-carregada.
Veja maiores detalhes em http://br2.php.net/manual/pt_BR/function.spl-autoload-register.php , e/ou o capítulo 7, seção 7.1 do livro 'PHP5 in Practice'

Nenhum comentário: