20. نشر تطبيق العميل/الخادم على خدمة استضافة
نوضح هنا نشر تطبيق العميل/الخادم الذي طورناه على خادم OVH [https://www.ovh.com/fr/]. لا ينبغي أن يختلف النشر على مزودي الاستضافة الآخرين كثيرًا. نريد ببساطة أن نظهر أن تطبيقنا مناسب تمامًا لهذا النشر.
20.1. نشر الخادم
خدمة الاستضافة OVH المعنية هي خطة استضافة أساسية:
- بيئة PHP 7.3؛
- نظام إدارة قواعد البيانات MySQL؛
- لا يوجد خادم [Redis]؛
النقطة الثالثة تتطلب منا تعديل الإصدار 14 من خادم حساب الضرائب الخاص بنا.

نحتاج إلى تعديل:
- ملفات التكوين [1]؛
- وحدات التحكم [AdminDataController] و [CalculerImpotController] لمراعاة عدم وجود خادم [Redis]؛
يتغير ملف [config.json] على النحو التالي:
{
"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"
}
],
...
}
تعليقات
- السطر 4: نقدم متغيرًا منطقيًا [redisAvailable] للإشارة إلى ما إذا كان لدينا وصول إلى خادم [Redis] أم لا؛
- السطور 5 و13 و14: ستتغير المسارات المطلقة؛
يتغير ملف [database.json] على النحو التالي:
{
"dsn": "mysql:host=...;dbname=...",
"id": "...",
"pwd": "...",
"tableTranches": "dbimpots_tbtranches",
"colLimites": "limites",
"colCoeffR": "coeffr",
"colCoeffN": "coeffn",
"tableConstantes": "dbimpots_tbconstantes",
"colPlafondQfDemiPart": "plafondQfDemiPart",
...
}
تعليقات
- السطور 2–4: سيتغير اسم قاعدة البيانات وبيانات اعتماد مالكها؛
يتطور [AdminDataController] على النحو التالي:
<?php
namespace Application;
// symfony dependencies
use \Symfony\Component\HttpFoundation\Response;
use \Symfony\Component\HttpFoundation\Request;
use \Symfony\Component\HttpFoundation\Session\Session;
// layer alias [dao]
use \Application\ServerDaoWithSession as ServerDaoWithRedis;
class AdminDataController implements InterfaceController {
// $config is the application configuration
// traitement d'une requête Request
// session and can modify it
// $infos is additional information specific to each controller
// renders an array [$statusCode, $état, $content, $headers]
public function execute(
array $config,
Request $request,
Session $session,
array $infos = NULL): array {
// you must have a single parameter GET
$method = strtolower($request->getMethod());
...
// we can work
// Redis
if ($config["redisAvailable"]) {
\Predis\Autoloader::register();
...
} else {
try {
// retrieve tax data from the database
$dao = new ServerDaoWithRedis($config["databaseFilename"], NULL);
// taxAdminData
$taxAdminData = $dao->getTaxAdminData();
} catch (\Throwable $ex) {
// it didn't go well
// return result with error to main controller
$état = 1051;
return [Response::HTTP_INTERNAL_SERVER_ERROR, $état,
["réponse" => utf8_encode($ex->getMessage())], []];
}
}
// return result to main controller
$état = 1000;
return [Response::HTTP_OK, $état, ["réponse" => $taxAdminData], []];
}
}
تعليقات
- السطر 31: نتحقق الآن مما إذا كان لدينا خادم [Redis] أم لا؛
- الأسطر 32–34: إذا كان الأمر كذلك، يتم تنفيذ الكود السابق بالكامل؛
- الأسطر 35–46: وإلا، يتم استرداد بيانات مصلحة الضرائب من قاعدة البيانات؛
يتم تحديث وحدة التحكم [CalculerImpotController]، التي تتطلب هي الأخرى بيانات من مصلحة الضرائب، بالطريقة نفسها.
هذا كل شيء. تضمن النشر على خادم OVH استخدام بروتوكول FTP. قمنا بتحميل ما يلي على OVH:
- إصدار [vuejs-14-without-redis]؛
- المجلد [vendor]، الذي يحتوي على جميع التبعيات لخادم [vuejs-14-without-redis]؛
بمجرد اكتمال نقل FTP، قمنا بإنشاء الجداول اللازمة للخادم باستخدام البرنامج النصي SQL التالي:
-- phpMyAdmin SQL Dump
-- version 4.8.5
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3306
-- Generation Time: Oct 12, 2019 at 07:45 AM
-- Server version: 5.7.24
-- PHP Version: 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 */;
--
-- Table structure for table `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;
--
-- Dumping data for table `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');
-- --------------------------------------------------------
--
-- Table structure for table `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;
--
-- Dumping data for table `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');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `dbimpots_tbconstantes`
--
ALTER TABLE `dbimpots_tbconstantes`
ADD PRIMARY KEY (`id`);
--
-- Indexes for table `dbimpots_tbtranches`
--
ALTER TABLE `dbimpots_tbtranches`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `dbimpots_tbconstantes`
--
ALTER TABLE `dbimpots_tbconstantes`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;
--
-- AUTO_INCREMENT for table `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 */;
بمجرد الانتهاء من كل هذا، قمنا بتكييف ملفات [config.json، database.json] مع بيئتها الجديدة.
20.2. نشر عميل [Vue.js]
تقرر نشر عميل [Vue.js] على عنوان URL [http://machine/apps/impot/client-vuejs/]. وأدى ذلك إلى التغييرات التالية:
في جذر [مساحة عمل] [VSCode]، أنشأنا ملف [vue.config.js] التالي:

ملف [vue.config.js] هو كما يلي:
// vue.config.js
module.exports = {
// l'URL de service du client [vuejs] du serveur de calcul de l'impôt
publicPath: '/apps/impot/client-vuejs/'
}
كما تم تعديل ملف [router.js] [3]:
// imports
import Vue from 'vue'
import VueRouter from 'vue-router'
...
// plugin de routage
Vue.use(VueRouter)
// les routes de l'application
const routes = [
...
]
// le routeur
const router = new VueRouter({
// les routes
routes,
// le mode d'affichage des URL
mode: 'history',
// l'URL de base de l'application
base: '/apps/impot/client-vuejs/'
})
// vérification des routes
router.beforeEach((to, from, next) => {
...
})
// export du router
export default router
تعليقات
- السطر 21: تم تغيير قاعدة عنوان URL؛
تم تعديل ملف [config.js] على النحو التالي:
// utilisation de la bibliothèque [axios]
const axios = require('axios');
// timeout des requêtes HTTP
axios.defaults.timeout = 5000;
// la base des URL du serveur de calcul de l'impôt
// le schéma [https] pose des problèmes à Firefox parce que le serveur de calcul
// de l'impôt envoie un certificat autosigné. ok avec Chrome et Edge. Safari pas testé.
// avec Firefox c'est possible en demandant l'URL ci-dessous directement et en disant à Firefox
// que vous acceptez le risque d'un certificat non signé. Ensuite le client [vuejs] fonctionnera.
axios.defaults.baseURL = 'http://.../apps/impot/serveur-php7';
// on va utiliser des cookies
axios.defaults.withCredentials = true;
// export de la configuration
export default {
// objet [axios]
axios: axios,
// délai maximal d'inactivité de la session : 5 mn = 300 s = 300000 ms
duréeSession: 300000
}
تعليقات
- السطر 10: أدخل عنوان URL لخادم حساب الضرائب؛
تم إنشاء الإصدار النهائي للمشروع باستخدام الأمر [build] في ملف [package.json] التالي [5]:
{
"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"
},
...
}
بمجرد الانتهاء من ذلك، تم "تحميل" المجلد [dist] الذي يحتوي على إصدار الإنتاج الذي تم إنشاؤه إلى خادم OVH في المجلد [/.../apps/impot] ثم تمت إعادة تسميته إلى [client-vuejs] بحيث يكون كود العميل في المجلد [/.../apps/impot/client-vuejs/] كما هو مخطط. ثم، في هذا المجلد، قمنا بتحميل ملف [.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>
وذلك لأن خادم الويب OVH المستخدم هنا هو خادم Apache. بالنسبة لأنواع الخوادم الأخرى، يرجى الرجوع إلى الوثائق |https://cli.vuejs.org/guide/deployment.html|.
يمكن اختبار تطبيق خادم PHP 7 |هنا|.
يمكن اختبار عميل [Vue.js] |هنا|.
20.3. خلاصة
لم تكن النسخة [vuejs-21] ضرورية. لقد رأينا أن الإصدار [vuejs-20] تعامل مع عناوين URL التي أدخلها المستخدم بشكل صحيح. ومع ذلك، يوفر الإصدار الجديد مزيدًا من الراحة للمستخدم. يمكنهم التنقل عن طريق كتابة عناوين URL. ثم يعرض التطبيق العرض الذي يناسب الحالة الحالية (الجلسة) للتطبيق. بالإضافة إلى ذلك، يقدم الإصدار [vuejs-22] تحسينات على عرض التطبيق على الأجهزة المحمولة.