Reescreva tudo * .php para o único index.php antes que o php-fpm o processe (apache)

2

Uma aplicação legada é passada através do Slim framework passando todas as requisições de arquivo PHP legadas para index.php em um arquivo .htaccess. Além disso, um aplicativo Symfony é configurado em uma pasta com um Alias configurado.

Configuração do VHost com PHP-FPM

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /path/to/app/slim
    Alias /system /path/to/app/symfony
    <IfModule mpm_itk_module>
            AssignUserId web_user web_user
    </IfModule>
    <LocationMatch "^(.*\.php)$">
            ProxyPass fcgi://127.0.0.1:9001/path/to/app/slim
    </LocationMatch>
</VirtualHost>

Arquivos para teste:

/path/to/slim/index.php

<?php echo "slim";

/path/to/slim/.htaccess

RewriteEngine On
RewriteBase /    
RewriteRule ^hello$ /hello.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

/path/to/slim/hello.php:

<?php echo "hello";

/path/to/symfony/app.php

<?php echo "symfony";

/path/to/symfony/.htaccess:

DirectoryIndex app.php
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::$
    RewriteRule ^(.*) - [E=BASE:%1]
    RewriteCond %{HTTP:Authorization} .
    RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^app\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]

    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^ - [L]

    RewriteRule ^ %{ENV:BASE}/app.php [L]
</IfModule>


Test Uri                 Expected Output           Actual Output

/hello.php               hello                     hello
----------------------------------------------------------------------
/test                    slim                      slim
----------------------------------------------------------------------
/test.php                slim                      404 error
                                                   [proxy_fcgi:error] [pid 18527] [client x.x.x.x:45357] AH01071: Got error 'Primary script unknown\n'
----------------------------------------------------------------------
/system/hello            symfony                   symfony
/system/app.php/hello    symfony                   symfony

Eu tentei isso tanto no Ubuntu 16 quanto no CentOs 7 com os mesmos resultados. Usando o Apache 2.4, AllowOverride All e mod_rewrite ativados. PHP7-fpm

O que mais eu tentei:

1)                  ProxyPass fcgi: //127.0.0.1: 9001 / caminho / para / app / slim / index.php     

para /test.php mostra "slim", no entanto, o pedido é, então, mal interpretado no framework slim como "/".

De acordo com a documentação do Apache .htaccess deve ser processada primeiro.

Qual é a melhor maneira de resolver isso?

(Nota: Bounty diz que eu não quero padronizar a configuração do Apache. Este é um erro de digitação.

EU QUERO padronizar a configuração do Apache)

    
por jdog 26.01.2017 / 04:19

3 respostas

2

Seu problema é o uso de <LocationMatch> para proxy ao php-fpm, que é aplicado a todas as URLs antes verificando se existe um arquivo correspondente. ( ProxyPassMatch faria a mesma coisa com mais elegância, a propósito). Para citar o documentação sobre <Location> :

<Location> sections operate completely outside the filesystem.

No entanto, você obviamente do quer verificar se o arquivo PHP existe antes de passá-lo para o php-fpm. Isso pode ser feito usando <FilesMatch> e SetHandler :

<FilesMatch \.php$>
    SetHandler "proxy:fcgi://127.0.0.1:9001/"
</FilesMatch>

(Eu mesmo estou usando soquetes unix aqui, como na documentação que eu fiz o link acima, então eu não estou 100% confiante de que esta é a sintaxe certa para o URL.)

Desta forma, apenas arquivos serão redirecionados para php-fpm, e suas regras mod_rewrite terão a chance de serem aplicadas até mesmo a URIs que terminem em .php quando os arquivos correspondentes não existirem. / p>

Note também que usar FallbackResource não tem nenhuma influência sobre isso, porque novamente o <LocationMatch> tem prioridade e procura até mesmo URIs inexistentes para php-fpm. Ele apenas redireciona aqueles URIs que, de outra forma, usariam o manipulador 404 embutido do Apache, mas isso não acontece como você já observou.

    
por 02.02.2017 / 12:49
0

À primeira vista, você parece não ter a diretiva AllowOverride no virtualhost, então é normal que o arquivo não esteja sendo lido, ainda me pergunto:

Por que você está usando o .htaccess se você tem acesso ao virtualhost? Você está apenas tentando complicar sua vida (como você já está fazendo) usando-a.

Esqueça o .htaccess e todas as diretivas de reescrita e adicione esta linha simples em seu virtualhost:

FallBackResource /index.php

Isso basicamente fará o mesmo com todas as suas 5 diretivas de reescrita, em uma única linha.

Sobre " script principal desconhecido ", verifique o que o fpm tem a dizer, você pode estar apontando para o caminho incorreto do e configurando o fpm incorretamente

Lembre-se de evitar definir suas diretivas em contexto por diretório sempre que possível para evitar pesadelos e dores de cabeça constantes.

    
por 27.01.2017 / 16:18
0

Você afirma que solicitações como /test funcionam, mas /test.php não.

Quando isso acontece, é sempre o caso em que /test.php não existe e é uma solicitação que termina com .php ? Em caso afirmativo, o que você poderia fazer é instruir o navegador para fazer automaticamente outra solicitação, removendo a parte .php .

O que pode ser conseguido com:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*)\.php$ $1 [R]

De acordo com o link , a opção R emite um redirect .

Eu não confiaria em .htaccess e o colocaria diretamente na configuração do servidor, dentro do <LocationMatch "^(.*\.php)$"> que você já tem e antes da diretiva ProxyPass dentro dele.

    
por 29.01.2017 / 20:14