nginx extensionless php url without if statement - php

I use this config:
root /www/mysite/static
location / {
try_files $uri #php;
}
location #php {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /www/mysite/controller$fastcgi_script_name.php;
}
This will first check if /www/mysite/static has the file. If it can't find the file, then it will run fastcgi on "file.php".
Now if I go to www.mysite.com/asdf, it will try to run fastcgi with /www/mysite/controller/asdf.php, which doesn't exist.
I read that If statement is evil, so what should I do instead?

Finally figured it out:
location /info {
root /usr/share/nginx/www;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/www/info.php;
}
Actually makes sense now as I've bothered to read the documentation...

Related

Increase fastcgi_read_timeout for single route

I have the following Nginx configuration for forwarding requests to a PHP-FPM backend:
server {
...
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~* \.php$ {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
}
One specific route in the app needs a slightly longer php max_execution_time setting. I've configured this successfully and verified it works by setting a longer fastcgi_read_timeout in the above config.
However, I don't need this to be applied to every single route. I'm guessing I need a nested location somewhere but nothing I've tried seems to work!
The fastcgi_read_timeout directive does not appear to accept dynamic values, so a separate location block for the special route will be required. Looking at your configuration file, I assume the special route is a unique URI processed by the /index.php script. Something like this should work:
location ^~ /special/route/uri {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_pass 127.0.0.1:9000;
fastcgi_read_timeout 100s;
}
You can use a prefix location with the ^~ modifier (as above) to override the regex location that usually processes PHP files. Alternatively, you can use a regex location, but place it above the existing regex location so that it takes precedence.
See this document for location syntax.

NGNIX - look in multiple directories for a .php file and then excecute it

I have .php files in multiple directories (/jobs/marketing/, /jobs/content/ etc) that need to map cleanly to /jobs/name-of-file.php.
For example hitting the url:
/jobs/digital-marketing
needs to map to:
/jobs/marketing/digital-marketing.php
It's safe to assume the file name of each php file is unique across directories.
my current nginx setup is the following:
location /jobs {
expires max;
add_header Cache-Control public;
add_header Pragma public;
rewrite ^/jobs[\/]?$ /marketing/jobs.php last;
location ~* ^/jobs/([\-a-z0-9]*)$ {
try_files /marketing/jobs/engineering/$1.php
/marketing/jobs/marketing/$1.php
/marketing/jobs/business-development/$1.php
/marketing/jobs/content/$1.php;
}
location ~ ^/.+\.php($|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
include fastcgi_params;
fastcgi_read_timeout 3000;
}
}
This seems pretty close, except a plain text version of the file gets downloaded instead of nginx redirecting to it. I think I need to somehow catch the correct file with another location block, but I nothing seems to be working (that might not even be the correct approach).
Any ideas about how to achieve this? Or a better approach perhaps?
Thanks.
I belive that you are using try_files a bit wrong. What it does is
Checks the existence of files in the specified order and uses the
first found file for request processing; the processing is performed
in the current context.
You have one context with location ~* ^/jobs/([-a-z0-9]*)$ and another with location ~ ^/.+.php($|/)
So you are finding files but not processing them through PHP as your processing is in another context.
Therefore I belive you should add php processing in your try_files location.
location ~* ^/jobs/([\-a-z0-9]*)$ {
try_files /marketing/jobs/engineering/$1.php
/marketing/jobs/marketing/$1.php
/marketing/jobs/business-development/$1.php
/marketing/jobs/content/$1.php;
...
fastcgi_param ...;
fastcgi_pass ...;
}
To not write same config for both /jobs and .php locations you can cut it to file and include like you do with include fastcgi_params;
So ok, if your actual location directs to correct files - we're half way there. At this moment nginx is trying to download files - let's try to add another location directing those files to PHP parser - this one works for me:
location ~ ^/.+\.php($|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
include fastcgi_params;
fastcgi_read_timeout 3000;
}
Add this piece of code after your location and let me know if this works for you. You can read more about nginx with PHP here

Nginx alias with laravel4

My nginx configuration for laravel
server {
listen 80;
server_name app.dev;
rewrite_log on;
root /var/www/l4/angular;
index index.html;
location /{
# URLs to attempt, including pretty ones.
try_files $uri $uri/ /index.php?$query_string;
}
location /lara/ {
index index.php;
alias /var/www/l4/public/;
}
# Remove trailing slash to please routing system.
if (!-d $request_filename) {
rewrite ^/(.+)/$ /$1 permanent;
}
location ~ ^/lara/(.*\.php)$ {
alias /var/www/l4/public/$1;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Laravel route:
Route::get('/', function()
{
return View::make('index');
});
Route::get('x', function()
{
return "alpha";
});
my problem is,"http://app.dev/lara/index.php" is working but "http://app.dev/lara" and lara/x is not working.
In a nutshell, make the following edits. An explanation of why is below.
Replace
try_files $uri $uri/ /index.php?$query_string;
with
try_files $uri $uri/ /lara/index.php?$query_string;
Replace the last location directive with this
location ~ /lara/(.*)$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME "/var/www/l4/public/index.php";
fastcgi_param REQUEST_URI /$1;
}
Restart nginx.
Now the why. I spotted a couple of mistakes with your nginx config. First, /index.php?$query_string in the try_files directive should be /lara/index.php?$query_string, otherwise nginx will try a request like http://app.dev/lara as /var/www/l4/angular/index.php?, which leads no where (unless you have an index.php there, and even is it will be served as text, not through fpm).
The second has to do with the location ~ ^/lara/(.*\.php)$ directive. I think restricting it to URIs that end with .php is wrong, because it won't work for http://app.dev/lara/x, which will make nginx only search for /var/www/l4/public/x, returning 404 of course. Changing the regex to ^/lara/(.*)$ should do the job of catching /lara/x. Now the fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; directive is erroneous because for http://app.dev/lara/x, SCRIPT_FILENAME is /var/www/l4/public/x/lara/x, and removing the $1 in the alias directive won't make it any better. Instead, make the fastcgi_param like this fastcgi_param SCRIPT_FILENAME "/var/www/l4/public/index.php";, remove the alias directive, it's useless now, then move include fastcgi_params; above the fastcgi_param so it won't override SCRIPT_FILENAME value.
Done? Not yet :). Trying /lara/x will show a Laravel routing error, because it tries to find the route lara/x instead of x, this is because you're including fastcgi_params. Just add fastcgi_param REQUEST_URI /$1; after SCRIPT_FILENAME param directive. Now it should be working fine. Don't forget to restart nginx :).

Nginx passing parameters to a PHP file

I'm trying to pass all the requests that hits a specific location, to a PHP file with the request URL via Nginx config file, I've almost done this but I cannot pass the URL to the PHP file.
I've tried var_dump($_REQUEST); var_dump($_ENV); var_dump($argv); but returns NULL or emtpy array results.
location /p/ {
try_files $uri $uri/ #php;
}
location #php {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/process/internal/t.php; # this script catches all requests
fastcgi_param QUERY_STRING $uri;
include fastcgi_params;
}
Try to move the include fastcgi_params; higher, above the fastcgi_params

Block apc.php file in nginx

I am trying to block the apc.php file on my webserver. If do the following it works but I am thinking there is a better way to do this and put the deny/allow rule below the general location ~ .php$ block. It doesnt seem right to have to have two blocks with the fastcgi params.
#Block to apc.php
location ~ /apc.php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
allow 192.168.3.0/24;
deny all;
}
# use fastcgi for all php files
location ~ \.php$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Since "deny" not allowed in if statement, you can use nested location like location / { location /uri/ {} }, however, it is not encouraged in Nginx manual:
"While nested locations are allowed by the configuration file parser,
their use is discouraged and may produce unexpected results."

Categories