PageRenderTime 54ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/LoadEnv.php

https://bitbucket.org/martijnjager/classloader
PHP | 178 lines | 138 code | 30 blank | 10 comment | 13 complexity | cd6f0f93053107ae742934f24c815dc9 MD5 | raw file
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: marti
  5. * Date: 07-Mar-18
  6. * Time: 10:34
  7. */
  8. namespace Bootstrap;
  9. trait LoadEnv
  10. {
  11. protected $_env;
  12. public function __construct($env)
  13. {
  14. $this->_env = $env;
  15. }
  16. public function loadEnvironment()
  17. {
  18. $lines =$this->readLinesFromFile();
  19. foreach($lines as $line){
  20. if(!$this->isComment($line) && $this->looksLikeSetter($line)){
  21. $this->setEnvironmentVariable($line);
  22. }
  23. }
  24. return $lines;
  25. }
  26. protected function readLinesFromFile()
  27. {
  28. // Read file into an array of lines with auto-detected line endings
  29. $autodetect = ini_get('auto_detect_line_endings');
  30. ini_set('auto_detect_line_endings', '1');
  31. $lines = file($this->_env, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
  32. ini_set('auto_detect_line_endings', $autodetect);
  33. return $lines;
  34. }
  35. protected function isComment($line)
  36. {
  37. return strpos(ltrim($line), '#') === 0;
  38. }
  39. protected function looksLikeSetter($line)
  40. {
  41. return strpos($line, "=") !== false;
  42. }
  43. public function setEnvironmentVariable($name, $value = null)
  44. {
  45. list($name, $value) = $this->normaliseVariable($name, $value);
  46. // If PHP is running as an Apache module and an existing
  47. // Apache environment variable exists, overwrite it
  48. if (function_exists('apache_getenv') && function_exists('apache_setenv') && apache_getenv($name)) {
  49. apache_setenv($name, $value);
  50. }
  51. if (function_exists('putenv')) {
  52. setenv($name, $value);
  53. }
  54. $_ENV[$name] = $value;
  55. $_SERVER[$name] = $value;
  56. }
  57. protected function normaliseVariable($name, $value)
  58. {
  59. list($name, $value) = $this->splitCompoundStringIntoParts($name, $value);
  60. list($name, $value) = $this->sanitiseVariableName($name, $value);
  61. list($name, $value) = $this->sanitiseVariableValue($name, $value);
  62. $value = $this->resolveNestedVariables($value);
  63. return array($name, $value);
  64. }
  65. protected function resolveNestedVariables($value)
  66. {
  67. if(strpos($value, '$') !== false){
  68. $loader = $this;
  69. $value = preg_replace_callback(
  70. '/\${([a-zA-Z0-9_]+)}/',
  71. function($matchedPatterns) use($loader){
  72. $nestedVariable = $loader->getEnvirenmentVariable($matchedPatterns[1]);
  73. if($nestedVariable === null){
  74. return $matchedPatterns[0];
  75. }else{
  76. return $nestedVariable;
  77. }
  78. },
  79. $value
  80. );
  81. }
  82. return $value;
  83. }
  84. public function getEnvironmentVariable($name)
  85. {
  86. switch(true){
  87. case array_key_exists($name, $_ENV):
  88. return $_ENV[$name];
  89. case array_key_exists($name, $_SERVER):
  90. return $_SERVER[$name];
  91. default:
  92. $value = getenv($name);
  93. return $value === false ? null : $value;
  94. }
  95. }
  96. protected function splitCompoundStringIntoParts($name, $value)
  97. {
  98. if(strpos($name, '=') !== false){
  99. list($name, $value) = array_map('trim', explode('=', $name, 2));
  100. }
  101. return array($name, $value);
  102. }
  103. protected function sanitiseVariableName($name, $value)
  104. {
  105. $name = trim(str_replace(['export', '\'', '"'], '', $name));
  106. return array($name, $value);
  107. }
  108. protected function sanitiseVariableValue($name, $value)
  109. {
  110. $value = trim($value);
  111. if (!$value) {
  112. return array($name, $value);
  113. }
  114. if ($this->beginsWithAQuote($value)) { // value starts with a quote
  115. $quote = $value[0];
  116. $regexPattern = sprintf(
  117. '/^
  118. %1$s # match a quote at the start of the value
  119. ( # capturing sub-pattern used
  120. (?: # we do not need to capture this
  121. [^%1$s\\\\] # any character other than a quote or backslash
  122. |\\\\\\\\ # or two backslashes together
  123. |\\\\%1$s # or an escaped quote e.g \"
  124. )* # as many characters that match the previous rules
  125. ) # end of the capturing sub-pattern
  126. %1$s # and the closing quote
  127. .*$ # and discard any string after the closing quote
  128. /mx',
  129. $quote
  130. );
  131. $value = preg_replace($regexPattern, '$1', $value);
  132. $value = str_replace("\\$quote", $quote, $value);
  133. $value = str_replace('\\\\', '\\', $value);
  134. } else {
  135. $parts = explode(' #', $value, 2);
  136. $value = trim($parts[0]);
  137. // Unquoted values cannot contain whitespace
  138. if (preg_match('/\s+/', $value) > 0) {
  139. throw new \Exception('Dotenv values containing spaces must be surrounded by quotes.');
  140. }
  141. }
  142. return array($name, trim($value));
  143. }
  144. protected function beginsWithAQuote($value)
  145. {
  146. return strpbrk($value[0], '"\'') !== false;
  147. }
  148. }