Доброго времени суток. По некоторым причинам возникла необходимость выполнять PHP-скрипт в режиме FastCGI. По идее, это не должно было предоставить каких-либо препятствий, в том числе в плане безопасности, но по какой-то причине отвалился PDO.
Изначально устанавливал соединение с MS SQL Server (расширение от Microsoft - php_pdo_sqlsrv), это приводило к вылетам (прекращена работа программы php-cgi.exe) при создании объекта класса \PDO. Ради теста попробовал подключиться к PostgreSQL, на что получил ошибку:
SQLSTATE[08006] [7] could not create socket: The requested service provider could not be loaded or initialized.
(0x0000277A/10106))
При этом, выполняя тот же самый код в рамках стандартной связки PHP-Apache, всё отрабатывает прекрасно.
Использую PHP 7.4 x64 Thread Safe для Windows, в php.ini, само собой, расширения подключены.
index.php, который загружается из-под Apache и выполняет обращение к CGI-скрипту, дублируя HTTP-заголовки:
<?php
$result;
$cmd = getenv('PHPDIR') . 'php-cgi.exe';
$descriptorspec = array(
0 => array("pipe", "r"), // stdin - канал, из которого дочерний процесс будет читать
1 => array("pipe", "w"), // stdout - канал, в который дочерний процесс будет записывать
2 => array("file", "/error.log", "a") // stderr - файл для записи
);
$cwd = './';
$env = [];
$_SERVER['REDIRECT_STATUS'] = 'CGI';
$_SERVER['SCRIPT_FILENAME'] = __DIR__ . '/program.php';
$variables = [
'AUTH_TYPE', 'CONTENT_LENGTH', 'CONTENT_TYPE', 'GATEWAY_INTERFACE', 'PATH_INFO', 'PATH_TRANSLATED', 'QUERY_STRING', 'REMOTE_ADDR', 'REMOTE_HOST', 'REMOTE_IDENT', 'REMOTE_USER', 'REQUEST_METHOD', 'SERVER_NAME', 'SERVER_PORT', 'SERVER_PROTOCOL', 'SERVER_SOFTWARE', 'REDIRECT_STATUS', 'SCRIPT_FILENAME', 'REQUEST_URI', 'REQUEST_METHOD'
];
foreach($variables as $var) {
if(isset($_SERVER[$var])) {
$env[$var] = $_SERVER[$var];
}
}
$pipes;
$process = proc_open($cmd, $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process)) {
fwrite($pipes[0], http_build_query($_POST));
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
proc_close($process);
}
Тестовый CGI-скрипт:
<?php
phpinfo();
try {
$db = new PDO('pgsql:host=127.0.0.1;port=5432;dbname=postgres', 'postgres', '');
} catch(PDOException $e) {
echo('{"error": "Не установлено соединение с БД (' . $e->getMessage() . ')"}');
exit;
}
echo 'It\'s work!!!';
Результат выполнения к index.php выглядит
так. А при обращении напрямую к program.php
отдаёт иной результат при подключении к PDO.