Config.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <?php
  2. /**
  3. * This file is part of webman.
  4. *
  5. * Licensed under The MIT License
  6. * For full copyright and license information, please see the MIT-LICENSE.txt
  7. * Redistributions of files must retain the above copyright notice.
  8. *
  9. * @author walkor<walkor@workerman.net>
  10. * @copyright walkor<walkor@workerman.net>
  11. * @link http://www.workerman.net/
  12. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  13. */
  14. namespace Webman;
  15. use FilesystemIterator;
  16. use RecursiveDirectoryIterator;
  17. use RecursiveIteratorIterator;
  18. use function array_replace_recursive;
  19. use function array_reverse;
  20. use function count;
  21. use function explode;
  22. use function in_array;
  23. use function is_array;
  24. use function is_dir;
  25. use function is_file;
  26. use function key;
  27. use function str_replace;
  28. class Config
  29. {
  30. /**
  31. * @var array
  32. */
  33. protected static $config = [];
  34. /**
  35. * @var string
  36. */
  37. protected static $configPath = '';
  38. /**
  39. * @var bool
  40. */
  41. protected static $loaded = false;
  42. /**
  43. * Load.
  44. * @param string $configPath
  45. * @param array $excludeFile
  46. * @param string|null $key
  47. * @return void
  48. */
  49. public static function load(string $configPath, array $excludeFile = [], ?string $key = null)
  50. {
  51. static::$configPath = $configPath;
  52. if (!$configPath) {
  53. return;
  54. }
  55. static::$loaded = false;
  56. $config = static::loadFromDir($configPath, $excludeFile);
  57. if (!$config) {
  58. static::$loaded = true;
  59. return;
  60. }
  61. if ($key !== null) {
  62. foreach (array_reverse(explode('.', $key)) as $k) {
  63. $config = [$k => $config];
  64. }
  65. }
  66. static::$config = array_replace_recursive(static::$config, $config);
  67. static::formatConfig();
  68. static::$loaded = true;
  69. }
  70. /**
  71. * This deprecated method will certainly be removed in the future.
  72. * @param string $configPath
  73. * @param array $excludeFile
  74. * @return void
  75. * @deprecated
  76. */
  77. public static function reload(string $configPath, array $excludeFile = [])
  78. {
  79. static::load($configPath, $excludeFile);
  80. }
  81. /**
  82. * Clear.
  83. * @return void
  84. */
  85. public static function clear()
  86. {
  87. static::$config = [];
  88. }
  89. /**
  90. * FormatConfig.
  91. * @return void
  92. */
  93. protected static function formatConfig()
  94. {
  95. $config = static::$config;
  96. // Merge log config
  97. foreach ($config['plugin'] ?? [] as $firm => $projects) {
  98. if (isset($projects['app'])) {
  99. foreach ($projects['log'] ?? [] as $key => $item) {
  100. $config['log']["plugin.$firm.$key"] = $item;
  101. }
  102. }
  103. foreach ($projects as $name => $project) {
  104. if (!is_array($project)) {
  105. continue;
  106. }
  107. foreach ($project['log'] ?? [] as $key => $item) {
  108. $config['log']["plugin.$firm.$name.$key"] = $item;
  109. }
  110. }
  111. }
  112. // Merge database config
  113. foreach ($config['plugin'] ?? [] as $firm => $projects) {
  114. if (isset($projects['app'])) {
  115. foreach ($projects['database']['connections'] ?? [] as $key => $connection) {
  116. $config['database']['connections']["plugin.$firm.$key"] = $connection;
  117. }
  118. }
  119. foreach ($projects as $name => $project) {
  120. if (!is_array($project)) {
  121. continue;
  122. }
  123. foreach ($project['database']['connections'] ?? [] as $key => $connection) {
  124. $config['database']['connections']["plugin.$firm.$name.$key"] = $connection;
  125. }
  126. }
  127. }
  128. if (!empty($config['database']['connections'])) {
  129. $config['database']['default'] = $config['database']['default'] ?? key($config['database']['connections']);
  130. }
  131. // Merge thinkorm config
  132. foreach ($config['plugin'] ?? [] as $firm => $projects) {
  133. if (isset($projects['app'])) {
  134. foreach ($projects['thinkorm']['connections'] ?? [] as $key => $connection) {
  135. $config['thinkorm']['connections']["plugin.$firm.$key"] = $connection;
  136. }
  137. foreach ($projects['think-orm']['connections'] ?? [] as $key => $connection) {
  138. $config['think-orm']['connections']["plugin.$firm.$key"] = $connection;
  139. }
  140. }
  141. foreach ($projects as $name => $project) {
  142. if (!is_array($project)) {
  143. continue;
  144. }
  145. foreach ($project['thinkorm']['connections'] ?? [] as $key => $connection) {
  146. $config['thinkorm']['connections']["plugin.$firm.$name.$key"] = $connection;
  147. }
  148. foreach ($project['think-orm']['connections'] ?? [] as $key => $connection) {
  149. $config['think-orm']['connections']["plugin.$firm.$name.$key"] = $connection;
  150. }
  151. }
  152. }
  153. if (!empty($config['thinkorm']['connections'])) {
  154. $config['thinkorm']['default'] = $config['thinkorm']['default'] ?? key($config['thinkorm']['connections']);
  155. }
  156. if (!empty($config['think-orm']['connections'])) {
  157. $config['think-orm']['default'] = $config['think-orm']['default'] ?? key($config['think-orm']['connections']);
  158. }
  159. // Merge redis config
  160. foreach ($config['plugin'] ?? [] as $firm => $projects) {
  161. if (isset($projects['app'])) {
  162. foreach ($projects['redis'] ?? [] as $key => $connection) {
  163. $config['redis']["plugin.$firm.$key"] = $connection;
  164. }
  165. }
  166. foreach ($projects as $name => $project) {
  167. if (!is_array($project)) {
  168. continue;
  169. }
  170. foreach ($project['redis'] ?? [] as $key => $connection) {
  171. $config['redis']["plugin.$firm.$name.$key"] = $connection;
  172. }
  173. }
  174. }
  175. static::$config = $config;
  176. }
  177. /**
  178. * LoadFromDir.
  179. * @param string $configPath
  180. * @param array $excludeFile
  181. * @return array
  182. */
  183. public static function loadFromDir(string $configPath, array $excludeFile = []): array
  184. {
  185. $allConfig = [];
  186. $dirIterator = new RecursiveDirectoryIterator($configPath, FilesystemIterator::FOLLOW_SYMLINKS);
  187. $iterator = new RecursiveIteratorIterator($dirIterator);
  188. foreach ($iterator as $file) {
  189. /** var SplFileInfo $file */
  190. if (is_dir($file) || $file->getExtension() != 'php' || in_array($file->getBaseName('.php'), $excludeFile)) {
  191. continue;
  192. }
  193. $appConfigFile = $file->getPath() . '/app.php';
  194. if (!is_file($appConfigFile)) {
  195. continue;
  196. }
  197. $relativePath = str_replace($configPath . DIRECTORY_SEPARATOR, '', substr($file, 0, -4));
  198. $explode = array_reverse(explode(DIRECTORY_SEPARATOR, $relativePath));
  199. if (count($explode) >= 2) {
  200. $appConfig = include $appConfigFile;
  201. if (empty($appConfig['enable'])) {
  202. continue;
  203. }
  204. }
  205. $config = include $file;
  206. foreach ($explode as $section) {
  207. $tmp = [];
  208. $tmp[$section] = $config;
  209. $config = $tmp;
  210. }
  211. $allConfig = array_replace_recursive($allConfig, $config);
  212. }
  213. return $allConfig;
  214. }
  215. /**
  216. * Get.
  217. * @param string|null $key
  218. * @param mixed $default
  219. * @return mixed
  220. */
  221. public static function get(?string $key = null, mixed $default = null)
  222. {
  223. if ($key === null) {
  224. return static::$config;
  225. }
  226. $keyArray = explode('.', $key);
  227. $value = static::$config;
  228. $found = true;
  229. foreach ($keyArray as $index) {
  230. if (!isset($value[$index])) {
  231. if (static::$loaded) {
  232. return $default;
  233. }
  234. $found = false;
  235. break;
  236. }
  237. $value = $value[$index];
  238. }
  239. if ($found) {
  240. return $value;
  241. }
  242. return static::read($key, $default);
  243. }
  244. /**
  245. * Read.
  246. * @param string $key
  247. * @param mixed $default
  248. * @return mixed
  249. */
  250. protected static function read(string $key, mixed $default = null)
  251. {
  252. $path = static::$configPath;
  253. if ($path === '') {
  254. return $default;
  255. }
  256. $keys = $keyArray = explode('.', $key);
  257. foreach ($keyArray as $index => $section) {
  258. unset($keys[$index]);
  259. if (is_file($file = "$path/$section.php")) {
  260. $config = include $file;
  261. return static::find($keys, $config, $default);
  262. }
  263. if (!is_dir($path = "$path/$section")) {
  264. return $default;
  265. }
  266. }
  267. return $default;
  268. }
  269. /**
  270. * Find.
  271. * @param array $keyArray
  272. * @param mixed $stack
  273. * @param mixed $default
  274. * @return array|mixed
  275. */
  276. protected static function find(array $keyArray, $stack, $default)
  277. {
  278. if (!is_array($stack)) {
  279. return $default;
  280. }
  281. $value = $stack;
  282. foreach ($keyArray as $index) {
  283. if (!isset($value[$index])) {
  284. return $default;
  285. }
  286. $value = $value[$index];
  287. }
  288. return $value;
  289. }
  290. }