This article is about different tools, programs and their configuration. It is not a comprehensive guide or rewrite of technical manuals. I just want to point you in right directions when you develop a web application and you encounter some technical issues. The information stated here may be useful to you when you decide to advance behind the APV course borders and write yourself a new web application and upload it on a Linux server or run it on your own PC.
Some information related to this topic can also be found in the section for readers not studying at MENDELU. A basic training with an IDE and SSH client is part of the APV course.
FTP and SSH are network services which are usually used to communicate with a web server. FTP service is just for file transfer, SSH offers full remote access to the system via a command line. Both services require authentication with a login and a password. Below is an image of Midnight Commander executed on a remote computer via SSH (an especially useful tool for remote web server configuration):
To connect with an FTP server you need an FTP client program. SSH is a bit trickier – you can use it similarly as FTP,
just for file transfers or you can use a remote shell via Putty on Windows or ssh
command on
Linux (type ssh user@hostname
to connect). To transfer files over the FTP/SSH protocol use these nice tools:
WinSCP on Windows or FileZilla (multi-platform).
A basic FTP plugin can also be found in many two-panel file managers.
Some PHP applications need to write their own files to the disk (e.g. Latte template cache, image thumbnails, error logs).
Most real world servers run on the Linux platform and a user which executes PHP scripts is different than a user (i.e. you)
who uploaded that script to the server. Therefore you have to set permissions to files/directories for other users to
allow them writing to your files/directories. This is done by the chmod
command. In the SSH remote shell type
chmod -R 0777 path/to/file/*
to allow read/write/execution of your files to everybody else on that system. Switch -R
means that you set that
privilege to files and directories recursively and 0777
is mode of privileges for you, your usergroup and for everybody
else. Both FileZilla and WinSCP clients provide setting of the user privileges in file/directories context menu.
The following image shows file attributes dialog (you do not have to remember some strange numbers,
there are checkboxes for this):
PHP is used as the main programming language in this book. I will list here some technical details about it and some information about the related applications.
PHP is an interpreter and therefore it can be configured
very differently on various systems. A script can work
perfectly in your development environment but it can break down in production environment without obvious reason.
You can make a small script with phpinfo()
function call to list environment
variables and settings of the PHP interpreter. It also lists enabled/installed modules of PHP – for example:
PDO, MySQL/PostgreSQL, GD library
etc. If you find some PHP setting uncomfortable and you have the privilege to tweak PHP config, you can locate
php.ini
file and adjust the settings, otherwise you have to contact customer support or even change the way you
operate with your application. The usual output of phpinfo()
function begins like this:
Some of default PHP settings may be limiting and sometimes you find out that you need a module which is not enabled/installed. Most common PHP settings which need to be often adjusted (most limiting ones):
memory_limit
– maximum amount of memory consumed by one instance of a PHP scriptmax_execution_time
– maximum duration of a PHP scriptupload_max_filesize
– maximum size of an uploaded fileFor example memory_limit
setting: when you work with bitmap images (resizing an image to obtain a thumbnail), you need
to fit a whole bitmap into the memory. For a 2 Mpx image you need 2000000 pixels × 24 bit per channel ~ about 6 MiB
of memory. But for a 10 Mpx image you need five times more (also include some overhead for calculations and other script needs
– 128 MiB should be enough for your scripts). Often the memory setting is set very low by default – 32MB is a typical
value (yes, this is about 100 times less than your mobile phone).
The file upload size can be limiting when you try to import a large database dump with Adminer and also with image uploads from users. Even a trained administrator can be lazy to downscale images beforehand, other users just do not care.
Useful PHP extensions:
PHP is a useful language, it has many functions in its standard library and many more in additional
plugins. Once you have learned the basics of PHP, you might want to use PHP for other tasks not related to web applications.
PHP is especially good for text file processing. If there is PHP installed in your
system, you can use PHP interpreter (executable file php
) to run scripts in the terminal. Just type
php script-name.php
and PHP should run that script. To print output use the echo
command. Reading from the standard
input is a bit more complicated though.
If you have PHP installed but your terminal does not respond to the php
command, make sure that you have added
PHP location to system variable called Path
(on Windows). To check its content type path
into the Windows command
window. To modify the Path
system variable, open the properties of your computer and find management of system variables
or execute setx path "%path%;C:\your\path\to\php"
command (which appends C:\your\path\to\php
as another Path
route).
This tool is used often to download PHP libraries. It is again a command line tool
written in PHP itself. It is used among developers to describe dependencies of their code on various libraries. When
you send your application’s source code to a colleague (by email, file sharing service or preferably through
VCS system like Git) you do not need to send
large amounts of libraries (which are usually larger than your code itself). You just send a recipe which dependencies
should be downloaded using Composer (stored in composer.json
file). You can read more about using Composer
in the walkthrough.
For example: to download Latte library execute composer require latte/latte
in the root of your project. This action will create or modify a composer.json
file which you can send along with your
sources to your colleagues and a vendor
directory, which contains the library (you do not have to include this directory
when you want to share your code, Composer will download it according to the composer.json
file contents).
In your code just include Composer’s autoload.php
file (this file handles autoloading of
classes by their
namespace
and name) from vendor
directory (include 'vendor/autoload.php';
) and you can create a new instance of Latte right
ahead ($tpl = new Latte\Engine();
) without including any other files.
You can either install Composer globally in your system and then call composer
command in your command line
interpreter directly or you can download file composer.phar
which you can execute using php
interpreter by
calling php composer.phar
(in the same folder). Other command line options and switches are identical. You have to
install PHP itself to be available globally in your system (i.e. to be able to execute php
in
command line) before you can use Composer.
Sometimes it is useful to send an email with notification to a user about an event that took place. PHP uses simple
mail()
function to send plain-text emails. To send HTML emails
or emails with attachments, use some PHP library such as SwiftMailer. You can download it
with Composer (composer require swiftmailer/swiftmailer
). This library can be configured to send mail
directly to given SMTP server (be careful with this).
The trickier part is configuring your environment - you usually do not want to send real email messages to real people from your dev-server. On Windows OS use Smtp4dev tool to open local SMTP server with simple user interface to view generated messages.
Check PHP settings in php.ini file to configure SMTP server and port on Windows or system mail command on Linux. You can also try commercial services like Mailtrap.
Adminer is a general database tool used in this book. Adminer handles different types of database engines. It is also a PHP application itself – you download a single PHP script (do not download Adminer editor) and you can place it into your public webserver directory and execute this script in your browser. Alternatives are phpMyAdmin for MySQL/MariaDB databases and phpPgAdmin for PostgreSQL. Adminer is more versatile but it has less functions than specific tools.
There are also database-specific applications e.g. MySQL Workbench or PgAdmin for database management which are not web-based.
I would have to write many books to describe PHP frameworks one by one. It is even impossible as I do not know all of them. To develop a real larger scale PHP application you do not need a framework, but after you do that again and again, you would consider some tasks repetitive. PHP frameworks usually take care of tasks which are related to application infrastructure (routing, templates, logging, user authentication) and they offer a set of well known and tested libraries to perform usual tasks (sending emails, communication with database) they also take care of tedious tasks related to security (CSRF, XSS or SQL injection). Most of them use MVC architecture and some of them offer additional features such as ORM, command line tools to speed up development or testing library interface. They are usually downloadable with Composer.
You can check out the source code and popularity of PHP frameworks on GitHub where their creators share and develop them (look at stars count):
There are also “micro-frameworks” used for SPA backend:
To become a really experienced PHP developer, try to develop at least one non trivial application without a framework to gain insight – such step can also help you to understand the benefits of using a framework.
This software is a complicated beast. It powers most web servers in the world and you will definitely have to
configure it at some point of your life. It is very versatile and therefore the configuration is quite detailed.
Also the website is not one of those super well organized. You can find its general
config in a file called httpd.conf
– always make a backup before you start modifying it.
Most common configuration tasks are enabling or disabling some modules, turning on/off directory listings and
setting up virtual hosts on your own server. Most common modules which you usually want to enable are PHP
for *.php
files, HTTP authentication support and mod_rewrite. You can use tools to enable plugins (a2enmod
)
and virtual hosts (a2ensite
) on Linux systems.
For most website developers, first encounter with Apache’s configuration is .htaccess
file which serves as
local configuration for a particular directory that it is placed in (and also its subdirectories).
To use .htaccess
files, the server’s administrator has to configure AllowOverride All
in Apache’s global config
for that directory. You are usually allowed to use .htaccess
files on shared web-hostings to configure mod_rewrite
or protecting your website with HTTP authentication.
On Linux operating systems, files the names of which begin with a dot are considered hidden. If you do not see .htaccess
file in directory listing in your FTP/SSH client (and you know that you uploaded it), go to settings and enable
hidden file listing.
To enable directory listing is useful for development servers. When you have multiple projects placed in one
directory and you do not want to create custom index.html
or index.php
file which you have to modify each
time you add a new project. Apache will create a simple directory listing page for you automatically. On the
other hand, you want to obfuscate as much as possible for production servers and not to show the application
directory structure to a potential attacker.
Put one of the following lines into your .htaccess
file. The second line is obviously used to disable directory listing.
Options Indexes
Options -Indexes
Sometimes you need to store files which should not be accessed freely. Perhaps you want to read them using PHP or
generate thumbnails or apply watermark in case of files containing images. To do this, simply put following into
.htaccess
file:
deny from all
You might have noticed that professional web applications have nice looking URLs – like this book, I do not have
/path/to/file.php
style URLs. I have cool URLs like /en/articles/name-of-article
. To achieve this,
developers use mod_rewrite. It is an Apache plugin
which is responsible for conversion of a nice readable URL into to a real one. Let’s take an e-shop for example:
A URL like /product/12345/new-super-cool-laptop
can be converted into product.php?id=12345
which
will be processed by the product.php
script of the application. The text
“new-super-cool-laptop” is irrelevant for database lookup, but we want to feed it to search engine crawlers
to achieve better ranking in search results for selected key words. Mod_rewrite is configured with
regular expressions to match a URL which is typed
into a browser and a rule used to convert it to something real and useful.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/product/([0-9]+)/.+$ product.php?id=$1 [L,QSA]
The two RewriteCond
lines test whether the path entered into browser address bar (%{REQUEST_FILENAME}
)
is not (!
) an actual directory (-d
) or file (-f
). All conditions must evaluate to true. In the RewriteRule
section,
a regular expression extracts the ID number by [0-9]+
pattern and passes it as an id
parameter of the product.php
script.
Here is something more general (the interpretation of a q
parameter is carried out by application’s logic):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
This example takes any text (.*
pattern) that is contained in the URL and passes it as the q
parameter.
The flag L means that this rule is last applied and QSA means query string append (take everything that is
behind ?
in the original URL and forward it). The URL in the browser stays the same unless there is R flag after
RewriteRule
.
Another use-case of mod_rewrite is to add www
to the URL beginning when a user enters just site.com
into
the web browser – here I used the R
flag with status code 301 which tells the browser that the content is located
elsewhere and it should navigate to the new URL given in RewriteRule
(the browser’s address bar changes):
RewriteEngine on
RewriteCond %{HTTP_HOST} ^site\.com
RewriteRule ^(.*)$ http://www.site.com/$1 [R=301,L]
If you want to use nice URLs, you have to generate such URLs into the href
attribute of each <a>
tag. This means that you
actually place a non-existing URL into the href
and rely on mod_rewrite to handle it. Your application therefore needs
a complex set of rules to generate and interpret symbolic URLs. Modern frameworks have such functionality built-in and
it is called routing.
Nice URLs can cause problems because your web browser generates relative paths according to address bar content.
If you have some non-existing path in the address bar (/product/12345/new-super-cool-laptop
) and your browser tries
to load an image given by relative path (<img src="images/shop-logo.png" alt="Logo">
) from that page (the resulting URL of image is /product/12345/new-super-cool-laptop/images/shop-logo.png
),
it fails. To prevent this, you have to generate all URLs from root of your application. To persuade the browser to do
that, you need to put a <base href="http://my-cool-site.com/my-shop/">
tag with an absolute path to the application root
(newer browsers do not need domain name) into <head>
tag. This will cause that all relative URLs are prefixed with
href
attribute value from <base>
tag. Therefore the image will be loaded from http://my-cool-site.com/my-shop/images/shop-logo.png
which should be OK. Another way is to store absolute path to root of your application and use it everywhere around
in your code: <img src="{$basePath}/images/shop-logo.png">
where {$basePath}
contains the same URL as in <base>
tag.
Read more about this topic in article about named routes.
If your application lives in a subdirectory, you usually need to add RewriteBase path/to/subdirectory
into
.htaccess
file (right after RewriteEngine on
line).
If your Apache server has enabled modules mod_auth_basic
and mod_authn_file
, you can use this approach
to restrict access to a selected directory and its subdirectories. This approach is useful when you want to hide
a web application during its development. Put these lines into your .htaccess
file:
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /path/to/.htpasswd
Require valid-user
Contents of the .htpasswd
file can look like this:
user:$apr1$Ywno0KCc$/R75cky8xEvL5DpWuTLEy.
The above line defines an account called user
with a password pass
. Use some online .htpasswd
generator to obtain yours. There can be more users defined
in .htpasswd
file.
In development environment, you almost never have to tweak database settings. When installing a database server, a form usually pops out which lets you select your intentions (development/production server) and it lets you create user accounts. To create more users and set permissions for them, you usually use SQL commands directly or a special environment for database administration.
A real production server should be configured by a database specialist. Important notes about technical issues with databases from the developer’s perspective are in another article of this book.
Docker is a kind of virtualisation tool. It executes images of virtual machines in containers. In does not virtualise the whole computer with operating system like VirtualBox or VMware but only the application itself.
You can use Docker to run whole virtual Linux web server with a database server on your PC.
This course’s project is ready to be executed in Docker thanks to docker-compose.yml
file in the root of the project. Just type docker-compose up
in command line after you install docker.
You can find instructions in the project’s readme.
Running Docker under Windows is a bit problematic. First of all use latest 64-bit Windows 10. Then you have to have a CPU with virtualisation support and you have to enable Hyper-V feature in your operating system.
You will encounter files with md
filename extension in many projects – GitHub or BitBucket displays formatted
readme.md
file as default content of repository homepage. These files are written in Markdown format.
Similarly to HTML, Markdown is designed to format text. You should learn few basic Markdown macros to use it:
Markdown code | Rendering |
---|---|
# Heading 1 ## Heading 2 ### and so on... *italic* **bold** ~~strikeout~~ Unordered list: - first - next level - second Ordered list: 1. first - next level 2. second Paragraphs is divided by two new-line characters. A [link](http://google.com) An ![image](/course/developer-tools.png) A code: `callSomeFunction()` Block of code (syntax is optional): ```php <?php echo "Hello world!"; ``` |
Heading 1Heading 2and so on…italic
bold
Unordered list:
Ordered list:
Paragraphs is divided by two new-line characters. A link An A code: Block of code (syntax is optional):
|