Arquitetura Multiplataforma e Configuração de Subdomínios no ThinkPHP 3.2

Ao desenvolver sistemas web complexos, é comum a necessidade de suportar múltiplas interfaces, como um portal web para desktop, uma versão mobile e um painel administrativo. Embora todas compartilhem a mesma fonte de dados, a arquitetura MVC do ThinkPHP permite uma separação clara: a camada Model (M) é centralizada, a Controller (C) compartilha lógicas de API quando necessário, e a View (V) é totalmente isolada por plataforma. Para estruturar esse ecossistema, é fundamental configurar corretamente o banco de dados, organizar os módulos da aplicação, personalizar os diretórios de visualização e implementar o roteamento por subdomínios.

Configuração do Ambiente e Conexão com o Banco de Dados

Após extrair o pacote principal do ThinkPHP 3.2 no diretório raiz do servidor web, o primeiro passo é estabelecer a conexão com o banco de dados. Seguindo a hierarquia de carregamento de configurações do framework, a abordagem mais eficiente é definir as credenciais no arquivo de configuração global da aplicação (Application/Common/Conf/config.php).

// Configurações de conexão com o banco de dados
'DB_TYPE'   => 'mysql',
'DB_HOST'   => '127.0.0.1',
'DB_NAME'   => 'library_db',
'DB_USER'   => 'db_admin',
'DB_PWD'    => 'secure_password',
'DB_PORT'   => '3306',
'DB_PREFIX' => 'lib_',
'DB_CHARSET'=> 'utf8mb4',
'DB_DEBUG'  => false,

Para validar a conexão, crie um método em um controller padrão para buscar e retronar registros em formato JSON:

public function fetchBookDetails() {
    $bookId = I('get.book_id', 0, 'intval');
    $bookData = M('lib_book')->where(['id' => $bookId])->find();
    
    if ($bookData) {
        $this->ajaxReturn(['status' => 1, 'data' => $bookData]);
    } else {
        $this->ajaxReturn(['status' => 0, 'msg' => 'Book not found']);
    }
}

Expansão de Módulos na Aplicação

O ThinkPHP organiza o código em módulos dentro do diretório Application. Para atender às diferentes plataformas, duplique o módulo padrão (por exemplo, Home) e renomeie as cópias para refletir seus propósitos, como Mobile e Dashboard. Lembre-se de atualizar o namespace nos controllers de cada novo módulo para namespace Mobile\Controller; e namespace Dashboard\Controller;, garantindo que o autoloader do framework localize as classes corretamente.

Gerenciamento de Views e Diretórios de Templates

A camada de visão no ThinkPHP utiliza um motor de templates para compor interfaces dinâmicas. Em vez de depender da estrutura de diretórios padrão, que pode se tornar excessivamente aninhada, é recomendável definir caminhos personalizados para os templates de cada módulo.

No controller do módulo web, implemente uma ação para listar o catálogo:

public function catalog() {
    $bookCollection = M('lib_book')->order('price DESC')->select();
    $this->assign('catalogItems', $bookCollection);
    $this->display();
}

O template HTML correspondente utilizará as tags do motor de templates para iterar sobre os dados:

<main>
    <volist name="catalogItems" id="item">
        <article>
            <h3>{$item.title}</h3>
            <span>ID: {$item.id}</span>
            <strong>Preço: {$item.price}</strong>
        </article>
    </volist>
</main>

Para desacoplar os templates da estrutura interna do módulo, defina a constante de caminho no arquivo de configuração específico do módulo (Application/Web/Conf/config.php):

define('TMPL_PATH', './Public/WebTemplates/');

Repita esse processo para os módulos Mobile e Dashboard, apontando para seus respectivos diretórios de interface.

Implantação de Subdomínios e Roteamento

Para que cada plataforma seja acessível através de um subdomínio dedicado (ex: www.myapp.local, m.myapp.local, admin.myapp.local), é necessário configurar o servidor web e o roteamento interno do framework.

No Apache, configure os VirtualHosts para direcionar o tráfego para o diretório raiz do projeto:

<VirtualHost *:80>
    DocumentRoot "/var/www/html/myapp/"
    ServerName myapp.local
    ServerAlias www.myapp.local
    <Directory "/var/www/html/myapp/">
        Require all granted
    </Directory>
    DirectoryIndex index.php
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot "/var/www/html/myapp/"
    ServerName myapp.local
    ServerAlias m.myapp.local
    <Directory "/var/www/html/myapp/">
        Require all granted
    </Directory>
    DirectoryIndex mobile.php index.php
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot "/var/www/html/myapp/"
    ServerName myapp.local
    ServerAlias admin.myapp.local
    <Directory "/var/www/html/myapp/">
        Require all granted
    </Directory>
    DirectoryIndex index.php
</VirtualHost>

Em seguida, ative o mapeamento de subdomínios no arquivo de configuração global do ThinkPHP. Isso instrui o framework a carregar o módulo correto antes mesmo de processar a URL:

'APP_SUB_DOMAIN_DEPLOY' => true,
'APP_SUB_DOMAIN_RULES'  => [
    'www.myapp.local'   => 'Web',
    'm.myapp.local'     => 'Mobile',
    'admin.myapp.local' => 'Dashboard',
],
'APP_DOMAIN_SUFFIX'     => 'local',
'MULTI_MODULE'          => true,
'MODULE_ALLOW_LIST'     => ['Web', 'Mobile', 'Dashboard'],
'MODULE_DENY_LIST'      => ['Common', 'Runtime'],

Com essa configuração, o roteamento do ThinkPHP intercepta o host da requisição. Ao acessar http://www.myapp.local/index.php/Index/catalog, o framework identifica o subdomínio www, carrega o módulo Web e executa o controller Index sem que o nome do módulo precise estar explícito na URL. O mesmo ocorre para http://m.myapp.local/index.php/Index/catalog, que servirá a interface mobile, resultando em URLs mais limpas e uma arquitetura altamente escalável.

Tags: ThinkPHP PHP apache SubdomainRouting MVC

Publicado em 6-25 04:26