Search code examples
phpfsockopenunix-socketfpm

PHP listen to unix socket


So in short I'm trying to get a PHP script to listen for requests over unix sockets and send it a request from another PHP script. I have configured PHP-FPM as such:

[a]

; Unix user/group of processes
user = www
group = www

listen = /var/run/php-fpm-a.sock
;listen.backlog = -1

listen.owner = www
listen.group = www
listen.mode = 0660

; Choose how the process manager will control the number of child processes.
pm = dynamic
pm.max_children = 75
pm.start_servers = 3
pm.min_spare_servers = 1
pm.max_spare_servers = 5
pm.max_requests = 500

; host-specific php ini settings here
php_admin_value[open_basedir] = /usr/local/www/a
php_flag[display_errors] = on
/usr/local/www/a contains the following index.php:

<?php
echo 'test\ntest\ntest\n';

There is another PHP-FPM config file that effectively listens at /var/run/php-fpm-b.sock and Nginx points to it (this bit works fine), this contains the following code in /usr/local/www/b/index.php:

echo 'TEST B';
$fp = fsockopen('unix:///var/run/php-fpm-a.sock', -1, $errno, $errstr, 30);
if (!$fp) {
  echo "$errstr ($errno)<br />\n";
} else {
  $out = "GET /index.php HTTP/1.1\r\n";
  $out .= "Host: localhost\r\n";
  $out .= "Connection: Close\r\n\r\n";
  fwrite($fp, $out);
  while (!feof($fp)) {
    echo fgets($fp, 128);
  }

  fclose($fp);
}

Clearly I have something wrong in /usr/local/www/b/index.php as all I get is "TEST B" as the output. I don't think it's a socket permission issue as it would state so with an error, my guess is $out is wrong for this to work but have no idea what PHP excepts to receive. Any help would be appreciated.

Note: using PHP7 on FreeBSD11


Solution

  • PHP-FPM is a FastCGI Process Manager. FastCGI and HTTP are two different protocols. So, PHP-FPM can't speak HTTP directly.

    browser -> (HTTP) -> nginx -> (FastCGI) -> PHP-FPM + scriptB
    scriptB -> (HTTP) -> PHP-FPM + scriptA
    

    You have two options:

    • Put script A behind nginx and then open TCP socket instead of unix socket to communicate from B to A.
    • Modify script B to speak in FastCGI language with script A instead of HTTP.