15. 应用练习 – 第 7 版

15.1. 实现
在此我们将基于第 6 版进行扩展,将主脚本中使用的常量提取到一个配置文件中。该配置文件名为 jSON,内容如下:
{
"rootDirectory": "C:/Data/st-2019/dev/php7/poly/scripts-console/impots/version-07",
"databaseFilename": "Data/database.json",
"taxAdminDataFileName": "Data/taxadmindata.json",
"taxPayersDataFileName": "Data/taxpayersdata.json",
"resultsFileName": "Data/results.json",
"errorsFileName": "Data/errors.json",
"dependencies": {
"BaseEntity": "/../version-05/Entities/BaseEntity.php",
"TaxAdminData": "/../version-05/Entities/TaxAdminData.php",
"TaxPayerData": "/../version-05/Entities/TaxPayerData.php",
"Database": "/../version-05/Entities/Database.php",
"ExceptionImpots": "/../version-05/Entities/ExceptionImpots.php",
"Utilitaires": "/../version-05/Utilities/Utilitaires.php",
"InterfaceDao": "/../version-05/Dao/InterfaceDao.php",
"TraitDao": "/../version-05/Dao/TraitDao.php",
"InterfaceDao4TransferAdminData2Database": "/../version-05/Dao/InterfaceDao4TransferAdminData2Database.php",
"DaoTransferAdminDataFromJsonFile2Database": "/../version-05/Dao/DaoTransferAdminDataFromJsonFile2Database.php",
"DaoImpotsWithTaxAdminDataInDatabase": "/../version-05/Dao/DaoImpotsWithTaxAdminDataInDatabase.php",
"InterfaceMetier": "/../version-05/Métier/InterfaceMetier.php",
"Metier": "/../version-05/Métier/Metier.php"
},
"dependencies4calculate": [
"BaseEntity",
"TaxAdminData",
"TaxPayerData",
"Database",
"ExceptionImpots",
"Utilitaires",
"InterfaceDao",
"TraitDao",
"DaoImpotsWithTaxAdminDataInDatabase",
"InterfaceMetier",
"Metier"],
"dependencies4transfer": [
"BaseEntity",
"TaxAdminData",
"Database",
"ExceptionImpots",
"Utilitaires",
"InterfaceDao",
"TraitDao",
"InterfaceDao4TransferAdminData2Database",
"DaoTransferAdminDataFromJsonFile2Database"]
}
在此配置中:
- 第2行:作为该配置文件中所有路径基准的目录;
- 第3-7行:应用程序中所有jSON文件的路径;
- 第8-22行:应用程序中所有文件的路径,格式为[clé=>chemin];
- 第23-34行:用于计算税款的依赖项,以字典[dependencies](第8-22行)的键列表形式呈现;
- 第 35-44 行:用于将文件 jSON 和 [taxadmindata.json] 导入数据库的依赖项,以字典 [dependencies](第 8-22 行)的键列表形式呈现;
税务管理数据导入数据库的脚本 [MainTransferAdminDataFromFile2PostgresSQLDatabase.php] 如下所示:
<?php
// 严格遵守函数参数的声明类型
declare (strict_types=1);
// 命名空间
namespace Application;
// 通过 PHP 进行错误处理
// ini_set("display_errors", "0");
//
// 配置文件路径
define("CONFIG_FILENAME", "../Data/config.json");
// 读取配置
$config = \json_decode(\file_get_contents(CONFIG_FILENAME), true);
// 引入脚本所需的依赖项
$rootDirectory = $config["rootDirectory"];
foreach ($config["dependencies4transfer"] as $dependency) {
require $rootDirectory . $config["dependencies"][$dependency];
}
// 定义常量
define("DATABASE_CONFIG_FILENAME", "$rootDirectory/{$config["databaseFilename"]}");
define("TAXADMINDATA_FILENAME", "$rootDirectory/{$config["taxAdminDataFileName"]}");
//
try {
// 创建 [dao] 层
$dao = new DaoTransferAdminDataFromJsonFile2Database(DATABASE_CONFIG_FILENAME, TAXADMINDATA_FILENAME);
// 将数据导入数据库
$dao->transferAdminData2Database();
} catch (ExceptionImpots $ex) {
// 显示错误
print $ex->getMessage() . "\n";
}
// 结束
print "Terminé\n";
exit;
注释
代码与“链接”段落中的保持一致。唯一的区别在于第18-26行使用文件[config.json]代替了常量;
- 第16行:函数[file_get_contents]将文件[config.json]转换为字符串。随后,函数[json_decode]利用该字符串构建字典[$config]。 函数 [json_decode] 的第二个参数 [true] 表示需要构建一个词典;
- 第 19-22 行:引入了将文件 [taxadmindata.json] 中的数据传输到数据库所需的依赖项;
- [$config["dependencies4transfer"]] 是数据传输脚本所需的依赖项数组。 这是一个键值列表。项目中需包含的文件路径可在字典 [$config["dependencies"]] 中找到;
- $config["rootDirectory"] 表示待包含文件应添加的前缀路径;
同样地,税款计算脚本变为 [MainCalculateImpotsWithTaxAdminDataInPostgresDatabase]:
<?php
// 严格遵守函数参数的声明类型
declare (strict_types=1);
// 命名空间
namespace Application;
// 由 PHP 处理错误
// ini_set("display_errors", "0");
//
// 配置文件路径
define("CONFIG_FILENAME", "../Data/config.json");
// 读取配置
$config = \json_decode(\file_get_contents(CONFIG_FILENAME), true);
// 引入脚本所需的依赖项
$rootDirectory = $config["rootDirectory"];
foreach ($config["dependencies4calculate"] as $dependency) {
require $rootDirectory . $config["dependencies"][$dependency];
}
// 定义常量
define("DATABASE_CONFIG_FILENAME", "$rootDirectory/{$config["databaseFilename"]}");
define("TAXPAYERSDATA_FILENAME", "$rootDirectory/{$config["taxPayersDataFileName"]}");
define("RESULTS_FILENAME", "$rootDirectory/{$config["resultsFileName"]}");
define("ERRORS_FILENAME", "$rootDirectory/{$config["errorsFileName"]}");
//
try {
// 创建图层 [dao]
$dao = new DaoImpotsWithTaxAdminDataInDatabase(DATABASE_CONFIG_FILENAME);
// 创建图层 [métier]
$métier = new Metier($dao);
// 批处理模式下的税款计算
$métier->executeBatchImpots(TAXPAYERSDATA_FILENAME, RESULTS_FILENAME, ERRORS_FILENAME);
} catch (ExceptionImpots $ex) {
// 显示错误
print "Une erreur s'est produite : " . utf8_encode($ex->getMessage()) . "\n";
}
// 结束
print "Terminé\n";
exit;
15.2. 测试 [Codeception]
此版本与之前的版本一样,已通过 [Codeception] 测试验证。

15.2.1. [dao] 层测试
[DaoTest.php] 测试内容如下:
<?php
// 严格遵守函数参数的声明类型
declare (strict_types=1);
// 命名空间
namespace Application;
// 常量定义
define("ROOT", "C:/Data/st-2019/dev/php7/poly/scripts-console/impots/version-07");
// 配置文件路径
define("CONFIG_FILENAME", ROOT."/Data/config.json");
// 获取配置
$config = \json_decode(\file_get_contents(CONFIG_FILENAME), true);
// 引入脚本所需的依赖项
$rootDirectory = $config["rootDirectory"];
foreach ($config["dependencies4calculate"] as $dependency) {
require $rootDirectory . $config["dependencies"][$dependency];
}
// 其他常量
define("DATABASE_CONFIG_FILENAME", "$rootDirectory/{$config["databaseFilename"]}");
// 测试 -----------------------------------------------------
class DaoTest extends \Codeception\Test\Unit {
// TaxAdminData
private $taxAdminData;
public function __construct() {
parent::__construct();
// 创建图层 [dao]
$dao = new DaoImpotsWithTaxAdminDataInDatabase(DATABASE_CONFIG_FILENAME);
$this->taxAdminData = $dao->getTaxAdminData();
}
// 测试
public function testTaxAdminData() {
…
}
}
注释
- 第 9-21 行:定义测试环境。我们使用与链接段落中描述的主脚本 [MainCalculateImpotsWithTaxAdminDataInPostgresDatabase] 相同的环境,但不包含 [métier] 层;
- 第 29-34 行:构建 [dao] 层;
- 第33行:[$this→taxAdminData]属性包含待测试的数据;
- 第37-39行:方法[testTaxAdminData]即链接段落中所述的方法;
测试结果如下:

15.2.2. [métier] 层测试
[MetierTest.php] 的测试如下:
<?php
// 严格遵守函数参数的声明类型
declare (strict_types=1);
// 命名空间
namespace Application;
// 常量定义
define("ROOT", "C:/Data/st-2019/dev/php7/poly/scripts-console/impots/version-07");
// 配置文件路径
define("CONFIG_FILENAME", ROOT . "/Data/config.json");
// 读取配置
$config = \json_decode(\file_get_contents(CONFIG_FILENAME), true);
// 引入脚本所需的依赖项
$rootDirectory = $config["rootDirectory"];
foreach ($config["dependencies4calculate"] as $dependency) {
require $rootDirectory . $config["dependencies"][$dependency];
}
// 其他常量
define("DATABASE_CONFIG_FILENAME", "$rootDirectory/{$config["databaseFilename"]}");
// 测试类
class MetierTest extends \Codeception\Test\Unit {
// 业务层
private $métier;
public function __construct() {
parent::__construct();
// 创建 [dao] 层
$dao = new DaoImpotsWithTaxAdminDataInDatabase(DATABASE_CONFIG_FILENAME);
// 创建 [métier] 层
$this->métier = new Metier($dao);
}
// 测试
public function test1() {
…
}
-----------------------------------
public function test11() {
…
}
}
注释
- 第 9-21 行:定义测试环境。我们使用与链接段落中描述的主脚本 [MainCalculateImpotsWithTaxAdminDataInPostgresDatabase] 相同的环境;
- 第28-34行:构建[dao]层;
- 第 33 行:属性 [$this→métier] 是对待测试的 [métier] 层的引用;
- 第 37-45 行:[test1, test2…, test11] 方法即链接段落中所述的方法;
测试结果如下:
