I have created some Laravel routes with they have ".php" extention, such as
Route::get('/api/send.php', function(){
echo 'Hi There';
});
But when I open the route it shows 404 error in Nginx server... That is Nginx configurations
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/laravel/public;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name xxx.xxx.xxx.xxx;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
What is the problem? I have used the same code it worked before..
Thanks
SOLVED
It solved by changing
try_files $fastcgi_script_name =404;
in /etc/nginx/snippets/fastcgi-php.conf to
try_files $fastcgi_script_name /index.php?$query_string;
This is a very common problem with nginx configured to serve PHP applications, especially Laravel. You can reproduce it on sites like laravel.com, e.g: laravel.com/example.php.
The default configuration (what you're probably using in snippets/fastcgi-php.conf) is this:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
And fastcgi_script_name is...
request URI or, if a URI ends with a slash, request URI with an index file name configured by the fastcgi_index directive appended to it. This variable can be used to set the SCRIPT_FILENAME and PATH_TRANSLATED parameters that determine the script name in PHP. For example, for the “/info/” request with the following directives
That means, when a request URI contains .php it is treated as if it is a request for a PHP file, and if that PHP file doesn't exist an error is returned by nginx -- it never reaches your application.
The solution is to force fastcgi_script_name to always equal your application's entry point, in this case that's index.php. You can either edit snippets/fastcgi-php.conf or add it into your location block like this:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}
Your application will now receive every request, including those that have .php in the path.
Related
I'm having an issue where when I go to the /public directory it shows the Laravel app as normal, but navigating away to any other page results in it saying
No input file specified.
I am using an Nginx server with PHP 5.5.9 FPM.
I've scoured google for the last 4 hours or so, looking at every tutorial and stackoverflow page for rewriting issues in Laravel however they all yield the same result.
I've even set all the files and folders to 777 so I could see if it was some sort of permissions issue. I've checked the Laravel config and it's all set, I've no idea what is wrong.
Can anyone point me in the right direction?
The last config I tried is below:
server {
listen 80 default_server;
root /usr/share/sites/base;
index index.php
server_name localhost;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
}
}
I have also tried many others such as:
server {
listen 80;
server_name domain.com;
root /usr/share/sites/base;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
if (!-d $request_filename) {
rewrite ^/(.+)/$ /$1 permanent;
}
location ~* \.php$ {
# Server PHP config.
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
The error "No input files specified" will nearly always be related to the fact that the wrong path was sent to php.
Looking at your 'last config tried' I can see that fastcgi_param SCRIPT_FILENAMEis not defined in your php location. You should first begin by defining it in the location :
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name
}
Furthermore you say that you can reach the app so this means that index.php is working but not when you change page. So the problem should also come from /index.php?$args. Indeed, using this line if I try to reach yourserver.com/test and if 'test' is not a file in your root path nginx will then try request /index.php? (I had this probem). You should try only with /index.php.
EDIT : The solution was that root directive should point to the Laravel public folder, in that case /usr/share/sites/base/public.
I am attempting to configure an Nginx server block in such a manner that it achieves two objectives:
To have a subdomain example.domain.com that serves an index page and pages from various paths such as /app1 and /app2; with all of these pages/paths sharing a common root of /srv/www/example.
To have the subdomain in the previous objective serve pages from a path such as /app3, but in this case having a root of /srv/www/example/app3/web.
I was able to achieve the first and second objectives, but never at the same time. Some resources I have made use of include:
Programming Junk: Nginx multiple sites in subdirectories
Martin Fjordvald: How to solve “No input file specified" with PHP and Nginx
CakePHP in a subdirectory using nginx (Rewrite rules?)
Here is my current configuration that is currently only serving the index, /app1, and /app2 correctly as a result of moving the root directive up out of the location / { directive.
server {
listen 80;
root /srv/www/example;
index index.php index.html index.htm;
server_name example.domain.com;
location /app3/ {
root /srv/www/example/app3/web;
try_files #app3 #app3;
}
location ~ /app3/.+\.(jpg|jpeg|gif|css|png|svg|js|ico|)$ {
root /srv/www/example;
}
location #app3 {
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME /srv/www/example/app3/web/index.php;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /srv/www/example/app3/web;
}
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
What do I need to change to achieve both objectives in a single server block? If there is some way to get this working with multiple server blocks that both access the same subdomain and listen on the same port that would also be acceptable.
I can't wrap my head around Nginxs' try_files. Recently I installed Nginx in favour of Apache on my development machine. How I used to work was like this: I'd bootstrap a project in a subfolder of my http directory. If this involved laravel, wordpress, codeigniter or any other framework that's using a front controller to make URLs more readable, I'd add a .htaccess in that directory to rewrite all non-existing paths to index.php.
Supposedly, this is very simple on Nginx: try_files $uri $uri/ /index.php?$query_string and it should work. However, all this does is redirect everything to the index.php in the $document_root. Example:
File structure:
http/clients/cms/public/index.php front controller
http/clients/cms/public/some/application/url request uri with the parameters some, application and url.
http/clients/cms/public/images/image.png a static file.
http/clients/blog/index.php another front controller
http/clients/blog/wp-content/image.png another static file
http/clients/blog/some-article-title a 'pretty url' that should be directed to 4
Now, hen a request is made to 2, try_files detects that /some, /some/application and /some/application/url don't exist. It will now redirect to /index.php. I would expect that it would redirect to index.php in the public/ directory, but it doesn't. Instead, it redirects to the index.php in the $document_root (which happens to contain a phpinfo(); call, so it's easy to see that it goes wrong..).
A solution would be to create multiple location blocks in my Nginx config, but I'm not liking that. It would add a significant amount of extra work to my bootstrapping process.
Is there a way to use try_files in the directories so that it works exactly like the apache alternative?
My config file:
server {
listen 80;
server_name localhost,imac.local;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
rewrite_log on;
root /Volumes/Storage/Fabian/Dropbox/Sites;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
#echo $request_filename;
#break;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
#fastcgi_split_path_info ^(.+\.php)(.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
thanks!
Is it any magic rewrite (like it does on Apache) for nginx to be able to rewrite URLs like '/submit.php' to be able to process them from index.php? We have lots of 404 not found errors because of the site structure and all previous URLs were like '/addrate.php', '/my_settings.php', '/profile.php' --> there are over 50 files like this and it would be very unprofessional and code-unwise to create a separate .php file for each of these functions, instead of parsing them all through index.php and using the needed classes like we do with the other rewrites.
Can you please find a solution/give us a suggestion today about this?
I think some info about this is here, but I want the exact reversed result:
http://www.nullis.net/weblog/2011/05/nginx-rewrite-remove-file-extension/
This configuration allow you to handle all URL (non-existing files in file system) with one php script placed in /var/www/example.org/htdocs/index.php
server {
listen 80; ## listen for ipv4
server_name example.org www.example.org;
root /var/www/example.org/htdocs;
access_log /var/log/nginx/example.org.access.log;
error_log /var/log/nginx/example.org.error.log;
location / {
index index.php index.html index.htm;
try_files $uri $uri/ #php;
}
# enable running php files under php fastcgi
location ~ \.php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/example.org/htdocs$fastcgi_script_name;
#fastcgi_param QUERY_STRING $uri;
include fastcgi_params1;
}
location #php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/example.org/htdocs/index.php; # this script catches all non existing URLs
fastcgi_param QUERY_STRING $uri;
include fastcgi_params1;
}
}
I'm using CakePHP 2.2.0 and I need to create one route that get this kind of page:
http://www.example.com/users/mypage.php
Following the cakephp documentation, I have found this page: http://book.cakephp.org/2.0/en/development/routing.html#file-extensions
where I read that I must to use:
Router::parseExtensions('php');
I have added this line in my routes.php file (above the routes), and than I added this route:
Router::connect('/users/mypage.php', array('controller' => 'users', 'action' => 'mypage'));
So, inside UsersController I added this action.
Unfortunately, Only the requests sent to www.example.com/users/mypage work good(the mypage action is called), If I try www.example.com/users/mypage.php I get a 404 not found error.
I really do not understand the reason, As the documentation says:
This will tell the router to remove any matching file extensions, and
then parse what remains.
So, that's exactly what I need, I have to interpret (only for this action) that the mypage action is called when the user digits /users/mypage.php (with extension).
I did not added anything else. AppController is as default, and my UsersController only has the mypage() method.
I do not know if NGINX is the problem, I write the configuration of the domain below:
server {
listen 80;
server_name www.example.com;
root /home/users/example.com/www/app/webroot/;
access_log /home/users/example.com/log/access.log;
error_log /home/users/example.com/log/error.log;
location / {
index index.php index.html;
try_files $uri $uri/ /index.php?$uri&$args;
}
location ~* \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
I think the question is clear, How to route the request to a specific Controller's action if the request has the extension ?
I need:
www.example.com/users/mypage.php ==> to UsersController mypage()
First, you either use parseExtensions() or add ".php" to the url template with connect(). You cannot use both at the same time. Whatever you choose, I suggest an experiment. Try using any other extensions such as "php5" and see that it works just fine. So obviously your problem is your nginx configuration:
location ~* \.php$ {
...
}
Those lines are telling nginx to parse anything in the url that ends in .php as a hard file in your file system. This is not very easy to overcome. You can use try_files in that directive having a fallback to another script, which is tricky, or you could simply just use another extension for your url :)
I hope this gives you a good hint of what you have to do.
this is my nginx.conf for cakephp 2.2.1:
server {
listen 80;
server_name localhost;
error_log /var/log/nginx/errordebug.log debug;
location / {
index index.php;
try_files $uri $uri/ #cakephp;
expires max;
access_log off;
}
location #cakephp {
fastcgi_param SCRIPT_NAME /index.php;
include /etc/nginx/fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param QUERY_STRING url=$request_uri; #&$args;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}
location ~* \favicon.ico$ {
access_log off;
expires 1d;
add_header Cache-Control public;
}