Como usar os recursos do CodeIgniter fora de um Controller? Ou, como usar o get_instance()?

Olá, feliz 2017!

Já deve ter acontecido de você criar uma biblioteca própria que não estende o CI_Controller ,ou então, criar uma função helper e precisar usar algum recurso nativo do CodeIgniter, como consultar um banco de dados, por exemplo.

Então, vamos imaginar um exemplo bem simples.

Imagine que você tem um relatório e que neste relatório há um select que mostra os anos para o usuário filtrar.

Como criar um select dinâmico somente com os anos que existem no banco de dados?

Uma maneira de resolvermos isto é criarmos este select dinâmico que será preenchido com o menor e maior ano que está lançado no banco de dados, assim, este select irá refletir somente informações que existem no banco de dados.

Criando um helper

O primeiro passo seria criar um helper que faria a criação deste select, para que quando precisássemos dele, bastaria chamá-lo no código.

Crie um arquivo chamado, por exemplo: funcoes_helper.php e salve na pasta helpers dentro de application.

Dentro deste arquivo você pode colocar o seguinte código:

<?php 

function selectAnos() {

    $ano = 2017;
    $ano_final = 2020;    

    $options = "<select name='ano'>";
    $options .= "<option value=''></option>";
    for ($ano ; $ano <= $ano_final ; $ano++) {
        $options .= "<option value='{$ano}'>{$ano}</option>";
    }
    $options .= "</select>";

    return $options;

}
 ?>

Para usar o código acima, basta carregar o seu helper no seu controller, assim: $this->load->helper(“funcoes”); ou no autoloader.php dentro da pasta application/config, depois basta digitar em qualquer lugar: echo selectAnos();

Ao executar o código acima, notaremos que ele funcionará perfeitamente, gerando um select entre os anos 2017 e 2020.

Porém, isto não resolve. E se no banco de dados houver anos inferiores a 2017, ou então superiores a 2020?

Então, o mais correto é nós sabermos quais são os anos que existem lançados no banco de dados e montarmos nosso select em função disto.

Para isto, precisaríamos consultar o banco de dados, porém, se você fizer isto: $this->db->get(“tabela”); dentro do seu arquivo de helper, não vai funcionar, pois o arquivo de helper não é uma classe PHP, e mesmo se fosse, ela não estaria estendendo a classe pai CI_Controller.

O que precisamos agora é trazer para dentro do nosso helper os recursos do CodeIgniter e é aí que entra nosso amigo get_instance();

A função get_instance() simplesmente faz uma referência para o super objeto do CodeIgniter, trazendo nesta referência todos os recursos que o super objeto possui.

Para podermos usar estes recursos precisamos fazer uma atribuição por referência, desta forma;

$CI =& get_instance();

A linha acima faz com que a variável $CI aponte para o mesmo endereço de memória onde está localizado o super objeto do CodeIgniter, por isso que existe aquele =& que nada mais é do que um ponteiro para a posição de memória da variável de origem.

Você pode ver mais detalhes sobre isto na documentação do PHP, aqui.

Agora, nossa variável $CI possui todos os recursos que precisamos do CodeIgniter.

Vamos agora complementar o código para que faça uma consulta a uma tabela no banco de dados que tem nossos lançamentos.

Apenas para fins didáticos, vamos imaginar que existe uma tabela chamada lancamentos e que ela possui 3 campos: id, lancamento e data e que tem os seguintes valores:

 

Tabela Lançamentos
id lancamento data
1 Mercado 2014-10-03
2 Aluguel 2015-03-26
3 Academia 2016-11-13
4 Almoço 2017-01-09

Agora, nosso código deverá ser capaz de identificar qual o menor e maior anos que estão cadastrados nesta tabela.

Aqui não vou criar um model nem configurar banco de dados, pois não é esse o foco do post, vou simplesmente digitar a consulta diretamente no helper.

Porém, você poderia normalmente carregar um model e depois chamar um método dentro dele para trazer os registros do banco de dados.

Nosso código ficaria assim:

<?php 

    //Atribui por referência o super objeto CodeIgniter
    $CI =& get_instance();

    //Agora, não devemos mais usar $this, mas sim $CI

    $menor_ano = $CI->db->select_min("YEAR(data) as ano")->get('lancamentos')->row()->ano;
    $maior_ano = $CI->db->select_max("YEAR(data) as ano")->get('lancamentos')->row()->ano;

    $ano = $menor_ano;
    $ano_final = $maior_ano;

    $options = "<select name='ano'>";
    $options .= "<option value=''>Escolha o ano</option>";
    for ($ano ; $ano <= $ano_final ; $ano++) {
        $options .= "<option value='{$ano}'>{$ano}</option>";
    }
    $options .= "</select>";

    echo $options;


 ?>

Agora, nosso select será gerado entre os anos de 2014 e 2017 automaticamente.

E se entrar um registro novo, de 2018, por exemplo, o select será ajustado automaticamente quando a página for recarregada.

Porém, note que não é possível usar o $this, pois não estamos dentro de uma classe.

Nosso $this foi mudado para $CI, ou qualquer outra variável que você quiser.

Esta variável agora é nosso objeto que possui todos os recursos nativos do CI.

Se você precisasse carregar um model para usar um método dentro dele, você faria assim:

$CI->load->model(“Lancamentos_model”);

$CI->Lancamentos_model->metodoXYZ();

E é isto, você pode usar a função get_instance() em qualquer lugar da sua aplicação que não esteja diretamente dentro do escopo do CodeIgniter, e assim trazer para você tudo aquilo de bom que o CI nos oferece.

Obs.: O exemplo acima não chegou a ser testado, pois tem intuito somente de lhe passar a ideia de como fazer tudo.

Abraços e até o próximo post!

Fabio

Fábio S. Reszko

Sou Programador PHP desde 2006 e eu acredito sinceramente que programar usando um Framework PHP é a solução para os problemas de códigos desorganizados, difíceis de entender e de dar manutenção no futuro. Se você também acredita nisto, então fique à vontade em explorar meu blog.