Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serving PHP files as downloads, instead of executing them

I recently installed nginx and php 7.0.16 in my machine, but for some reason nginx downloads php files, rather than executing them. I've already spent couple of days and implemented all solutions available online, but all in vain.

My nginx.conf is:

worker_processes 4;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.fedora.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

There is no file in conf.d folder and sites-enabled has only default file that looks like below

server {
    listen 80;
    server_name infrastructure;
    root /home/infra/index;
    index index.php index.html index.htm;
    #return 301 https://$server_name$request_uri;

    location / {
        try_files $uri $uri/ = 404;
    }

    # pass the PHP scripts to FastCGI server listening on the php-fpm socket
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

        # With php5-cgi alone:
        #fastcgi_pass 127.0.0.1:9000;
        fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

Can someone please advise, what could be the problem?

like image 524
Ravi Singh Avatar asked Mar 08 '17 06:03

Ravi Singh


People also ask

Why does my PHP file download instead of executing?

This is normally due to an improper handler code. In the . htaccess file, you will want to ensure the handler code matches your version of php. If it does not, the php files may try to download instead of process.

Can PHP files be downloaded?

Php is server side language it always execute on server and return html. you can clone or download any php file until have a ftp access.

Can Nginx serve PHP files?

After the restart, PHP is fully enabled on Nginx. To prove this, create a PHP file in Nginx's /var/www/html folder and test to ensure the page renders properly on the server.


2 Answers

Found the solution. The problem was in nginx.conf file.

Replaced following line:

default_type        application/octet-stream;

with:

default_type        text/html;
like image 194
Ravi Singh Avatar answered Oct 22 '22 01:10

Ravi Singh


Nginx is available as a package for Ubuntu 16.04 which we can install.

apt-get -y install nginx

Start nginx afterwards:

service nginx start

Then open localhost page and see what comes up.

Install PHP 7

We can make PHP work in nginx through PHP-FPM (PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features useful for sites of any size, especially busier sites) which we install as follows:

apt-get -y install php7.0-fpm

PHP-FPM is a daemon process (with the init script php7.0-fpm) that runs a FastCGI server on the socket /run/php/php7.0-fpm.sock.

The nginx configuration is in /etc/nginx/nginx.conf which we open now:

nano /etc/nginx/nginx.conf

The configuration is easy to understand (you can learn more about it here: http://wiki.nginx.org/NginxFullExample and here: http://wiki.nginx.org/NginxFullExample2)

First (this is optional) adjust the keepalive_timeout to a reasonable value:

[...]
    keepalive_timeout   2;
[...]

The virtual hosts are defined in server {} containers. The default vhost is defined in the file /etc/nginx/sites-available/default - let's modify it as follows:

nano /etc/nginx/sites-available/default

[...]
server {
 listen 80 default_server;
 listen [::]:80 default_server;

 # SSL configuration
 #
 # listen 443 ssl default_server;
 # listen [::]:443 ssl default_server;
 #
 # Note: You should disable gzip for SSL traffic.
 # See: https://bugs.debian.org/773332
 #
 # Read up on ssl_ciphers to ensure a secure configuration.
 # See: https://bugs.debian.org/765782
 #
 # Self signed certs generated by the ssl-cert package
 # Don't use them in a production server!
 #
 # include snippets/snakeoil.conf;

 root /var/www/html;

 # Add index.php to the list if you are using PHP
 index index.html index.htm index.nginx-debian.html;

 server_name _;

 location / {
 # First attempt to serve request as file, then
 # as directory, then fall back to displaying a 404.
 try_files $uri $uri/ =404;
 }

 # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
 #
 location ~ \.php$ {
 include snippets/fastcgi-php.conf;

 # With php7.0-cgi alone:
 # fastcgi_pass 127.0.0.1:9000;
 # With php7.0-fpm:
 fastcgi_pass unix:/run/php/php7.0-fpm.sock;
 }

 # deny access to .htaccess files, if Apache's document root
 # concurs with nginx's one
 #
 location ~ /\.ht {
  deny all;
 }
}
[...]

server_name _; makes this a default catchall vhost (of course, you can as well specify a hostname here like www.example.com).

root /var/www/html; means that the document root is the directory /var/www/html.

The important part for PHP is the location ~ .php$ {} stanza. Uncomment it to enable it.

Now save the file and reload nginx:

service nginx reload

Next open /etc/php/7.0/fpm/php.ini...

nano /etc/php/7.0/fpm/php.ini

... and set cgi.fix_pathinfo=0:

[...]
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.  PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is.  For more information on PATH_INFO, see the cgi specs.  Setting
; this to 1 will cause PHP CGI to fix its paths to conform to the spec.  A setting
; of zero causes PHP to behave as before.  Default is 1.  You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
; http://php.net/cgi.fix-pathinfo
cgi.fix_pathinfo=0
[...]

Reload PHP-FPM:

service php7.0-fpm reload

Now create the following PHP file in the document root /var/www/html:

nano /var/www/html/info.php

<?php
phpinfo();
?>

Now we call that file in a browser (e.g. http://localhost/info.php):

like image 35
Pradeep Sapkota Avatar answered Oct 21 '22 23:10

Pradeep Sapkota