I have created a try_files directive that tries files in a different directory than the files are put in. I.e., if I visit www.example.com/home/main it will try the file /var/www/main/home/main.php. It works, but when I visit a page, it only shows the PHP source code and not the processed page. Here is my directive:
location ~ /home/ {
index main.php
try_files /main$uri.php #404;
location \.php {
fastcgi_pass php_server;
include fastcgi_params;
}
}
Any ideas on how I can get the page to process instead of just showing the PHP source?
Edit for additional information: I have tried making a location directive that looks like
location ~ /main/(.*)\.php {
fastcgi_pass php_server;
include fastcgi_params;
}
but this doesn't work either and the pages still show just the source code.
Of course it will show you source, since you don't have fastcgi_pass in your /home/ location.
Try this one:
location /home/ {
try_files /main$uri.php #static;
fastcgi_pass php_server;
include fastcgi_params;
}
location #static { }
EDIT: Actually the below is wrong - the last parameter is always used as a redirect if the file can't be found anywhere else in the try_files directive. In this example, it is hitting the .php file, but not be processed, so the #404 wasn't being hit. However, if no #404 example exists, then a failure to find the file would blow up anyways.
In the event that no file is found, an internal redirect to the last parameter is invoked [...]The last parameter is the fallback URI and must exist, or else an internal error will be raised.
source: http://wiki.nginx.org/HttpCoreModule#try_files
The #404 at the end of your try_files directive will send the php file to be parsed by a location #404 directive, not your php directive that uses fastcgi.
Try dropping the #404 or simple doing: try_files $uri /main$uri.php;
Related
I have files in the following structure
index.php
help.php
help\helpone.php
help\helptwo.php
If I visit something.com, I'm taken to the correct index page with the .php removed from the end. When I goto something.com/help, nginx throws a 403. This is happening because there is a help folder inside the same directory. The requirement is to visit something.com/help to see the help page
help page has links to the other pages, so on click it becomes something.com/help/helpone
I have the following server block that does the operation.
server {
root /usr/share/nginx/landing;
server_name sample.com;
index index.php index.html;
location / {
try_files $uri/ $uri.php$is_args$query_string;
}
location ~ \.php {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_index index.php;
}
}
How can I achive sample.com/help without getting 403
That's because first it tries help/ directory, not help.php file. There is no index.php inside, so it shows 403 error.
Try:
location / {
try_files $uri.php$is_args$query_string $uri/;
}
Or change the name of help.php file or directory.
So the solution to this issue was to move the help.php which was in the root directory to help\index.php This way Nginx will directly look inside folder help for index.php instead of conflicting between the help.php which was outside and the folder help doing a Forbidden Access.
Now going to sample.com/help goes directly into sample.com/help/index.php whithout showing you the index.php of-course.
Attaching nginx block for reference although nothing much changed.
index index.php index.html;
location / {
try_files $uri/ $uri.php;
}
location ~ \.php {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_index index.php;
}
Folder structure
index.php
help\index.php
help\help1.php
help\help2.php
Output
sample.com goes to sample.com/index.php & doesn't show the /index.php so UX is also satisfied!
I've looked at dozens of other questions and references on the web - and by all my calculations, my setup should work, but it doesn't.
I have nginx installation with php-fpm. If I try to access a .php file, it runs correctly and I get the correct results. I got this in my config file:
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
Now, I want to setup my web app so that /somedir/file automatically executes /somdir/file.php while still displaying /somdir/file in the browser's address bar. So I modified my config to contain the following:
location / {
try_files $uri $uri/ $uri.php?query_string
}
This kind of works, that is, the server does access the .php file. Yet, instead of executing it using the existing location ~ \.php$ block above, it simply spits the php source code as the download into the browser. If I append the .php manually to the requested URL, then the php is executed.
It feels as if once the server matches try_files to $uri.php, it then does not do another pass at locations to see that what it needs to do with the php files. I tried putting the php block above and below the location /, but it makes no difference.
How can I get the php to be executed?
You want file.php to be treated as an index file, so that domain.com/dir/file.php works on domain.com/dir/ ?
Why not just rename it to index.php?
You can do this by adding this param on your location block:
index index.html file.php index.php;
If not, you might want to look into writing a rewrite rule for nginx to map domain.com/dir/ to domain.com/dir/file.php (but you have to do it for each dir that you need it to work)
This question could also be: "How to modify an NGiNX variable with a RegEx?",
or: "Can RegEx backreference have gaps?"
Either of those would resolve the problem I'm having. Perhaps a really simple solution exists, and after digging the web for few hours, it's time to ask for help.
Here's the scenario:
There's a part of the request URI that is going to be present always (for a sort of a gimmicky domain name + URI combination :-). I enforce the presence of that always-present URI path component, which follows immediately after the domain name, like so:
http://somedomain.com/basepart/rest/of/the/path?q=123
In the above example the "/basepart" represents the always-present URI component.
So far so good. The problem arises when I want the base file path to be /var/www/somedomain.com/htdocs/ without the basepart, and php5_fpm proxy is used. I obviously set:
location /basepart {
alias /var/www/somedomain.com/htdocs;
try_files $uri $uri/ /index.php?$args;
}
But since the dynamic files are in PHP, I need to either use fastcgi_split_path_info or $request_uri to build/pass the SCRIPT_FILENAME to php5_fpm. How do I do that? How do I remove the /basepart from $fastcgi_script_name, or from $request_uri, as otherwise PHP will look for the file in /var/www/somedomain.com/htdocs/basepart?
I've considered named backreferences, or "collecting" or "fragmented" backreferences (which I don't think exist in regex) so that I could capture the segment in $fastcgi_script_name before and after the basepart when fastcgi_split_path_info assignment happens, but haven't got them to work. Dayo writes earlier at SO: »Nginx is a webserver and not a scripting application.», and suggests use of Lua for more complex scripting. But I have a feeling I may be overlooking some really simple, facepalm-worthy solution :-].
Any thoughts, anyone?
If someone else stumbles on this question, after some brainstorming i came up with stupidly obvious solution:
root /app/frontend/web/;
location /api/ {
alias /app/backend/web/;
index index.php index.html;
# Double /api/ because "that's how nginx alias and try_files works together"
try_files $uri /api//api/index.php$is_args$args;
location ~ ^/api(/.*\.php(?:\?.*)?)$ {
try_files $uri /api//api/index.php$is_args$args;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$1;
...
}
}
I.e. using regex capturing group.
With this rules requests will be routed following way:
/index.html -> /app/frontend/web/index.html
/test/test.php -> /app/frontend/web/test/test.php as plaintext
/api/<somepath> -> /app/backend/web/<somepath> (proxied to FPM if .php) if it exists, otherwise /app/backend/web/index.php
The alias directive is fine for static websites but not so useful when PHP is involved. My preferred solution is to internally rewrite the URI without the /basepart and then use root rather than alias.
The problem is that many PHP scripts use $request_uri in order to process the request, which is frozen with the /basepart intact. However, we can specify any value we choose for REQUEST_URI and construct a more appropriate value from $uri or captures. In the example below, I preserve the value of $uri after the first rewrite so that it can be used to pass our modified request URI to the PHP script.
root /var/www/somedomain.com/htdocs;
location ^~ /basepart {
rewrite ^/basepart/(.*)$ /$1 last;
rewrite ^ / last;
}
location / {
internal;
try_files $uri #index;
}
location #index {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_param REQUEST_URI $uri;
...
}
location ~ \.php$ {
internal;
try_files $uri #index;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param REQUEST_URI $uri;
...
}
The fastcgi code block is duplicated across two locations. If it becomes unwieldy, the common code can be placed into a separate include file.
Locations are made private by using the internal directive keeping the /basepart mandatory for external access.
I have an .htaccess file that I'm trying to convert so it can be run on my Nginx server.
I'm having two primary problems:
1. I'm not sure how to convert some lines
2. I don't know where to put the Nginx configuration code
Here are the lines I'm having issues converting:
Options All -Indexes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?page_request=$1 [QSA,L]
I've tried some online converters, but they don't seem to be working.
Also, once I've converted the lines, where do I put them? I assume I need to place them in the mysite.conf file in /etc/nginx/sites-available/, but within that file, do I just put them within the server {} block?
Thanks a lot for any help you can give me.
Edit: Here's the conf file
server {
listen 0.0.0.0:80;
server_name www.subdomain.domain.tld subdomain.domain.tld;
access_log /var/log/subdomain.domain.tld.log;
location / {
root /srv/www/subdomain.domain.tld/public_html;
index index.html index.php;
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /srv/www/subdomain.domain.tld/public_html$fastcgi_script_name;
}
try_files $uri $uri/ /index.php?page_request=$uri;
}
UPDATE
Doing some nginx research, came across this, give this a shot and see if it works as you expect:
location / {
# other code below this line
try_files $uri $uri/ /index.php?page_request=$uri;
}
Basically the try_files is the if statement, it tries the regular file first, if it cannot find it, it tries it as a directory, if it cannot find that it sends it to the last argument.
OLD
Have you tried using a service like: http://www.anilcetin.com/convert-apache-htaccess-to-nginx/
It outputs:
#ignored: condition 0
#ignored: condition 1
if ($rule_0 = "2"){
rewrite /RewriteRule ^/(.*)$;
}
For the data you provided.
Where you put them is inside the:
server {
}
Since this is not for a specific location you would just put it after the default stuff. There is order of operations to be had, so yea. It can be inside of a location, if you have more than one location type bit. For nginx, I would probably put this under the .php location definition.
If a user requests any .php file on my webserver I want his request (e.g. he requested mysite.com/testfile.php) to be handled by index.php
In index.php I use $_SERVER['REQUEST_URI'] to see which page the user wants to see (e.g. /testfile.php), so the index.php can generate the appropriate html-code. Notice that testfile.php doesn't need to exist.
My problem is that I always get a redirect 302 to / when I try to request testfile.php (as a result $_SERVER['REQUEST_URI'] is /). But what I want is a 200 OK for testfile.php and that index.php generates the right html-code for this.
This is a snippet from my buggy nginx.conf:
server {
[...]
root /home/test;
# When I go to mysite.com redirect my to mysite.com/
location = / {
index index.php;
}
# For any php file request: let index.php handle the request
location ~ \.(php)$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME /home/test/index.php;
}
}
Anyone can help me out?
Thanks.
If the files never exist you can do this:
try_files $uri $uri/ /index.php
you can also rewrite the request like this:
location / {
rewrite ^.*$ /index.php last;
}
in both cases you should be able to read the original request with PATH_INFO or REQUEST_URI.
Have a look at these links for some more suggestions: http://drupal.org/node/110224, http://michaelshadle.com/2010/08/20/front-controller-patterns-and-nginx/, Zend Framework on nginx