NSWI142: Web Applications

5. PHP Application I.

Jáchym Bártík, KSI
jachym.bartik@matfyz.cuni.cz

Preliminaries

Please read this section at least one day prior to the seminar. This section outlines what you are expected to know, be able to do, or prepare in advance. Following these instructions will help you get the most out of the seminar and ensure smooth participation.

Preliminaries

Please make sure you bring a pen with you to the practical. In addition, before the start of the practical, you should be able to:

  • Create an HTML form and process it using PHP script.
  • Read an HTTP query and POST data from PHP script.
  • Use interleaving and echo (or print) to produce HTML output.
  • include or require a PHP file.

You can use OneCompiler PHP to test yourself before the lecture.

Preliminaries software

This slide applies to you only if you plan to use your own computer for the practical.

Before the start of the practical, make sure that:

Agenda

  • Exercise: Project review
  • Exercise: Fixing the project
  • Demonstration: Front controller
  • Demonstration: Unit test
  • Exercise: Unit test

Exercise: Project review

You already know how to create a simple web application to register users for an event. The application consists from a landing page, registration form, confirmation, etc.. Yet, in reality you are likely to work in an existing codebase rather than staring from nothing.

Project review

Download the event registration project, unpack it, run it, explore it. You can run the project using PHP


php -S localhost:8080
    

Imagine you are doing a review and want to submit the review to GitHub. We use default GitHub labels:

  • Bug - Something isn't working
  • Enhancement - New feature or request

As we do not have GitHub repository ready ( ... work in progress), we will utilize pen and paper today.

Focus on functionality, visuals, and the code. In addition, you should mark issues as "critical" or "low" to indicate priorities. These priorities are important for developers to know what they should focus on first.

Task Complete

Congratulation, if you have followed the instruction you just reached the end of this exercise.

Exercise: Fixing the project

Issues have been identified. Now it is your turn to fix them.

Well, that is your problem now.

Reading query arguments

We can do better with filter_input function to read values from $_GET and $_POST.


<?php
// Value is NULL - if the value is not set.
// Value is false - if the value is not integer.
// Value is of type int - if a number value is provided.
$counter = filter_input(INPUT_GET, 'counter', FILTER_VALIDATE_INT);

// We can use the fourth argument to customize the behavior
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, [
    'options' => [ 'default' => 0, 'min_range' => 0, 'max_range' => 12 ]
]);
    

The function can be used with various options.

The function can read from different inputs such as INPUT_GET, INPUT_POST, INPUT_SESSION, INPUT_SERVER, ...

Redirect on POST

It is a good idea to use redirect to prevent the form from resubmitting on refresh.


<?php
// Keep in mind you must not send any output before calling header function.
// This will instruct browser to perform GET at given URL.
// Take a note that we may need to transfer the data to the new location.
header("Location: ./form.php?name=petr");
exit();
    

Sanitization

Task Complete

Congratulation, if you have followed the instruction you just reached the end of this exercise.

Demonstration: Front controller

We need all request to arrive at the bootstrap script. From there we can perform routing and dispatching. A good practice is to put the index.php file (the bootstrap script) into a ./public directory.

Front controller - PHP build-in server

Running with PHP build-in server is easy.


php -S localhost:8888 ./public/index.php
    

You can check (e.g., by using a web browser) that all requests are handled by the single file. You can find the original URL in $_SERVER['REQUEST_URI'].


<prev><code> <?php var_dump($_GET); ?> </prev></code>
<hr>
<prev><code> <?php var_dump($_POST); ?> </prev></code>
<hr>
<prev><code> <?php var_dump($_SERVER['REQUEST_URI']); ?> </prev></code>
    

Front controller - Apache configuration

The Apache server must be configured to allow for use of .htaccess and rewrites. webik.ms.mff.cuni.cz is configured in this way. We need two files to make it work.

The first .htaccess file is located in root of your project. It redirects all request to the public directory.


RewriteEngine on
RewriteRule ^$ public/ [L]
RewriteRule (.*) public/$1 [L]
    

The second .htaccess file is in the public directory. It redirects all requests (not matching other public files or directories) to the index.php file.


RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
    

Keep in mind that files starting with dot '.', like .htaccess, are hidden by default on some systems.

Demonstration: Unit test

Máte sklep? A mohla bych ho vidět?

Unit tests

How can you ensure that your app continues to work as you add more features or change existing functionality?
By writing tests. Unit tests are handy for verifying the behavior of a single function, method, or class.

— Flutter, An introduction to unit testing

A unit test is a type of software test that focuses on testing individual components of a software product.

— Bright, Unit Testing: Definition, Examples, and Critical Best Practices

Unit testy testují malé jednotky programu, typicky jednotlivé třídy a metody v nich.

— Lubomír Bulej, MFF UK, Best Practices in Programming, Unit testing and testable design (CS)

PHPUnit

PHPUnit is a programmer-oriented testing framework for PHP. There is a small PHP cheat sheet you can use.

We are going to utilize only some basic stuff from PHP unit. If you want to know more, or you missed something, please read the PHPUnit manual.

In the Organizing Tests section, there is an approach to put tests into a separate directory called ./tests/unit.

Exercise: Unit test

Testing the application

Pick a piece of code from the given application and made it testable. Then write a test using PHPUnit.

Questions, ideas, or any other feedback?

Please feel free to use the anonymous feedback form.