/** * Check file syntax via runkit_lint_file if supported or via php -l * @param string File name * @return boolean */ public static function lintFile($filename) { if (!file_exists($filename)) { return false; } if (self::supported(self::SUPPORT_RUNKIT_SANDBOX)) { /** @noinspection PhpUndefinedFunctionInspection */ return runkit_lint_file($filename); } $cmd = 'php -l ' . escapeshellcmd($filename) . ' 2>&1'; exec($cmd, $output, $retcode); return 0 === $retcode; }
/** * Builds a test suite from a library of test cases. * The new suite is composed into this one. * @param string $test_file File name of library with * test case classes. * @return TestSuite The new test suite. * @access public */ function load($test_file) { $existing_classes = get_declared_classes(); $existing_globals = get_defined_vars(); // as the included file can contain errors, we don't want to crash, but report those instead! // // See also: http://us3.php.net/manual/en/function.php-check-syntax.php // // NOTE: you can also load the file content and then pull it through eval(): that one though will // NOT report the parse error, only return FALSE ( http://nl.php.net/manual/en/function.eval.php ) $parse_err = -1; if (is_readable($test_file)) { $code = @file_get_contents($test_file); if ($code === false) { return new BadTestSuite($test_file, "Could not load the contents of the file"); } $shell = new SimpleShell(); $parse_err = $shell->execute('php -l "' . realpath($test_file) . '"'); if ($parse_err) { // either we're not being allowed to run a php cli, or we got an actual parse error: find out which it is $out = $shell->getOutput(); if (strpos($out, 'syntax error') !== false) { return new BadTestSuite($test_file, "There is a SYNTAX ERROR in the file:\n" . trim($out)); } /* * ELSE: seems we weren't able to run the php cli; we cannot fall back to the eval() way of checking the code * as that would also /execute/ the code, which is sorta okay, apart from the fact that the code-under-test * may collide with the simpletest code itself (e.g. when simpletest is used to test itself), resulting in * eval failures such as 'cannot redefine class', while the code to test is perfectly fine. * * We can, however, use runkit_lint_file(), IFF it exists in our PHP install... */ if (function_exists('runkit_lint_file')) { $ret = runkit_lint_file($test_file); if ($ret === false) { // to display the code causing the error: $code = htmlentities($code, ENT_NOQUOTES); return new BadTestSuite($test_file, "There is a SYNTAX ERROR ({$php_errormsg}) in the file. Besides, you should adjust your setup so we can invoke 'php -l' as that gives you much more info about this error than a mere 'syntax error'."); } } } include_once $test_file; // or should this really be 'include' instead of 'include_once'? } else { return new BadTestSuite($test_file, "You don't have read access to the file"); } $new_globals = get_defined_vars(); $this->makeFileVariablesGlobal($existing_globals, $new_globals); $new_classes = array_diff(get_declared_classes(), $existing_classes); if (empty($new_classes)) { $new_classes = $this->scrapeClassesFromFile($test_file); } $classes = $this->selectRunnableTests($new_classes); return $this->createSuiteFromClasses($test_file, $classes); }