Computing: Website and Database Programming

Web/Database environment on macOS.


2. Dynamic webpages with PHP and Perl.
  In my tutorial Web/Database environment on macOS: Apache webserver basics, I showed how to start the Apache webserver on macOS 11 BigSur (where it is included with the default OS setup) and where is located the webserver document root, i.e. the directory, where you have to place the files that you want to be accessible by a HTTP client (web browser). This primarily concerns static HTML pages (that may, of course, include interactivity implemented with Javascript code). This new tutorial deals with dynamic web pages, written in PHP and Perl. As you will see, making PHP and Perl work on macOS is quite a lot simpler than on MS Windows.
  Using PHP on macOS.
  There is no need to install PHP on macOS BigSur, because it already is; in my case it's PHP 7.3. If, for some reason, you need another version of PHP, you'll have to install it. This topic is not covered in this tutorial (if you want to update PHP, you may want to have a look at Updating to PHP versions 7.4 and 8 on macOS 11 BigSur and Catalina), as isn't the usage of more than one PHP versions.
  PHP files, as HTML files, have to be placed in the document root (or a subdirectory of it), that on macOS is the directory /Library/WebServer/Documents. Let's create the simple PHP file below, call it hello.php, and save it into the Apache document root (you can copy/paste files to any macOS directory using Finder, but you'll have to enter the administrator's password to do so).
    <html>
        <head>
            <title>Hello World</title>
        </head>
        <body>
            <?php
                echo "<h1>Hello, World!</h1>";
            ?>
        </body>
    </html>
  To run the script, open Safari and enter the following address: localhost/hello.php.
 
PHP on macOS: No script execution because PHP is not enabled by default
  Obviously, there is something wrong. In fact, the PHP page has been returned by Apache as if it was a HTML page, i.e. without that the PHP interpreter has been called. This can only mean one thing: PHP is not available. As on Windows, PHP is not enabled by default and you have to edit the Apache configuration file. You can find this file, called httpd.conf in /etc/apache2. In the first part of the file, where the modules, that have to be loaded, are specified, find the line concerning PHP and uncomment it. With the original files on macOS 11, PHP is enabled by loading the PHP 7 module with the following directive:
    LoadModule php7_module libexec/apache2/libphp7.so
  Do not forget to restart Apache after you have made the changes. Then, try again to run the script: localhost/hello.php. All as it should be, now!
 
PHP on macOS: Correct execution of the PHP script after enabling PHP
  Using Perl CGI on macOS.
  As Apache and PHP, Perl is included with the default installation of macOS 11. To find out where Perl is actually located within the filesystem (you'll need this information for the shebang line at the beginning of your Perl scripts), enter the following command in a terminal:
    whereis perl
Normally, you'll get as answer /usr/bin/perl.
  As a difference with HTML and PHP files, CGI scripts are normally located in a special directory1, outside the document root. On MS Windows and Linux, this directory is called cgi-bin, on macOS it corresponds to the directory /Library/WebServer/CGI-Executables. Let's create a file called hello.cgi, stored in this directory, with the following content:
    #!/usr/bin/perl
    use strict; use warnings;
    use CGI qw(:standard);
    use CGI::Carp qw(fatalsToBrowser);
    print header;
    print "<html>";
    print "<head><title>Perl CGI test</title></head>";
    print "<body><h1>Hello from Perl!</h1></body>";
    print "</html>";
Note that Perl scripts must begin with the so-called shebang line, that contains the path to the Perl interpreter.
  Before we can use a Perl CGI script (the same applies to Perl command line scripts), we have to make the script executable. I think (without being sure), that there is no possibility to change file attributes in Finder, so we have to do it in a terminal.
    cd /Library/WebServer/CGI-Executables
    sudo chmod +x hello.cgi
  With the first command we set the current directory to the location, where the script is stored. The second command changes the file attributes. sudo is used to give us super-user privileges; the +x parameter of the chmod command means: add the attribute "is executable" to the specified file (for all users). If we make a directory listing using the long format, using the command
    ls -l
we get something like the following (this is what I actually got on my system, "allu" being my user name):
    -rwxr-xr-x@ 1 allu wheel 261 Feb 15 21:16 hello.cgi
The important point here is that the file is actually executable ("x") not only for root (and the wheel group), but for everybody.
  You can test the CGI script in the terminal. Not only should it work correctly by running the command perl hello.cgi, but also by running the file directly, entering ./hello.cgi.
  The screenshot below shows how I browsed to the /Library/WebServer/CGI-Executables directory, listed its content and tried to run the script. Tried to run, because I got an error message telling me that I've specified a bad interpreter, the interpreter name referenced in the message being /usr/bin/perl^M. What's this about? I had written the hello.cgi script on my Windows 10, and on Windows systems lines are terminated by CR + LF. On Linux systems, the end-of-line character is LF, on macOS it's CR. This isn't normally a problem for Perl, but it is one for the shell, that does only understand commands that end with the correct end-of-line character. The shebang line is not interpreted by Perl, but by the bash (in order it can find the interpreter) and even if the shebang line ends with CR (because we had to change it, replacing the Windows by the macOS path) there is this empty line, containing a CR plus a LF and this LF (that corresponds to ^M) is interpreted as being a part of the shebang line and thus becomes a part of the Perl interpreter path.
 
Perl CGI on macOS: 'Bad interpreter' error when running a script that was developed on MS Windows
  Normally it is not possible to access a file located outside the document root of the webserver with the browser. To make this possible, two configuration settings must be added to httpd.conf: 1. the definition of an Alias, referencing this directory; 2. the access and other options for this directory. This configuration is part of the default installation of Apache on macOS (on other OS, the lines are sometimes commented out). Here the CGI related lines in httpd.conf:
    ScriptAliasMatch ^/cgi-bin/((?!(?i:webobjects)).*$) "/Library/WebServer/CGI-Executables/$1"
    <Directory "/Library/WebServer/CGI-Executables>
        AllowOverride None
        Options None
        Require all granted
    </Directory>
  These settings mean that in order to access a file located in CGI-Executables, the alias cgi-bin has to be specified in the URL. Furthermore, as the directive ScriptAlias (and not simply Alias) is used, this directory may contain scripts, that are executed without having to specify the ExecCGI option. So, to test the Perl CGI script in Safari, enter the following address: localhost/cgi-bin/hello.cgi.
 
Perl CGI on macOS: Display of the script because CGI is not enabled by default
  If we take a look at the screenshot above, it's obvious that this is not what we wanted. Instead of the script being executed, the Perl source code has been displayed! And this despite the fact that the ScriptAlias is correctly configured and points to the CGI-Executables directory, where the script is located. The source code being displayed means that Apache did not pass control to Perl, but simply returned the script file content to the browser, that renders it as simple text. Isn't that similar to what we had with PHP? It is, and to make things work, we'll have to load the CGI module. In the first part of httpd.conf, where the modules that have to be loaded are specified, find the lines concerning CGI and uncomment them. Here the (uncommented) directives that enable CGI:
    <IfModule !mpm_prefork_module>
        LoadModule cgid_module libexec/apache2/mod_cgid.so
    </IfModule>
    <IfModule mpm_prefork_module>
        LoadModule cgi_module libexec/apache2/mod_cgi.so
    </IfModule>
  After the restart of Apache, point Safari to the CGI script, again. This time, everything ok: The Perl code is executed insead of being displayed.
 
Perl CGI on macOS: Correct execution of the Perl script after enabling CGI
  [1]: It is possible to run CGI scripts from any directory, but for security reasons it's not the best practice to do so.

If you find this text helpful, please, support me and this website by signing my guestbook.