20. Implantação da aplicação cliente/servidor num serviço de alojamento
Apresentamos aqui as linhas gerais da implementação da aplicação cliente/servidor que desenvolvemos num servidor OVH [https://www.ovh.com/fr/]. A implementação noutros fornecedores de alojamento não deverá ser muito diferente. Pretendemos simplesmente mostrar que a nossa aplicação se adapta bem a esta implementação.
20.1. Implementação do servidor
O alojamento OVH em questão é um alojamento básico:
- um ambiente PHP 7.3;
- um SGBD MySQL;
- sem servidor [Redis];
O terceiro ponto obriga-nos a alterar a versão 14 do nosso servidor de cálculo de impostos.

Temos de alterar:
- os ficheiros de configuração [1];
- os controladores [AdminDataController] e [CalculerImpotController] para ter em conta o facto de não existir o servidor [Redis];
O ficheiro [config.json] é alterado da seguinte forma:
{
"databaseFilename": "Config/database.json",
"corsAllowed": false,
"redisAvailable":false,
"rootDirectory": "/.../www/apps/impot/serveur-php7",
"relativeDependencies": [
"/Entities/BaseEntity.php",
...
"/Controllers/AdminDataController.php"
],
"absoluteDependencies": [
"/.../vendor/autoload.php",
"/.../vendor/predis/predis/autoload.php"
],
"users": [
{
"login": "admin",
"passwd": "admin"
}
],
...
}
Comentários
- linha 4: introduz-se um valor booleano [redisAvailable] para indicar se existe ou não acesso a um servidor [Redis];
- linhas 5, 13 e 14: os caminhos absolutos vão mudar;
O ficheiro [database.json] passa a ter o seguinte aspeto:
{
"dsn": "mysql:host=...;dbname=...",
"id": "...",
"pwd": "...",
"tableTranches": "dbimpots_tbtranches",
"colLimites": "limites",
"colCoeffR": "coeffr",
"colCoeffN": "coeffn",
"tableConstantes": "dbimpots_tbconstantes",
"colPlafondQfDemiPart": "plafondQfDemiPart",
...
}
Comentários
- linhas 2-4: a identificação da base de dados, bem como os identificadores do seu proprietário, irão mudar;
O controlador [AdminDataController] passa a ter a seguinte forma:
<?php
namespace Application;
// dependências do Symfony
use \Symfony\Component\HttpFoundation\Response;
use \Symfony\Component\HttpFoundation\Request;
use \Symfony\Component\HttpFoundation\Session\Session;
// alias da camada [dao]
use \Application\ServerDaoWithSession as ServerDaoWithRedis;
class AdminDataController implements InterfaceController {
// $config é a configuração da aplicação
// processamento de um pedido Request
// utiliza a sessão Session e pode alterá-la
// $infos são informações adicionais específicas de cada controlador
// retorna um array [$statusCode, $état, $content, $headers]
public function execute(
array $config,
Request $request,
Session $session,
array $infos = NULL): array {
// deve existir um único parâmetro GET
$method = strtolower($request->getMethod());
...
// é possível trabalhar
// Redis
if ($config["redisAvailable"]) {
\Predis\Autoloader::register();
...
} else {
try {
// vamos buscar os dados fiscais da base de dados
$dao = new ServerDaoWithRedis($config["databaseFilename"], NULL);
// taxAdminData
$taxAdminData = $dao->getTaxAdminData();
} catch (\Throwable $ex) {
// correu mal
// envio do resultado com erro para o controlador principal
$état = 1051;
return [Response::HTTP_INTERNAL_SERVER_ERROR, $état,
["réponse" => utf8_encode($ex->getMessage())], []];
}
}
// envio do resultado para o controlador principal
$état = 1000;
return [Response::HTTP_OK, $état, ["réponse" => $taxAdminData], []];
}
}
Comentários
- linha 31: passa-se agora a verificar se existe ou não um servidor [Redis];
- linhas 32-34: se sim, o código anterior é retomado na íntegra;
- linhas 35-46: caso contrário, os dados da administração fiscal são obtidos da base de dados;
O controlador [CalculerImpotController], que também necessita dos dados da administração fiscal, funciona de forma idêntica.
Feito isso. A implementação no servidor OVH consistiu em criar o FTP. Foi transferida para o OVH:
- a versão [vuejs-14-without-redis];
- a pasta [vendor], que contém todas as dependências do servidor [vuejs-14-without-redis];
Após a transferência do FTP, gerámos as tabelas necessárias para o servidor com o seguinte script SQL:
-- phpMyAdmin SQL Dump
-- versão 4.8.5
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3306
-- Hora de geração: 12 de outubro de 2019 às 07:45 AM
-- Versão do servidor: 5.7.24
-- PHP Versão: 7.2.11
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Estrutura da tabela `dbimpots_tbconstantes`
--
CREATE TABLE `dbimpots_tbconstantes` (
`id` int(11) NOT NULL,
`plafondQfDemiPart` decimal(10,2) NOT NULL,
`plafondRevenusCelibatairePourReduction` decimal(10,2) NOT NULL,
`plafondRevenusCouplePourReduction` decimal(10,2) NOT NULL,
`valeurReducDemiPart` decimal(10,2) NOT NULL,
`plafondDecoteCelibataire` decimal(10,2) NOT NULL,
`plafondDecoteCouple` decimal(10,2) NOT NULL,
`plafondImpotCelibatairePourDecote` decimal(10,2) NOT NULL,
`plafondImpotCouplePourDecote` decimal(10,2) NOT NULL,
`abattementDixPourcentMax` decimal(10,2) NOT NULL,
`abattementDixPourcentMin` decimal(10,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Exportação de dados da tabela `dbimpots_tbconstantes`
--
INSERT INTO `dbimpots_tbconstantes` (`id`, `plafondQfDemiPart`, `plafondRevenusCelibatairePourReduction`, `plafondRevenusCouplePourReduction`, `valeurReducDemiPart`, `plafondDecoteCelibataire`, `plafondDecoteCouple`, `plafondImpotCelibatairePourDecote`, `plafondImpotCouplePourDecote`, `abattementDixPourcentMax`, `abattementDixPourcentMin`) VALUES
(8, '1551.00', '21037.00', '42074.00', '3797.00', '1196.00', '1970.00', '1595.00', '2627.00', '12502.00', '437.00');
-- --------------------------------------------------------
--
-- Estrutura da tabela `dbimpots_tbtranches`
--
CREATE TABLE `dbimpots_tbtranches` (
`id` int(11) NOT NULL,
`limites` decimal(10,2) NOT NULL,
`coeffR` decimal(10,2) NOT NULL,
`coeffN` decimal(10,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- A exportar dados da tabela `dbimpots_tbtranches`
--
INSERT INTO `dbimpots_tbtranches` (`id`, `limites`, `coeffR`, `coeffN`) VALUES
(36, '9964.00', '0.00', '0.00'),
(37, '27519.00', '0.14', '1394.96'),
(38, '73779.00', '0.30', '5798.00'),
(39, '156244.00', '0.41', '13913.69'),
(40, '0.00', '0.45', '20163.45');
--
-- Índices das tabelas cujos dados foram exportados
--
--
-- Índices da tabela `dbimpots_tbconstantes`
--
ALTER TABLE `dbimpots_tbconstantes`
ADD PRIMARY KEY (`id`);
--
-- Índices para a tabela `dbimpots_tbtranches`
--
ALTER TABLE `dbimpots_tbtranches`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT para tabelas exportadas
--
--
-- AUTO_INCREMENT para a tabela `dbimpots_tbconstantes`
--
ALTER TABLE `dbimpots_tbconstantes`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;
--
-- AUTO_INCREMENT para a tabela `dbimpots_tbtranches`
--
ALTER TABLE `dbimpots_tbtranches`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=41;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
Quando tudo isto esteve concluído, adaptámos os ficheiros [config.json, database.json] ao seu novo ambiente.
20.2. Implantação do cliente [Vue.js]
Decidiu-se implementar o cliente [Vue.js] no URL e no [http://machine/apps/impot/client-vuejs/]. Isto implicou as seguintes alterações:
Na raiz do [workspace] do [VSCode], foi criado o seguinte ficheiro [vue.config.js]:

O ficheiro [vue.config.js] é o seguinte:
// vue.config.js
module.exports = {
// o URL do serviço de apoio ao cliente [vuejs] do servidor de cálculo de impostos
publicPath: '/apps/impot/client-vuejs/'
}
O ficheiro [router.js] [3] também foi alterado:
// importações
import Vue from 'vue'
import VueRouter from 'vue-router'
...
// plug-in de encaminhamento
Vue.use(VueRouter)
// as rotas da aplicação
const routes = [
...
]
// o router
const router = new VueRouter({
// as rotas
routes,
// o modo de visualização do URL
mode: 'history',
// o URL básico da aplicação
base: '/apps/impot/client-vuejs/'
})
// verificação das rotas
router.beforeEach((to, from, next) => {
...
})
// exportação do router
export default router
Comentários
- linha 21: a base do ficheiro URL foi alterada;
O ficheiro [config.js] foi alterado da seguinte forma:
// utilização da biblioteca [axios]
const axios = require('axios');
// tempo limite das solicitações HTTP
axios.defaults.timeout = 5000;
// a base de dados do servidor de cálculo de impostos URL
// o esquema [https] causa problemas no Firefox porque o servidor de cálculo
// de impostos envia um certificado autoassinado. Funciona bem com o Chrome e o Edge. O Safari não foi testado.
// Com o Firefox, é possível aceder ao URL abaixo diretamente e indicar ao Firefox
// que aceita o risco de um certificado não assinado. Depois disso, o cliente [vuejs] funcionará.
axios.defaults.baseURL = 'http://.../apps/impot/serveur-php7';
// vamos utilizar cookies
axios.defaults.withCredentials = true;
// exportação da configuração
export default {
// objeto [axios]
axios: axios,
// tempo máximo de inatividade da sessão: 5 min = 300 s = 300 000 ms
duréeSession: 300000
}
Comentários
- linha 10: insere-se o ficheiro URL do servidor de cálculo de impostos;
A versão de produção do projeto foi gerada com o comando [build] do ficheiro [package.json] [5] seguinte:
{
"name": "vuejs",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve vuejs-22/main.js",
"build": "vue-cli-service build vuejs-22-ovh-withBootstrapVue/main.js",
"lint": "vue-cli-service lint"
},
...
}
Feito isto, a pasta [dist], que continha a versão de produção gerada, foi «carregada» para o servidor OVH, na pasta [/.../apps/impot], e posteriormente renomeada para [client-vuejs], para que o código do cliente ficasse na pasta [/.../apps/impot/client-vuejs/], tal como previsto. Em seguida, nessa pasta, descarregámos o seguinte ficheiro [.htaccess]:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /apps/impot/client-vuejs/
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /apps/impot/client-vuejs/index.html [L]
</IfModule>
isto porque o servidor web do OVH utilizado aqui é um servidor Apache. Para outros tipos de servidores, consulte a documentação |https://cli.vuejs.org/guide/deployment.html|.
A aplicação de servidor PHP 7 pode ser testada |aqui|.
O cliente [Vue.js] pode ser testado |aqui|.
20.3. Conclusion
A versão [vuejs-21] não era indispensável. Verificou-se que a versão [vuejs-20] resistia corretamente aos URL introduzidos pelo utilizador. No entanto, a nova versão proporciona um conforto adicional ao utilizador. O utilizador pode navegar digitando URL. A aplicação apresenta-lhe então a vista que melhor se adequa ao estado atual (a sessão) da aplicação. Além disso, a versão [vuejs-22] traz melhorias para a visualização da aplicação em dispositivos móveis.