@danilasar

Почему PDO не может соединиться с БД из-под CGI?

Доброго времени суток. По некоторым причинам возникла необходимость выполнять 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.
  • Вопрос задан
  • 146 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы