Você provavelmente tem uma variável de ambiente $LS_COLORS definida em algum lugar no seu ~/.bashrc / ~/.zshrc ... (provavelmente por meio de uma chamada de eval "$(dircolors)" ).
O php que você executa na linha de comando herdará o ambiente do seu shell, incluindo essa variável $LS_COLORS .
Enquanto o iniciado por apache2 herdará o ambiente de apache2 , é improvável que tenha $LS_COLORS nele. bash não lê ~/.bashrc (e, de qualquer forma, seria o ~/.bashrc do usuário executando o apache, se assim fosse) quando não fosse executado interativamente (exceto em casos de canto como quando invocado por sshd / rshd / telnetd ).
Observe que php ' exec() já inicia um shell, portanto, não é necessário iniciar outro (especialmente bash , que é o shell mais lento no oeste).
exec('ls --color=always', $result);
deve ser o suficiente.
$ strace -fe execve php -r 'exec("bash -c echo\ test");'
execve("/usr/bin/php", ["php", "-r", "exec(\"bash -c echo\ test\");"], [/* 49 vars */]) = 0
[pid 3608] execve("/bin/sh", ["sh", "-c", "bash -c echo\ test"], [/* 49 vars */]) = 0
[pid 3608] execve("/bin/bash", ["bash", "-c", "echo test"], [/* 48 vars */]) = 0