Home >Backend Development >PHP Tutorial >How to solve the 404 error when CodeIgniter encounters Nginx
Since CodeIgniter was originally designed for apache, and apache has better support for pathinfo, everything is very nice. But when you put the code you wrote on nginx, you were dumbfounded. Maybe except CodeIgniter's welcom, everything else was a 404 error. And I was surprised to find that CodeIgniter's official documentation said nothing about the configuration on Nginx. And you Baidu”CodeIgniter Nginx 404" and you can search for piles of articles. The strange thing is that the configuration method of almost every document seems to be different. If you have done it well, maybe you can’t configure it for several nights, like Same for me. (Server environment for this article: CentOS, nginx-1.4.7, PHP-5.4.24, CodeIgniter3.0.2 - the latest version)
The reason for the 404 error
The reason is that Nginx does not support the pathinfo format by default. When you enter http:xxx.xxx.comindex.phppageshome in your browser, Nginx will think that you want to access the home in the pages folder under the index.php directory, so it will report 404 not found error.
Solution
The solution is definitely to modify the redirection rules of the server. There are probably two ideas. One is to change the nginx.conf file in the nginx installation directory. If you use a virtual host, go to the nginx installation directory. Just find the corresponding *.conf under vhosts and change it. Another idea is to modify the .htaccess file in the CI directory, see: http://blog.csdn.net/freshlover/article/details/8977111
This article is the first idea. Before modifying, take a look at the original conf file:
{ listen 80; server_name 1.abc.com 2.abc.com; root /a/domains/1.abc.com/public_html; index index.html index.htm index.shtml index.php; error_page 404 /404.html; #Custom rules Start #Custom rules End location = /500.html { root /usr/share/nginx/html; } location ~ \.php$ { fastcgi_pass unix:/dev/shm/php.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; access_log /a/apps/nginx/logs/1.abc.com.access.log main; } location ~ /\.ht { deny all; } }1234567891011121314151617181920212223242512345678910111213141516171819202122232425
PS: For the sake of privacy, I changed the server_name to 1.abc.com, which corresponds to my own server_name.
The modification method is introduced below. Remember before modifying the conf Make a backup copy of your own conf and cp as conf.back.
The following is the modification method:
1. Modify php to support pathinfo
Before modifying conf, find the php.ini file of php (it may be in the etc directory of the php installation directory or in the lib folder, depending on your configuration), search :cgi.fix_pathinfo
Release the comment and set it to 1: cgi.fix_pathinfo=1
2. There is a question to be clear before modifying conf, that is, whether the root directory of CI is the root directory of the web. If so, Modify as follows:
Just add the following:
Add a paragraph before location ~ .php$:
if (!-e $request_filename) { rewrite ^.*$ /index.php last; }123123
This means that if the file you want to access in your browser does not exist, it will be automatically routed to the web root directory index.php to access.
Of course, the above paragraph can also be replaced by the following:
location / { try_files $uri $uri/ /index.php; }123123
The complete configuration is:
server{ listen 80; server_name 1.sod90.com app.sod90.com; root /a/domains/1.sod90.com/public_html; index index.html index.htm index.shtml index.php; error_page 404 /404.html; #Custom rules Start #Custom rules End location = /500.html { root /usr/share/nginx/html; } #location / { # try_files $uri $uri/ /index.php; #} if (!-e $request_filename) { rewrite ^.*$ /city52/index.php last; } location ~ \.php$ { fastcgi_pass unix:/dev/shm/php.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; access_log /a/apps/nginx/logs/app.sod90.com.access.log main; } location ~ /\.ht { deny all; } }123456789101112131415161718192021222324252627282930313233123456789101112131415161718192021222324252627282930313233
Note: The try_files above can completely replace rewrite, see the link
In addition to adding this redirection, there is no need for it in the conf Plus any weird stuff.
Then check the following three parameters in the CI config file:
$config['base_url'] = 'http://1.abc.com/';$config['index_page'] = '';$config[ 'uri_protocol'] = 'REQUEST_URI';123123
These three parameters are more critical. The first one is the domain name corresponding to the web root directory. Index_page should be ", not the default value 'index.php'.
After the above The setting is ok, and there is no need to write index.php in the url address.
Extension
Now consider this situation, if a backend supports app and web, sometimes it is inevitable to use different frameworks. It doesn’t look good if all the frameworks are placed in the root directory. If the root directory of my CI is not the root directory of the web, but the xxx folder under public_html, then I only need to route / in the try_files statement in conf. Index.php can be changed to /xxx/index.php as follows:
location / { try_files $uri $uri/ /xxx/index.php; }123123
In CI's config.php, write
$config['base_url'] = 'http://1.abc.com/';11
or:
$config['base_url'] = 'http://app.sod90.com/xxx/';11
. As long as the routing is correct, there will be no problem. But for the sake of safety, it is better to use the latter for base_url, and do not include index.php in the url. The difference between the two is also reflected in the fact that the values obtained when using CI functions such as base_url() will be different. Reference. Link.
Attached is a more reliable foreign link:
http://stackoverflow.com/questions/8182868/nginx-configuration-avoid-codeigniter-rewrite-rules
CI’s multiple directories: http://blog. sina.com.cn/s/blog_6ec2ae900101kbx9.html
Additional explanation, generally speaking, the following three sentences in the conf are key:
fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;123123
But I only used the following sentence in my conf:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;