PHPDBG.php (2846B)
1 <?php 2 /* 3 * This file is part of the PHP_CodeCoverage 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 11 /** 12 * Driver for PHPDBG's code coverage functionality. 13 * 14 * @since Class available since Release 2.2.0 15 * @codeCoverageIgnore 16 */ 17 class PHP_CodeCoverage_Driver_PHPDBG implements PHP_CodeCoverage_Driver 18 { 19 /** 20 * Constructor. 21 */ 22 public function __construct() 23 { 24 if (PHP_SAPI !== 'phpdbg') { 25 throw new PHP_CodeCoverage_Exception( 26 'This driver requires the PHPDBG SAPI' 27 ); 28 } 29 30 if (!function_exists('phpdbg_start_oplog')) { 31 throw new PHP_CodeCoverage_Exception( 32 'This build of PHPDBG does not support code coverage' 33 ); 34 } 35 } 36 37 /** 38 * Start collection of code coverage information. 39 */ 40 public function start() 41 { 42 phpdbg_start_oplog(); 43 } 44 45 /** 46 * Stop collection of code coverage information. 47 * 48 * @return array 49 */ 50 public function stop() 51 { 52 static $fetchedLines = array(); 53 54 $dbgData = phpdbg_end_oplog(); 55 56 if ($fetchedLines == array()) { 57 $sourceLines = phpdbg_get_executable(); 58 } else { 59 $newFiles = array_diff( 60 get_included_files(), 61 array_keys($fetchedLines) 62 ); 63 64 if ($newFiles) { 65 $sourceLines = phpdbg_get_executable( 66 array('files' => $newFiles) 67 ); 68 } else { 69 $sourceLines = array(); 70 } 71 } 72 73 foreach ($sourceLines as $file => $lines) { 74 foreach ($lines as $lineNo => $numExecuted) { 75 $sourceLines[$file][$lineNo] = self::LINE_NOT_EXECUTED; 76 } 77 } 78 79 $fetchedLines = array_merge($fetchedLines, $sourceLines); 80 81 return $this->detectExecutedLines($fetchedLines, $dbgData); 82 } 83 84 /** 85 * Convert phpdbg based data into the format CodeCoverage expects 86 * 87 * @param array $sourceLines 88 * @param array $dbgData 89 * @return array 90 */ 91 private function detectExecutedLines(array $sourceLines, array $dbgData) 92 { 93 foreach ($dbgData as $file => $coveredLines) { 94 foreach ($coveredLines as $lineNo => $numExecuted) { 95 // phpdbg also reports $lineNo=0 when e.g. exceptions get thrown. 96 // make sure we only mark lines executed which are actually executable. 97 if (isset($sourceLines[$file][$lineNo])) { 98 $sourceLines[$file][$lineNo] = self::LINE_EXECUTED; 99 } 100 } 101 } 102 103 return $sourceLines; 104 } 105 }