Impossible to redirect subprocess stderr on macOS

This particular behaviour have nothing at all to do with any "impossibility" of redirecting subprocess stderr on macOS. It is not impossible, and works like you would expect - i.e. similar to Linux and FreeBSD.

The gotcha here is that you're using different PHP configurations on those setups. It seems you're not using the stock supplied PHP, but rather something else - but I'll explain according to the stock PHP considering that the same will apply to a custom install.

The way PHP works is that it outputs these types of errors messages according to the setting of the "display_errors" configuration directive. You can choose to either mute it completely (i.e. never output the error), output to stdout (the default) or output to stderr.

You'll commonly set the value of display_error in /etc/php.ini - if you haven't got a php.ini file, or display_errors is not set in it, it will default to stdout. If you're using a custom built php, the location of the php.ini file will vary.

You can test this out by performing the following in the Terminal:

php -r 'foo();' 2>/dev/null

Produces

Fatal error: Uncaught Error: Call to undefined function foo() in Command line code:1
Stack trace:
#0 {main}
  thrown in Command line code on line 1

However running:

php -d'display_errors=stderr' -r 'foo();' 2>/dev/null

Produces no output.

You can also use 1>/dev/null to redirect stdout, and then you'll see that the behaviour reverses between those two examples.

Note also that the setting "on" for display_errors is the same as "stdout".