47 lines
2.2 KiB
PHP
47 lines
2.2 KiB
PHP
<?php
|
|
namespace Xxx\Tests\Support;
|
|
|
|
/*
|
|
* Run PHP code in a new process, after tests/php/bootstrap.php. This is
|
|
* for code that ends the script (die, exit) or that needs php.ini
|
|
* settings which cannot change at run time, such as sendmail_path.
|
|
*/
|
|
class PhpProcess {
|
|
/*
|
|
* Returns array('status' => exit code, 'stdout' => ..., 'stderr' => ...,
|
|
* 'log' => what the code wrote to the PHP error log).
|
|
*/
|
|
public static function run(string $code, array $env = array(), array $ini = array()): array {
|
|
// One line, so that line numbers in $code stay the same; the code runs
|
|
// in publish/, as the unit tests do
|
|
return self::runPlain("require " . var_export(XXX_ROOT . '/tests/php/bootstrap.php', TRUE) . "; chdir(XXX_ROOT . '/publish');\n" . $code, $env, $ini);
|
|
}
|
|
|
|
// The same with only the test environment, for code that includes a site library itself
|
|
public static function runBare(string $code, array $env = array(), array $ini = array()): array {
|
|
return self::runPlain("require " . var_export(XXX_ROOT . '/tests/php/environment.php', TRUE) . ";\n" . $code, $env, $ini);
|
|
}
|
|
|
|
// The same without the bootstrap: the code loads what it needs itself
|
|
public static function runPlain(string $code, array $env = array(), array $ini = array()): array {
|
|
$script = tempnam(sys_get_temp_dir(), 'xxx-php-');
|
|
$log = $script . '.log';
|
|
file_put_contents($script, "<?php\n" . $code);
|
|
$command = array(PHP_BINARY, '-d', 'display_errors=stderr', '-d', 'error_reporting=-1', '-d', "error_log=$log");
|
|
foreach ($ini as $name => $value)
|
|
array_push($command, '-d', "$name=$value");
|
|
$command[] = $script;
|
|
$env = array_merge(getenv(), array('XXX_TEST_LOG' => $log), $env);
|
|
$process = proc_open($command, array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes, XXX_ROOT, $env);
|
|
$stdout = stream_get_contents($pipes[1]);
|
|
$stderr = stream_get_contents($pipes[2]);
|
|
fclose($pipes[1]);
|
|
fclose($pipes[2]);
|
|
$status = proc_close($process);
|
|
$logged = is_file($log) ? file_get_contents($log) : '';
|
|
@unlink($script);
|
|
@unlink($log);
|
|
return array('status' => $status, 'stdout' => $stdout, 'stderr' => $stderr, 'log' => $logged);
|
|
}
|
|
}
|