Skip to content

Commit d4680f1

Browse files
ACPT-961: Improve Config readData() (when config cache is clean)
* using str_contains ahead of time (so we don't have to call the methods or run regex when we know it wouldn't match) (about 5-10% faster) * using array_walk_recursive which is a lot easier to read and is 5-10% faster * caching environmental variables config (we don't need to reload environment variables for each website)
1 parent 1c874bd commit d4680f1

File tree

2 files changed

+35
-33
lines changed

2 files changed

+35
-33
lines changed

app/code/Magento/Config/App/Config/Source/EnvironmentConfigSource.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ class EnvironmentConfigSource implements ConfigSourceInterface
3333
*/
3434
private $placeholder;
3535

36+
/**
37+
* cache for loadConfig()
38+
*
39+
* @var array|null
40+
*/
41+
private $loadConfigCache;
42+
43+
/**
44+
* cache for loadConfig()
45+
*
46+
* @var string|null
47+
*/
48+
private $loadConfigCacheEnv;
49+
3650
/**
3751
* @param ArrayManager $arrayManager
3852
* @param PlaceholderFactory $placeholderFactory
@@ -57,27 +71,32 @@ public function get($path = '')
5771

5872
/**
5973
* Loads config from environment variables.
74+
* Caching the result for when this method is called multiple times.
75+
* The environment variables don't change in run time, so it is safe to cache.
6076
*
6177
* @return array
6278
*/
6379
private function loadConfig()
6480
{
6581
$config = [];
66-
82+
// phpcs:disable Magento2.Security.Superglobal
6783
$environmentVariables = $_ENV;
68-
84+
// phpcs:enable
85+
if (null !== $this->loadConfigCache && $this->loadConfigCacheEnv === $environmentVariables) {
86+
return $this->loadConfigCache;
87+
}
6988
foreach ($environmentVariables as $template => $value) {
7089
if (!$this->placeholder->isApplicable($template)) {
7190
continue;
7291
}
73-
7492
$config = $this->arrayManager->set(
7593
$this->placeholder->restore($template),
7694
$config,
7795
$value
7896
);
7997
}
80-
98+
$this->loadConfigCache = $config;
99+
$this->loadConfigCacheEnv = $environmentVariables;
81100
return $config;
82101
}
83102
}

app/code/Magento/Store/Model/Config/Placeholder.php

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,48 +43,30 @@ public function __construct(\Magento\Framework\App\RequestInterface $request, $u
4343
*
4444
* @param array $data
4545
* @return array
46+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
4647
*/
4748
public function process(array $data = [])
4849
{
49-
// check provided arguments
5050
if (empty($data)) {
5151
return [];
5252
}
53-
54-
// initialize $pointer, $parents and $level variable
55-
reset($data);
56-
$pointer = &$data;
57-
$parents = [];
58-
$level = 0;
59-
60-
while ($level >= 0) {
61-
$current = &$pointer[key($pointer)];
62-
if (is_array($current)) {
63-
reset($current);
64-
$parents[$level] = &$pointer;
65-
$pointer = &$current;
66-
$level++;
67-
} else {
68-
$current = $this->_processPlaceholders($current, $data);
69-
70-
// move pointer of last queue layer to next element
71-
// or remove layer if all path elements were processed
72-
while ($level >= 0 && next($pointer) === false) {
73-
$level--;
74-
// removal of last element of $parents is skipped here for better performance
75-
// on next iteration that element will be overridden
76-
$pointer = &$parents[$level];
53+
array_walk_recursive(
54+
$data,
55+
function (&$value, $key, $data) {
56+
if (is_string($value) && str_contains($value, '{')) { // If _getPlaceholder() would do nothing, skip
57+
$value = $this->_processPlaceholders($value, $data);
7758
}
78-
}
79-
}
80-
59+
},
60+
$data
61+
);
8162
return $data;
8263
}
8364

8465
/**
8566
* Process array data recursively
8667
*
8768
* @deprecated 101.0.4 This method isn't used in process() implementation anymore
69+
* @see process()
8870
*
8971
* @param array &$data
9072
* @param string $path
@@ -179,6 +161,7 @@ protected function _getValue($path, array $data)
179161
* Set array value by path
180162
*
181163
* @deprecated 101.0.4 This method isn't used in process() implementation anymore
164+
* @see process()
182165
*
183166
* @param array &$container
184167
* @param string $path
@@ -187,7 +170,7 @@ protected function _getValue($path, array $data)
187170
*/
188171
protected function _setValue(array &$container, $path, $value)
189172
{
190-
$segments = explode('/', (string)$path);
173+
$segments = explode('/', (string)$path);
191174
$currentPointer = &$container;
192175
foreach ($segments as $segment) {
193176
if (!isset($currentPointer[$segment])) {

0 commit comments

Comments
 (0)