HMVC no CodeIgniter com Modular Extensions

1 de novembro de 2010, em Tutoriais, por

Já vimos, no estudo sobre o padrão MVC, que todos frameworks modernos utilizam a abordagem de Model-View-Controller para separar o acesso ao banco de dados, a apresentação e o controle de toda a aplicação; e também vimos como models, views e controllers trabalham juntos no CodeIgniter. Essa é a base de funcionamento do CodeIgniter. Nada além, nada aquém.

Mas, além do MVC, existem uma abordagem diferente, considerada, por alguns, como uma evolução a esse consagrado padrão. Trata-se do Hierarquical Model-View-Controller (Model-View-Controller Hierárquico), mais conhecido como HMVC!

O CodeIgniter atualmente não apresenta suporte nativo ao padrão HMVC, portanto,, caso se queira usufruir de seus benefícios, é preciso se valer de códigos da comunidade. Neste artigo, ensinaremos como dar suporte ao HMVC no CodeIgniter usando o Modular Extensions.

Sobre o HMVC

O HMVC é tido como uma evolução do MVC. Basicamente, é como se a estrutura básica de funcionamento do CodeIgniter tivesse um nível hierárquico acima, “englobando” cada tríade MVC, tornando-a modular e, até certo ponto, independente das demais.

Em outras palavras: com HMVC é possível ter “pacotinhos” de models, views e controllers independentes, que funcionam separadamente de outros “pacotinhos”, mas que podem se comunicar com todos eles. É como mostra a seguinte imagem:

CodeIgniter: HMVC

Estrutura HMVC no CodeIgniter

HMVC no CodeIgniter

A primeira coisa a se fazer para implementar o HMVC no CodeIgniter é fazer download do Modular Extensions. Depois de baixá-lo, você verá que existem 2 pastas no arquivo compactado: “core” e “third_party“. Proceda da seguinte maneira:

  • Coloque a subpasta “MX” (dentro de “third_part”) no diretório “application/third_party”
  • Coloque os arquivos da pasta “core” (não a própria pasta!) dentro de “application/core”
  • Crie a pasta “modules” dentro da pasta “application”

Pronto, agora você já tem uma estrutura HMVC no CodeIgniter!

Atenção para algo muito importante: ao implementar a estrutrura de HMVC no CodeIgniter com o Modular Extensions, você abre mão da estrutura tradicional do CI. A partir de agora, você deve criar subdiretórios dentro de “modules” com seus “pacotinhos” de tríades MVC. Ou seja, a partir de agora, os diretórios “models”, “views” e “controllers”, que ficam dentro da pasta “application”, não mais necessitam ser usados.

Com HMVC, toda a interação do CI deve ser feita pelo diretório “modules”.

Por exemplo, vamos supor que você utilize uma tríade para exibição de livros de um site ou sistema virtual, qualquer. Neste caso, poderia usar uma estrutura como esta:

  • application/modules/livros/
  • application/modules/livros/controllers/
  • application/modules/livros/models/
  • application/modules/livros/views/

E, dentro dessa estrutura, mexer normalmente com os models, views e controllers. Em relação à estrutura de URLs, nada se altera; dentro do exemplo, se tivéssemos um controller “listar” dentro de application/modules/livros/controllers/, este seria acessado via (usando a técnica explicada no artigo Dicas básicas de configuração do CodeIgniter para retirar o segmento “index.php”):

http://www.site.com.br/livros/listar/

Quanto à configuração de $route['default_controller'] em application/config/routes.php, pode ficar tranquilo, já que, também, nada se altera: coloque o nome do controller e pronto.

Conclusão sobre HMVC no CodeIgniter

Talvez as maiores vantagens da abordagem HMVC sejam a praticidade e facilidade de reaproveitamento de códigos. Para o caso de um módulo desenvolvido precisar ser usado em outro projeto, simplesmente copie o módulo em questão e cole na nova instalação do CodeIgniter (provida de HMVC e mesma estrutura de banco de dados, obviamente) e pronto! Nada mais precisa ser feito!

Não é só porque o HMVC é considerado como uma “evolução” por alguns que seja preciso utilizá-lo em todo e qualquer projeto. Entretanto, a praticidade de se usar módulos prontos de outros projetos é notável e pode, sim, fazer a diferença num cumprimento de um prazo mais apertado! Se for o caso, não hesite em se valer da praticidade do padrão HMVC!

66 comentários em "HMVC no CodeIgniter com Modular Extensions"

gravatar

Marcelo Wanderley  em 7 de novembro de 2010

Ola pessoal.

Seria bastante interessante mostrar a integração do CodeIgniter2 com DocTrine2.

Acho que não sou o único que tem essa duvida.

E acho bastante viável a integração de um ORM com o CodeIgniter.

Seria ótimo. Principalmente se estiver exemplos de relacionamento. Estou quebrando a cabeça para isso.

Abraços,
Marcelo Wanderley

gravatar

Tárcio Zemel  em 8 de novembro de 2010

Excelente sugestão, Marcelo! Por enquanto, estamos seguindo uma "linha evolutiva", aumentando a complexidade dos artigos aos poucos. Quando chegar o momento oportuno, seguiremos sua sugestão e faremos uma série ensinando como realizar este tipo de integração!

Abraços e obrigado!

gravatar

Tárcio Zemel  em 20 de novembro de 2010

É como eu havia respondido ao seu outro comentário no artigo sobre as diferenças entre helper, library e plugin no CodeIgniter: é tanta coisa que, de repente, dar uma olhada no change log do CodeIgniter 2 valha a pena.

De qualquer maneira, assim que a versão for oficialmente lançada, faremos um artigo com um resumo das mudanças mais significativas.

Abraços!

gravatar

William Lopes  em 7 de dezembro de 2010

Opa, muito bom seu artigo. Eu sinceramente acho o padrão MVC meio "bagunçado", depois destas explicações vou partir agora para o HMVC no CodeIgniter.

Você saberia dizer em quanto tempo mais ou menos a versão 2 do CodeIgniter será lançada?

Abraços!

gravatar

Diego Carvalho  em 9 de dezembro de 2010

Opa cara, ainda sou novo no CI mas achei muito legal essa estrutura com modulos.
Alguns frameworks "caseiros" usam essa idéia de modulos que acho sensacional.

Minha dúvida seria sobre o front-end. Onde ficariam os scripts e css relacionados somente aquele modulo. Penso que seria legal na view mas não sei se é o melhor.

Parabens pelo artigo.
=D

gravatar

William Lopes  em 12 de dezembro de 2010

Olá Diego Carvalho, você é novo só no CI ou em POO também?

Te recomendo não misturar js, css, etc nas views não. Eu crio uma pasta chamada "public" na raíz do web site e depois crio uma constante chamada "BASEPUBLIC" com o caminho para a pasta criada. Isso deixa muito mais organizado.

Espero ter te ajudado, abraços!

gravatar

Bruno Urbano  em 30 de dezembro de 2010

Dê uma olhada, talvez possa te ajudar http://wildlyinaccurate.com/integrating-doctrine-

gravatar

Tárcio Zemel  em 1 de fevereiro de 2011

Acabou de ser lançada! Confira o artigo "CodeIgniter 2".

gravatar

Tárcio Zemel  em 1 de fevereiro de 2011

Isso que o Willian falou é bastante interessante! Certamente é uma boa dica a ser seguida!

gravatar

Neto  em 19 de fevereiro de 2011

Com certeza, e por coincidência, eu faço a mesma coisa (e a pasta tem até o mesmo nome!!!).
Colocar esses arquivos dentro das views é errado por dois motivos:
1 – Falha de segurança, pois no código fonte da aplicação você estará revelando sua estrutura de arquivos.
2 – Caso os arquivos da aplicação sejam colocados em algum lugar que não seja possível acessar pela url (como acima da public_html por example), já era!

Para crier essay constant, basta monitor:
FCPATH.'public/'
Pronto.
Já que o papo é HMVC, os arquivos desse tipo poderiam ficar assim:
public/moduleX/css/
public/moduleX/js/
public/moduleX/img/
public/moduleY/css/
public/moduleY/js/
public/moduleY/img/

Mas acho meio bagunçado, já que toda a aplicação terá uma mesma interface, é certo que haverão imagens, estilos repetidos e isso não é legal. É melhor colocar na cabeça que esse "pattern" é uma solução para o server-side. e que a interface sera feita na "tora".

gravatar

William Lopes  em 7 de março de 2011

Opa, tudo bem aí Tárcio?

Deixa eu te perguntar porque tenho que passar um projeto meu aqui para o novo CI, daí surgiu uma dúvida, para o CI 2.0 faz a instalação do mesmo modo? E com os mesmos arquivos?

Abraços!

gravatar

William Lopes  em 18 de março de 2011

Eu estava falando do HMVC apenas.

Mas ta valendo, abraços!

gravatar

acsar  em 16 de junho de 2011

Olá Tárcio,
Segui os procedimentos acima (estou utilizando CI_2.02).
Dentro de modules, tenho duas pastas: admin e default cada qual com pastas controllers, views e models.
No config fiz: $route['default_controller'] = "default/home"; onde 'home' é meu controller dentro da pasta default. Até ai funciona blz, porém se digito: meu_site/welcome (welcome = controller dentro de default. da 404 do Apache!
Grande abraço

gravatar

Joelson  em 25 de julho de 2011

Ola tbm sou novato no CI, mas estou tentando usa o HMVC num projeto meu. O problema é que em relação aos arquivos de css, js e imagens, o arquivo não são chamados, pq esta dando um erro de permissão de acesso 403, e eu não consigo resolver isto. Alguem sabe como eu resolvo isto, deve ser algo obvio más não faço a menor ideia de como resolver. lembro que numa versão do mesmo projeto sem HMVC, os arquivos de css, js e imagem, funcionam

gravatar

Tárcio Zemel  em 2 de agosto de 2011

Olá, Joelson.

Implementar o HMVC no CI nada tem a ver com esse erro. Confira as configurações do seu servidor para ver se está tudo ok.

Abraços!

gravatar

André  em 21 de agosto de 2011

Muito bom o Link e o artigo também… parabéns

gravatar

Tárcio Zemel  em 22 de agosto de 2011

Obrigado, André! Apareça sempre!

gravatar

Raphael Calintro  em 22 de setembro de 2011

É uma boa. Outra alternativa é usar a tag base do próprio HTML no topo da sua view (normalmente eu tenho um topo só), ficando assim:

<base href="<?=base_url()?>" />

Aí pra linkar qualquer coisa:

<img src="assets/img/imagem.jpg" alt="Imagem" />

gravatar

Alexandre Muniz  em 19 de dezembro de 2011

To fazendo um projeto, integrando code 2 com datamapper. Tive problema nessa library ao integrar com HMVC..mas com um ajuste pontual foi possivel utilizar esse conceito, que eu considero uma evoluçao bastante considerável. Vo começar a seguir essa linha em meus projetos..Parabens pelo post..abraço.

gravatar

Tárcio Zemel  em 20 de dezembro de 2011

Muito bom!

Legal você citar o DataMapper porque, assim que possível, farei uma série sobre ele por aqui.

Abraços!

gravatar

yarkhan  em 14 de janeiro de 2012

As últimas versões estáveis do Codeigniter, do Datamapper e do HMVC são totalmente compatíves uma com a outra, vale a pena conferir.

gravatar

Tárcio Zemel  em 17 de janeiro de 2012

Pois é, essa trinca é praticamente indispensável para projetos a partir do nível "básico"! hehe

gravatar

Sitjunior  em 25 de fevereiro de 2012

Estou testando o Modular Extensions e estou tendo algumas dificuldades com ele.

Se eu colocar um model dentro de um pacote, é possível acessá-lo por outro?

gravatar

Tárcio Zemel  em 27 de fevereiro de 2012

Sim, é possível! :-)

gravatar

Tárcio Zemel  em 27 de fevereiro de 2012

Não entendi muito bem, já que você citou o controller "home" e tá querendo acessar "welcome"… E se você não tiver controllers com nomes iguais, nem precisa colocar o "default/home"; ele já entende só de colocar "home".

Abraços!

gravatar

Junir  em 3 de março de 2012

Meu amigo, cuidado, ao usar texto indique sempre o autor
http://ti-developer.blogspot.com/2010/11/hmvc.htm

gravatar

Tárcio Zemel  em 5 de março de 2012

Cuidado, você, ao acusar alguém… O cara que ripou o artigo não se deu ao trabalho nem de apagar os links aos outros artigos aqui do blog.

gravatar

Renato  em 30 de março de 2012

Ola Joelson, crie um arquivo .htaccess com "Allow from all" dentro, salve na pasta do css.

gravatar

Lucas  em 9 de abril de 2012

O Tárcio viu o post do cara, achou fantástico, viajou no tempo e postou aqui 5 dias antes do cara postar no blog dele.
Super plausível pra mim.

gravatar

diangelisj  em 4 de junho de 2012

Tenho que comentar… O cara do blogspot é simplesmente um retardado! sem base. =)

gravatar

Francis  em 9 de junho de 2012

Pessoal, seria interessante mostrar na prática como é criar uma app, desde um menu com submenu, até mesmo páginas, módulos de comentários, busca, avaliações, estaticas e dinamicas, pois na minha opinião, hooks é o conceito mais difícil de se encontrar material pra estudo..

gravatar

Tárcio Zemel  em 12 de junho de 2012

Com certeza ajudaria bastante, Francis, mas este conteúdo ficaria tão extenso que, na verdade, daria até um livro! Hummm… OK, vou escrever um livro! ;-)

gravatar

Amilton Aquino  em 16 de junho de 2012

Olá Tárcio! Esta também é a minha dúvida. Não sei como acessar uma model de um outro módulo. Acho que esta é uma das principais dúvidas de quem começa a usar Extensões Modulares.

gravatar

Tárcio Zemel  em 18 de junho de 2012

Não tem que fazer nada de diferente. Basta instanciar o novo model, normalmente, assim como se faria caso não se estivesse trabalhando com HMVC. ;-)

gravatar

Ricardo Mendes  em 21 de agosto de 2012

Olá pessoal.

Eu publiquei um artigo falando sobre isso:
http://imasters.com.br/artigo/25199/codeigniter/c

Espero que seja util!

Abraços

gravatar

Wanderson Scopel  em 24 de agosto de 2012

Tárcio parabens pelo blog… estou com uma duvida, eu defini assim:
$route['default_controller'] = "home"; e meu acesso ficou assim:
http://localhost:89/code2/home porem estou criando uma pasta para colocar a administracao do meu site em uma pasta chamada administracao dentro da modules/administracao/meumodulo porem quando acesso http://localhost:89/code2/administracao da 404 Page Not Found… sabe me dizer onde estou esquecendo de configurar? abracos

gravatar

Tárcio Zemel  em 6 de setembro de 2012

Oi, Wanderson! Tudo bom?

Na verdade, o processo não funciona com "modules/administracao/meumodulo". Usando esta estrutura, "administracao" já é um módulo, em si. Dentro dele que você deve colocar "controllers", "models" e "views", entendeu?

Abraços!

gravatar

edyonil  em 25 de outubro de 2012

Poxa, achei muito interessante. Mas Tárcio, me diga uma coisa. O que você recomenda: O uso do MVC do CI ou essa expansão do HMVC?

gravatar

Tárcio Zemel  em 30 de outubro de 2012

Opa, Edyonil! Já conversamos no Google+ sobre, mas, para os outros colegas que tenham a mesma dúvida, minha opinião é: https://plus.google.com/113803733192283872057/pos

gravatar

Fabiano  em 12 de novembro de 2012

Não seria mais fácil usar o padrão do Zend no CI?
Ele faz tipo
application/controller/livros
application/model/livros
application/view/livros

Não é uma verdade absoluta, mas gostaria de saber qual a forma ideal e pros e contras de uma ou outra.

gravatar

Tárcio Zemel  em 13 de novembro de 2012

Eu não conheço como se faz no Zend, mas, pelo menos num primeiro momento, não vi vantagens em ficar acessando models e views via URL (e não estou falando somente no "engessamento" de todos terem que ter o mesmo nome)…

gravatar

Fabiano  em 11 de dezembro de 2012

Esse plugin foi descontinuado? Não consigo baixar e no repositório não tem nada no download:
https://bitbucket.org/wiredesignz/codeigniter-mod

gravatar

Tárcio Zemel  em 11 de dezembro de 2012

Descontinuado não foi, mas, realmente, a parte de download no Bitbucket está com problema… Faz o seguinte, baixa na aba "Source", mesmo, até eles darem um jeito nisso.

Att

gravatar

Fabiano  em 17 de dezembro de 2012

Não tem nenhum modelo conhecido no github?

gravatar

Tárcio Zemel  em 27 de dezembro de 2012

Não precisa, é só ver como fica a estrutura depois da instalação. Tem um exemplo no próprio artigo.

gravatar

Jorge  em 10 de março de 2013

Olá,

Já utilizo o Code Igniter com HMVC, é muito prático.
Porém estou tendo dificuldades para criar sistemas grandes e manter a organização.

Por exemplo, eu tenho alguns módulos que são no sistema os módulos principais, ex.: Acadêmico, Financeiro, etc (quem já mexeu com ERP sabe do que falo).

Então eu tentei fazer de uma maneira que não consegui:

Ex.:
-applications
-modules
-academico
-controllers
-models
-views
-alunos
-controllers
-models
-views
-pais
-controllers
-models
-views
-materiais
-controllers
-models
-views
-financeiro

Eu criei a estrutura desta forma para ter uma URL mais amigável, mas deste jeito não funciona.
Quando executo meusite.com.br/academico/alunos/gerenciar, eu gostaria de ver o gerenciamento de
alunos, porém o CI entende como academico sendo o controller, alunos sendo o método e gerenciar o parâmetro.

Alguém tem idéia como fazer com que outras pastas sejam entendidas como MVC também, como expliquei acima?

Grato!

gravatar

Jorge  em 10 de março de 2013

Desculpem, ficou sem indentação, sobre o post anterior é assim o exemplo:

Ex.:
-applications
–modules
—-academico
——controllers
——models
——views
—-alunos
——controllers
——models
——views
—-pais
——controllers
——models
——views
—-materiais
——controllers
——models
——views
—-financeiro

gravatar

Tárcio Zemel  em 13 de março de 2013

A maneira como o CI está "entendendo" é correta. Com HMVC só muda a estrutura dos diretórios/arquivos, mas o funcionamento é o mesmo.

Ou você cria um controller inicial que vai receber todas as requisições e, a partir da análise de URL, vai direcionar corretamente; ou começa a mexer com _remap().

gravatar

Jackson  em 14 de março de 2013

Olá Tárcio,
Primeiramente parabéns pelo post,
porem eu tive uma duvida sobre, se nessa jeito de desenvolvimento, um modulo não acessa os models de um outro modulo?

por exemplo se eu tiver um modulo de orçamento, eu posso reaproveitar o model do modulo de produtos ou teria que reescrever o que eu necessito do modulo de produto dentro de orçamento?

gravatar

Tárcio Zemel  em 15 de março de 2013

Acessa normalmente! A conveniência fica só na estruturação do projeto; o uso do framework não se altera.

gravatar

Jackson  em 15 de março de 2013

então do module/orcamento/controller/orcamento eu consigo acessar o module/produto/model/produto?

se sim acho que peguei uns arquivos que não funcionam corretamente

através do link q vc disponibilizou nao consegui fazer download, mas vou tentar novamente mais tarde

gravatar

Tárcio Zemel  em 15 de março de 2013

Consegue, sim! Mas, na hora de carregar o módulo, não precisa colocar "modules/whatever" no caminho; faça como faria normalmente.

gravatar

Jackson  em 15 de março de 2013

sim, só coloquei as pastas pra enfatizar q estavam em módulos diferentes :)

gravatar

Jackson  em 15 de março de 2013

obrigado :)

gravatar

Tárcio Zemel  em 15 de março de 2013

=)

gravatar

Lucas Soares  em 16 de abril de 2013

Ola,
Estou começando a estudar pra começar a utilizar o codeigniter e gostaria de saber o seguinte. A ideia de modulo, por exemplo em um desenvolvimento de sistema, se refere a um unico sistema ou eu posso pensar q cada modulo seria um sistema especifico para cada setor, por exemplo, modulo1 (setor RH), modulo 2 (lista de ramais), e assim por diante…….Essa ideia eh correta? Parabens pelo post e pelo site….Sao essas iniciativas q faz a direfenca.

gravatar

Tárcio Zemel  em 18 de abril de 2013

Na verdade, vai da sua maneira de organizar o projeto. Fazendo dessa maneira que você disse, vai funcionar, mas também pode ser feito de N outras maneiras.

Uma das vantagens do CI é que ele é bastante flexível quanto à sua estrutura, então, fala da maneira que achar que vai ficar melhor para este projeto, em especial.

Abraços!

gravatar

marcelo  em 4 de julho de 2013

Gostaria de saber como ficaria a questão de classes estendidas.
Pois eu normalmente gero um padraoModel.php e lá eu coloco vários itens que automatizam o processo no banco de dados e todos os models possuem uma extensão dele.

Eu precisaria fazer algo do tipo class Restaurante_model extends PadraoModel

Abraços.

gravatar

daniel  em 22 de julho de 2013

Quem tiver mais dúvidas sobre como projetar com HMVC, tem um gringo chamado David Connely que postou no YouTube uma série de vídeos que ensinam como trabalhar com essa arquitetura: http://www.youtube.com/watch?v=8fy8E_C5_qQ
Espero que ajude!

gravatar

Francis  em 31 de julho de 2013

Bom, não precisaria escrever um livro, mas poderia abordar os principais pontos pra fazer um HMVC funcionar com banco de dados ou autoload, por exemplo, para carregar em qualquer lugar do sistema como se fosse um widget.

É isso que nós precisamos! ;)

gravatar

Tárcio Zemel  em 31 de julho de 2013

Continua a mesma coisa. Continua sendo PHP OO. :-)

gravatar

Marcelo Silva  em 13 de setembro de 2013

Vou migrar meu sistema todo para codeigniter padrão HMVC e tenho uma pequena dúvida: qual a melhor maneira de chamar views comuns a todos os módulos?

Crio um módulo "default" de dentro da pasta VIEW desse módulo eu chamo normalmente com o $this->load->view('topo')?

Qual a melhor maneira? Acho que do jeito que eu disse funciona, mas fica parecendo gambiarra… rs.

A tempo: parabéns pelo blog. Tem me ajudado bastante.

gravatar

Felipe  em 25 de outubro de 2013

Como faria para fazer submodulos…

Exemplo:

Dentro do módulo RH ter o módulo funcionario..
Seria possível essa estrutura ?

modules/RH/controllers
modules/RH/views
modules/RH/models
modules/RH/funcionario/controllers
modules/RH/funcionario/models
modules/RH/funcionario/views

gravatar

Glauber  em 31 de julho de 2014

Olá, qual a possibilidade de se criar sub-módulos? por exemplo: Admin > modulox > controller/model/view.

gravatar

Gilberto  em 22 de junho de 2016

Alguém consegui fazer os submodulos?
preciso de algo assim
modulos/Cadastros/Clientes
modulos/Relatorios/Clientes
modulos/Ferramentas/Configuracoes
Quando entrar na url ficaria meusite.com/Cadastros/Clientes outro ex. meusite.com/Cadastros/Usuarios e meusite.com/Ferramentas/Configuracoes
Consigo fazer isso no Router[] mas gostaria de poder usar a arquitetura HMVC para organizar os diretorios
Aguém?

Comente!