dump_bak.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. <?php
  2. class DumpBak
  3. {
  4. // 文件夹路径符
  5. private static $DS = '/';
  6. // 是否分子文件夹存储
  7. private static $CREATE_PHP_CONFIG_IN_CHILD_DIR = 3;
  8. // 是否分子文件存储
  9. private static $CREATE_CHILD_PHP_CONFIG = 4;
  10. /**
  11. * @var string
  12. */
  13. private $appName;
  14. /**
  15. * @var string
  16. */
  17. private $dumpName;
  18. /**
  19. * 是否需要分子目录
  20. *
  21. * @var boolean
  22. */
  23. private $needChildDir = false;
  24. /**
  25. * 是否切割配置文件
  26. *
  27. * @var boolean
  28. */
  29. private $needSplitConfig = false;
  30. /**
  31. * Dump constructor.
  32. *
  33. * @param array $argv
  34. */
  35. public function __construct($argv)
  36. {
  37. self::vd(sprintf("argv: %s", var_export($argv, true)));
  38. $this->appName = $argv[1];
  39. $this->dumpName = $argv[2];
  40. if (isset($argv[3])) {
  41. $this->outputOption = $argv['3'];
  42. }
  43. // 初始化是否需要分子目录
  44. self::vd(sprintf("outputOption: %s", $this->outputOption));
  45. if (!is_null($this->outputOption)) {
  46. $this->needChildDir = $this->outputOption & self::$CREATE_PHP_CONFIG_IN_CHILD_DIR;
  47. }
  48. self::vd(sprintf("needChildDir: %s", var_export($this->needChildDir, true)));
  49. // 初始化是否需要切割配置文件
  50. if (!is_null($this->outputOption)) {
  51. $this->needSplitConfig = $this->outputOption & self::$CREATE_CHILD_PHP_CONFIG;
  52. }
  53. self::vd(sprintf("needSplitConfig: %s", var_export($this->needSplitConfig, true)));
  54. }
  55. /**
  56. * 执行主函数
  57. */
  58. public function run()
  59. {
  60. // 判断参数是否正确
  61. self::vd("App Name: {$this->appName}, Dump Name: {$this->dumpName}, Option: {$this->outputOption}");
  62. if (!$this->appName || !$this->dumpName) {
  63. self::vd("App Name or Dump Name not provided, quit ...", true);
  64. }
  65. // 组装导出目录
  66. $dumpBase = '..' . self::$DS . '..' . self::$DS . 'output' . self::$DS . $this->appName;
  67. self::vd($dumpBase);
  68. // 找到最后一次导出目录
  69. $lastDumpDir = $this->getLastDumpDir($dumpBase);
  70. self::vd("Last Dump Dir: " . $lastDumpDir);
  71. // 获取json文件路径
  72. $jsonPath = $lastDumpDir . self::$DS . 'PHP' . self::$DS . $this->dumpName . '.json';
  73. // 读取json文件,并解析成数组
  74. $json = $this->getJsonData($jsonPath);
  75. // 写配置文件
  76. $this->writeData($json, $lastDumpDir, $this->dumpName);
  77. // 判断此配置文件是否有特殊逻辑
  78. $methodName = $this->dumpName . '_handler';
  79. if (method_exists($this, $methodName)) {
  80. $this->$methodName($json, $lastDumpDir, $this->dumpName);
  81. self::vd("{$methodName} Done...");
  82. }
  83. // 删除json文件
  84. unlink($jsonPath);
  85. // 退出
  86. self::vd("Dump Done ...", true);
  87. }
  88. /**
  89. * 写入配置文件
  90. *
  91. * @param string $json
  92. * @param string $dumpDir 文件输出目录
  93. * @param string $dumpName 输出文件名
  94. * @param boolean $handlerNoNeedSplit default false, 强制不切割通过handler生成的文件
  95. */
  96. private function writeData($json, $dumpDir, $dumpName, $handlerNoNeedSplit = false)
  97. {
  98. $dumpPath = $dumpDir . self::$DS . 'PHP';
  99. // 如果需要分子目录存储,则需要再生成一层子目录
  100. if ($this->needChildDir) {
  101. $dumpNameArray = explode('_', $dumpName);
  102. if (count($dumpNameArray) >= 2) {
  103. $dumpPath .= self::$DS . $dumpNameArray[0] . '_' . $dumpNameArray[1];
  104. // 创建目录
  105. if (!file_exists($dumpPath)) {
  106. var_dump(mkdir($dumpPath));
  107. self::vd("make dir: " . $dumpPath);
  108. }
  109. }
  110. }
  111. $phpFile = $dumpPath . self::$DS . $dumpName . '.config.php';
  112. $this->writeFile($phpFile, $json);
  113. // 切割配置文件
  114. if ($this->needSplitConfig && !$handlerNoNeedSplit) {
  115. // 切割文件都统一放到以原文件名命名的文件夹内
  116. $dumpPath .= self::$DS . $dumpName;
  117. if (!file_exists($dumpPath)) {
  118. mkdir($dumpPath);
  119. self::vd("make dir: " . $dumpPath);
  120. }
  121. // 按行切割文件
  122. foreach ($json as $configId => $config) {
  123. $phpFile = $dumpPath . self::$DS . $configId . '.config.php';
  124. $this->writeFile($phpFile, $config);
  125. }
  126. }
  127. }
  128. /**
  129. * 写入php文件
  130. *
  131. * @param string $file 写入文件路径
  132. * @param string $data 写入文件内容
  133. * @return void
  134. */
  135. private function writeFile($file, $data)
  136. {
  137. // 写入配置文件
  138. $configs = var_export($data, true);
  139. // 整理输出格式
  140. $config = <<<TXT
  141. <?php
  142. return {$configs};
  143. TXT;
  144. // 写入导出文件
  145. file_put_contents($file, $config);
  146. }
  147. /**
  148. * 读取json数据
  149. *
  150. * @param string $jsonPath
  151. * @return array
  152. */
  153. private function getJsonData($jsonPath)
  154. {
  155. if (!file_exists($jsonPath)) {
  156. self::vd("Target json file not found, quit: {$jsonPath}", true);
  157. }
  158. $jsonStr = file_get_contents($jsonPath);
  159. $json = json_decode($jsonStr, true);
  160. // 轮询数组的value,将子json结构成数组结构
  161. foreach ($json as $key => $valueArr) {
  162. foreach ($valueArr as $valueKey => $value) {
  163. $decodedValue = @json_decode($value, true); // 如果$value是数组输入的话,会报warning,压制掉
  164. if (is_array($decodedValue)) {
  165. $json[$key][$valueKey] = $decodedValue;
  166. }
  167. }
  168. }
  169. ksort($json);
  170. return $json;
  171. }
  172. /**
  173. * 找到最后一次导出目录
  174. *
  175. * @param string $dumpBase
  176. * @return string
  177. */
  178. private function getLastDumpDir($dumpBase)
  179. {
  180. $lastDumpDir = null;
  181. $dumpBaseDir = new DirectoryIterator($dumpBase);
  182. /* @var DirectoryIterator $info */
  183. foreach ($dumpBaseDir as $info) {
  184. if ($info->isDir()) {
  185. $lastDumpDir = $info->getFilename();
  186. }
  187. }
  188. return $dumpBase . self::$DS . $lastDumpDir;
  189. }
  190. /**
  191. * 输出调试信息
  192. *
  193. * @param string $msg
  194. * @param boolean $exit default false, 是否退出程序执行
  195. * @return void
  196. */
  197. private static function vd($msg, $exit = false)
  198. {
  199. echo $msg . "\r\n";
  200. if ($exit) {
  201. exit;
  202. }
  203. }
  204. /**
  205. * 处理成就, 找出entityId => configId对应关系
  206. *
  207. * @param array $originData
  208. * @param string $dumpDir
  209. * @param string $originName
  210. * @return void
  211. */
  212. private function module_achievement_handler($originData, $dumpDir, $originName)
  213. {
  214. // 生成新数据
  215. $data = [];
  216. foreach ($originData as $config) {
  217. if (!$config['require']) {
  218. continue;
  219. }
  220. foreach ($config['require'] as $entityId => $value) {
  221. if (!isset($data[$entityId])) {
  222. $effects = [];
  223. } else {
  224. $effects = $data[$entityId]['effects'];
  225. }
  226. $effects[] = $config['configId'];
  227. $data[$entityId] = [
  228. 'entityId' => $entityId,
  229. 'effects' => $effects,
  230. ];
  231. }
  232. }
  233. // 生成配置文件
  234. $dumpName = 'module_achievement_effects';
  235. $this->writeData($data, $dumpDir, $dumpName);
  236. }
  237. /**
  238. * 处理任务, 生成等级任务表
  239. *
  240. * @param array $originData
  241. * @param string $dumpDir
  242. * @param string $originName
  243. * @return void
  244. */
  245. private function module_mission_handler($originData, $dumpDir, $originName)
  246. {
  247. $data = [];
  248. foreach ($originData as $config) {
  249. $typeKey = null;
  250. switch ($config['type']) {
  251. case 2:
  252. $typeKey = 'dailyMission';
  253. break;
  254. case 3:
  255. $typeKey = 'dailyTimeMission';
  256. break;
  257. case 4:
  258. $typeKey = 'dailyVipMission';
  259. break;
  260. default:
  261. break;
  262. }
  263. if (is_null($typeKey)) {
  264. continue;
  265. }
  266. $maxLv = $config['level'] + 10;
  267. for ($lv = $config['level']; $lv < $maxLv; ++$lv) {
  268. if (!isset($data[$lv])) {
  269. $data[$lv] = [
  270. 'configId' => $lv,
  271. 'level' => $lv,
  272. 'dailyMission' => [],
  273. 'dailyVipMission' => [],
  274. 'dailyTimeMission' => [],
  275. ];
  276. }
  277. $data[$lv][$typeKey][] = $config['configId'];
  278. }
  279. }
  280. // 生成配置文件
  281. $dumpName = 'module_mission_daily';
  282. $this->writeData($data, $dumpDir, $dumpName);
  283. }
  284. /**
  285. * 处理dol_social_help, 生成一张以helpId为主键的表
  286. *
  287. * @param array $originData
  288. * @param string $dumpDir
  289. * @param string $originName
  290. * @return void
  291. */
  292. private function dol_social_help_handler($originData, $dumpDir, $originName)
  293. {
  294. // 整理数据
  295. $data = [];
  296. foreach ($originData as $config) {
  297. $helpId = strval($config['helpId']);
  298. $data[$helpId] = $config;
  299. }
  300. // 生成配置文件
  301. $dumpName = 'dol_social_help_auto_create';
  302. $this->writeData($data, $dumpDir, $dumpName);
  303. }
  304. /**
  305. * 处理dol_social_request, 生成一张以requestDefId为主键的表
  306. *
  307. * @param array $originData
  308. * @param string $dumpDir
  309. * @param string $originName
  310. * @return void
  311. */
  312. private function dol_social_request_handler($originData, $dumpDir, $originName)
  313. {
  314. // 整理数据
  315. $data = [];
  316. foreach ($originData as $config) {
  317. $helpId = strval($config['requestDefId']);
  318. $data[$helpId] = $config;
  319. }
  320. // 生成配置文件
  321. $dumpName = 'dol_social_request_auto_create';
  322. $this->writeData($data, $dumpDir, $dumpName);
  323. }
  324. /**
  325. * 处理dol_social_feed, 生成一张以feedDefId为主键的表
  326. *
  327. * @param array $originData
  328. * @param string $dumpDir
  329. * @param string $originName
  330. * @return void
  331. */
  332. private function dol_social_feed_handler($originData, $dumpDir, $originName)
  333. {
  334. // 整理数据
  335. $data = [];
  336. foreach ($originData as $config) {
  337. $helpId = strval($config['feedDefId']);
  338. $data[$helpId] = $config;
  339. }
  340. // 生成配置文件
  341. $dumpName = 'dol_social_feed_auto_create';
  342. $this->writeData($data, $dumpDir, $dumpName);
  343. }
  344. /**
  345. * 处理dol_drop, 切割掉落配置文件, 将配置文件按组切成一个个的配置文件
  346. *
  347. * @param array $originData
  348. * @param string $dumpDir
  349. * @param string $originName
  350. * @return void
  351. */
  352. private function dol_drop_handler($originData, $dumpDir, $originName)
  353. {
  354. $groupData = [];
  355. // 按组划分数组
  356. foreach ($originData as $configId => $config) {
  357. $groupData[$config['groupId']][$configId] = $config;
  358. }
  359. // 分组写入文件
  360. $namePrefix = 'dol_drop_group_';
  361. foreach ($groupData as $groupId => $data) {
  362. $dumpName = $namePrefix . $groupId;
  363. $this->writeData($data, $dumpDir, $dumpName, true);
  364. }
  365. }
  366. }
  367. $dump = new Dump($argv);
  368. $dump->run();