D
D
danilasar2021-12-11 22:57:17
PHP
danilasar, 2021-12-11 22:57:17

Why can't PDO connect to a database from under CGI?

Good day. For some reason, it became necessary to execute the PHP script in FastCGI mode. In theory, this should not have provided any obstacles, including in terms of security, but for some reason PDO fell off.
Initially, it established a connection with MS SQL Server (an extension from Microsoft - php_pdo_sqlsrv), this led to crashes (the php-cgi.exe program stopped working) when creating an object of the \PDO class. For the sake of testing, I tried to connect to PostgreSQL, but got an error:

SQLSTATE[08006] [7] could not create socket: The requested service provider could not be loaded or initialized.
 (0x0000277A/10106))

At the same time, when executing the same code as part of the standard PHP-Apache bundle, everything works fine.
I use PHP 7.4 x64 Thread Safe for Windows, in php.ini, of course, the extensions are connected.

index.php, which is loaded from under Apache and makes a call to the CGI script, duplicating HTTP headers:
<?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);
  }

Test CGI script:
<?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!!!';

The result of execution to index.php looks like this . And when accessing program.php directly, it gives a different result when connected to PDO.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question