CodeExporter.php 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php declare(strict_types=1);
  2. /*
  3. * This file is part of sebastian/global-state.
  4. *
  5. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace SebastianBergmann\GlobalState;
  11. use const PHP_EOL;
  12. use function is_array;
  13. use function is_scalar;
  14. use function serialize;
  15. use function sprintf;
  16. use function var_export;
  17. final class CodeExporter
  18. {
  19. public function constants(Snapshot $snapshot): string
  20. {
  21. $result = '';
  22. foreach ($snapshot->constants() as $name => $value) {
  23. $result .= sprintf(
  24. 'if (!defined(\'%s\')) define(\'%s\', %s);' . "\n",
  25. $name,
  26. $name,
  27. $this->exportVariable($value),
  28. );
  29. }
  30. return $result;
  31. }
  32. public function globalVariables(Snapshot $snapshot): string
  33. {
  34. $result = <<<'EOT'
  35. call_user_func(
  36. function ()
  37. {
  38. foreach (array_keys($GLOBALS) as $key) {
  39. unset($GLOBALS[$key]);
  40. }
  41. }
  42. );
  43. EOT;
  44. foreach ($snapshot->globalVariables() as $name => $value) {
  45. $result .= sprintf(
  46. '$GLOBALS[%s] = %s;' . PHP_EOL,
  47. $this->exportVariable($name),
  48. $this->exportVariable($value),
  49. );
  50. }
  51. return $result;
  52. }
  53. public function iniSettings(Snapshot $snapshot): string
  54. {
  55. $result = '';
  56. foreach ($snapshot->iniSettings() as $key => $value) {
  57. $result .= sprintf(
  58. '@ini_set(%s, %s);' . "\n",
  59. $this->exportVariable($key),
  60. $this->exportVariable($value),
  61. );
  62. }
  63. return $result;
  64. }
  65. private function exportVariable(mixed $variable): string
  66. {
  67. if (is_scalar($variable) || null === $variable ||
  68. (is_array($variable) && $this->arrayOnlyContainsScalars($variable))) {
  69. return var_export($variable, true);
  70. }
  71. return 'unserialize(' . var_export(serialize($variable), true) . ')';
  72. }
  73. private function arrayOnlyContainsScalars(array $array): bool
  74. {
  75. $result = true;
  76. foreach ($array as $element) {
  77. if (is_array($element)) {
  78. $result = $this->arrayOnlyContainsScalars($element);
  79. } elseif (!is_scalar($element) && null !== $element) {
  80. $result = false;
  81. }
  82. if ($result === false) {
  83. break;
  84. }
  85. }
  86. return $result;
  87. }
  88. }