Blog de programación, errores, soluciones

Chose Language:
Author: Admin/Publisher |finished | checked

How to set NGINX with PHP on Windows

To have a local server that uses PHP on Windows, there are many options. Nginx is one of them, but we need to have some ideas on how to configure Nginx to use PHP.

Recently, I formatted my PC and in order to avoid installing XAMPP again, I decided to install NGINX and follow the configuration recommended by others, although it didn’t work too well for me, so let’s see how I did my installation and configuration.

[Info] The installation that we will see in this post will be for doing projects in the local environment, for production you should take a different approach[/info]

Nginx Installation

nginx-eng

To install Nginx on Windows, we don’t need much. We simply need to go to http://nginx.org/en/download.html and download the latest stable version.

Once the file has been downloaded, we can unzip it and copy the folder inside to wherever we want, for example to C:\Nginx and change its name to Nginx. We can also place it in our user’s folder, in my case C:\Users\luisg\Nginx.

PHP installation

To install PHP in this case, I used Chocolatey with its GUI (graphic user interface). You can see how to install Chocolatey in https://blastcoding.com/en/chocolatey-a-package-manage-for-windows/

Just select what you want to install and that’s it. As you can see, I also installed Composer. These days, having PHP without Composer is like competing with a cart against a car.

Config of Nginx to use PHP

Nginx comes with a default configuration for PHP, but it will not work in all cases, since it is designed for use on Linux. Let’s see this configuration:

NGINX – nginx.conf

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #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  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

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


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

From this file, we are interested in the part that matters most to us, which is the location ~ \.php$ part, which we must uncomment, leaving it as follows.

location ~ \.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi_params;
}

In this code snippet from our nginx.conf file, we can see that it has: root, fastcgi_pass, fastcgi_index y fastcgi_param

root – This is where our server will look. In my case, I left it in html folder but with its full path throughout the file.

For some reason, html didn’t work well on Windows, and therefore my full path would be C:/Users/luisg/Nginx/html. I’m sure it might work for you with html or /html.

For example, if I want to have multiple sites that will be folders placed in the html folder, therefore, when I upload the server if I search localhost/automotora it will be the page hosted in C:/Users/luisg/Nginx/html/automotora

fastcgi_pass – In this configuration we see that we pass it a socket 127.0.0.1:9000 which is constituted by the ip and port where php-cgi will listen. We will not touch this configuration unless necessary

fastcgi_index – we will not touch it clearly, we want our index to be index.php although we could also set it to be home.php

fastcgi_param – with this configuration we will define parameters that we will pass to fastcgi, in this case SCRIPT_FILENAME is enough, in this case it is telling you that the PHP files are in the scripts folder we will change this to $document_root$fastcgi_script_name in this way we will tell you that we will check from root.

Keep in mind that this is part of a virtualhost if you wanted to make multiple virtualhosts we should configure this differently
nginx.conf

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #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  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   C:/Users/luisg/Nginx/html;
            index  index.html index.htm index.php;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   C:/Users/luisg/Nginx/html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {

            root           C:/Users/luisg/Nginx/html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            #fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi_params;
        }

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


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

Creating a BATCH file to start PHPCGI and NGINX

To start PHP-CGI with this command in the console, it would be enough to execute C:\tools\phpX\php-cgi.exe -b 127.0.0.1:9000, where X in this example would represent the version.

But keep in mind that we should also run Nginx and terminate the processes when indicated. For this, we could use taskkill /f /im nginx.exe to terminate Nginx and taskkill /f /im php-cgi.exe to terminate PHP CGI.

The following batch script was made with the help of ChatGPT, and I made some corrections to make it work.

I don’t know as much about batch scripting as one might think upon seeing this file, but it’s still understandable enough. We have 2 labels: :terminate_services and :main. All the “REM” lines are comments, “start” is used to initiate a command, etc.

Using “goto” will move to the designated label, although it may seem like a good idea, avoid doing this in programming languages, or you’ll end up with spaghetti code.

archivo.bat
@echo off

:main
REM Start Nginx
start "Nginx" nginx.exe

REM Start PHP-CGI
start "PHP-CGI" "C:\tools\php83\php-cgi.exe" -b 127.0.0.1:9000

REM Wait for user input to stop services
set /p input=Enter 'exit' to stop services: 
if /I "%input%"=="exit" goto :terminate_services

goto :main

:terminate_services
REM Kill PHP-CGI task
taskkill /f /im php-cgi.exe
echo PHP-CGI has been stopped.

REM Kill Nginx task
taskkill /f /im nginx.exe
echo Nginx has been stopped.

exit /b
Category: en-php
Something wrong? If you found an error or mistake in the content you can contact me on Twitter | @luisg2249_luis.
Last 4 post in same category