Runtime.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. /*
  3. * This file is part of the Environment package.
  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\Environment;
  11. /**
  12. * Utility class for HHVM/PHP environment handling.
  13. */
  14. class Runtime
  15. {
  16. /**
  17. * @var string
  18. */
  19. private static $binary;
  20. /**
  21. * Returns true when Xdebug is supported or
  22. * the runtime used is PHPDBG (PHP >= 7.0).
  23. *
  24. * @return bool
  25. */
  26. public function canCollectCodeCoverage()
  27. {
  28. return $this->hasXdebug() || $this->hasPHPDBGCodeCoverage();
  29. }
  30. /**
  31. * Returns the path to the binary of the current runtime.
  32. * Appends ' --php' to the path when the runtime is HHVM.
  33. *
  34. * @return string
  35. */
  36. public function getBinary()
  37. {
  38. // HHVM
  39. if (self::$binary === null && $this->isHHVM()) {
  40. if ((self::$binary = getenv('PHP_BINARY')) === false) {
  41. self::$binary = PHP_BINARY;
  42. }
  43. self::$binary = escapeshellarg(self::$binary) . ' --php';
  44. }
  45. // PHP >= 5.4.0
  46. if (self::$binary === null && defined('PHP_BINARY')) {
  47. if (PHP_BINARY !== '') {
  48. self::$binary = escapeshellarg(PHP_BINARY);
  49. }
  50. }
  51. // PHP < 5.4.0
  52. if (self::$binary === null) {
  53. if (PHP_SAPI == 'cli' && isset($_SERVER['_'])) {
  54. if (strpos($_SERVER['_'], 'phpunit') !== false) {
  55. $file = file($_SERVER['_']);
  56. if (strpos($file[0], ' ') !== false) {
  57. $tmp = explode(' ', $file[0]);
  58. self::$binary = escapeshellarg(trim($tmp[1]));
  59. } else {
  60. self::$binary = escapeshellarg(ltrim(trim($file[0]), '#!'));
  61. }
  62. } elseif (strpos(basename($_SERVER['_']), 'php') !== false) {
  63. self::$binary = escapeshellarg($_SERVER['_']);
  64. }
  65. }
  66. }
  67. if (self::$binary === null) {
  68. $possibleBinaryLocations = [
  69. PHP_BINDIR . '/php',
  70. PHP_BINDIR . '/php-cli.exe',
  71. PHP_BINDIR . '/php.exe'
  72. ];
  73. foreach ($possibleBinaryLocations as $binary) {
  74. if (is_readable($binary)) {
  75. self::$binary = escapeshellarg($binary);
  76. break;
  77. }
  78. }
  79. }
  80. if (self::$binary === null) {
  81. self::$binary = 'php';
  82. }
  83. return self::$binary;
  84. }
  85. /**
  86. * @return string
  87. */
  88. public function getNameWithVersion()
  89. {
  90. return $this->getName() . ' ' . $this->getVersion();
  91. }
  92. /**
  93. * @return string
  94. */
  95. public function getName()
  96. {
  97. if ($this->isHHVM()) {
  98. return 'HHVM';
  99. } elseif ($this->isPHPDBG()) {
  100. return 'PHPDBG';
  101. } else {
  102. return 'PHP';
  103. }
  104. }
  105. /**
  106. * @return string
  107. */
  108. public function getVendorUrl()
  109. {
  110. if ($this->isHHVM()) {
  111. return 'http://hhvm.com/';
  112. } else {
  113. return 'https://secure.php.net/';
  114. }
  115. }
  116. /**
  117. * @return string
  118. */
  119. public function getVersion()
  120. {
  121. if ($this->isHHVM()) {
  122. return HHVM_VERSION;
  123. } else {
  124. return PHP_VERSION;
  125. }
  126. }
  127. /**
  128. * Returns true when the runtime used is PHP and Xdebug is loaded.
  129. *
  130. * @return bool
  131. */
  132. public function hasXdebug()
  133. {
  134. return ($this->isPHP() || $this->isHHVM()) && extension_loaded('xdebug');
  135. }
  136. /**
  137. * Returns true when the runtime used is HHVM.
  138. *
  139. * @return bool
  140. */
  141. public function isHHVM()
  142. {
  143. return defined('HHVM_VERSION');
  144. }
  145. /**
  146. * Returns true when the runtime used is PHP without the PHPDBG SAPI.
  147. *
  148. * @return bool
  149. */
  150. public function isPHP()
  151. {
  152. return !$this->isHHVM() && !$this->isPHPDBG();
  153. }
  154. /**
  155. * Returns true when the runtime used is PHP with the PHPDBG SAPI.
  156. *
  157. * @return bool
  158. */
  159. public function isPHPDBG()
  160. {
  161. return PHP_SAPI === 'phpdbg' && !$this->isHHVM();
  162. }
  163. /**
  164. * Returns true when the runtime used is PHP with the PHPDBG SAPI
  165. * and the phpdbg_*_oplog() functions are available (PHP >= 7.0).
  166. *
  167. * @return bool
  168. */
  169. public function hasPHPDBGCodeCoverage()
  170. {
  171. return $this->isPHPDBG() && function_exists('phpdbg_start_oplog');
  172. }
  173. }