NSWI142: Web Applications

4. PHP Introduction

Štěpán Stenchlák, KSI
stepan.stenchlak@matfyz.cuni.cz

ReCodEx

New task:

  • PHP - Šablonátor (2 points, optional)

This task will be useful for your mandatory final project.

Examples of real-world template engines:

[cheatsheet] How to run PHP

Be careful which PHP version you are running; you want at least version 8. Older versions may lack some features. Check Supported Versions.

  • Use one of many online compilers, e.g. [1], [2], [3].
  • Use PHP from a command line by running php file.php. (Only for simple scripts.)
    • You can use our Webik server via SSH.
    • You can install it on your own.
    • Use a Docker image.
  • Use a web server with PHP support.
    • Use Webik, upload PHP file into public_html directory and open it via webik.ms.mff.cuni.cz/~UKČO/file.php.
    • Install XAMPP / MAMP / LAMP / WAMP on your own computer.
    • Use built-in server by running php -S localhost:8000 from your project directory.

[cheatsheet] SSH on Webik

It is a Linux computer with PHP and Apache installed.

  • Connect using ssh -p 42222 UKČO@webik.ms.mff.cuni.cz
  • Copy files using scp -P 42222 file.php UKČO@webik.ms.mff.cuni.cz:public_html/
  • Copy directories using scp -r -P 42222 dir UKČO@webik.ms.mff.cuni.cz:public_html/

To avoid typing the domain and port each time, you can create or modify the ~/.ssh/config (Linux) or %USERPROFILE%\.ssh\config (Windows) file:

host webik
  hostname webik.ms.mff.cuni.cz
  user UKČO
  port 42222

Then you can use ssh webik and scp -r dir webik:public_html/ only.

You can generate SSH keys using ssh-keygen and copy the public key to remote server using ssh-copy-id to avoid typing your password every time and to secure your connection.

[cheatsheet] Error reporting on Webik web server

Normally, you will get an HTTP 500 error without any details when any error occurs in your PHP code.

To show errors in your code and make them visible to everyone (this is not recommended for production servers), use the following code at the beginning of your PHP file:

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

Show PHP version and other information:

<?php
phpinfo();

[cheatsheet] PHP: Hypertext Preprocessor

Input:

This text is sent <strong>a⁠s is</strong> without any modifications.
<?php
  // We are inside PHP script that is executed by PHP preprocessor
  echo("The time is " . date("H:i:s"));
?>

Again, this text is sent a⁠s is.

Output:

This text is sent a⁠s is without any modifications.
The time is 07:06:20
Again, this text is sent a⁠s is.

[cheatsheet] PHP Variables and types

<?php

$age = 42;
$message = "Your age is $age"; // double quotes interpolate; single quotes do not
$fullMessage = $message . "\nWelcome."; // concatenation uses .

echo($message);
echo $message; // echo is actually language construct, so you can write it without parentheses

var_dump($fullMessage); // Dump (print) any variable

$age = "John Doe"; // dynamically typed language: variable can change its type

$pi = 3.14; // float
$isAdult = true; // boolean
$nothing = null; // null

$userProvidedName = 'John <img src="pepe_hacker.png"> Doe';
echo "Hello user " . htmlspecialchars($userProvidedName); // escape dangerous strings before outputting them to HTML
// Hello user John &lt;img src="pepe_hacker.png"&gt Doe

[cheatsheet] Control Structures

<?php
if ($name === "John") {
  ...
} else {
  ...
}

while ($x >= 0) {
  ...
}

do {
  ...
} while (strlen($text) > 0)

for ($i = 0; $i < 3; $i++) {
  ...
}

[cheatsheet] Arrays

<?php
$food = ["apple", "tomato", "pear"]; // indexed
$user = ['name' => 'Ada', 'id' => 7]; // associative (like Python dict)
$empty = [];

// Access
$food[0]; // "apple"
$user["name"]; // "Ada"

$food[] = "banana"; // append
$last = array_pop($food); // pop from end

// Existence checks
isset($user['name']); // true if key exists and not null
array_key_exists('name', $user); // true even if null

// Looping through array
foreach ($arr as $v) { /* $v is a copy */ }
foreach ($arr as &$v) { $v *= 2; } // & mutates original
foreach ($arr as $key => $value) { echo "$key: $value\n" }

[cheatsheet] Working with JSON

<?php
$data = ['name' => 'Ada', 'skills' => ['math', 'code'], 'id' => 42];

// Encode: returns JSON string
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
echo $json;

// Decode to an associative array (similar to a Python dictionary)
$arr = json_decode($json, true); // true => associative array
$arr["name"];
<?php
file_put_contents("data.json", $stringData); // write string to file
$content = file_get_contents("data.json"); // read string from file

// You can append to the file and obtain an exclusive lock to prevent concurrency issues
file_put_contents("data.json", $stringData, FILE_APPEND | LOCK_EX);

Where to read documentation?

The official PHP documentation is available at php.net/docs.php.

Examples:

Comparisons in PHP

Prefer strict comparisons (===, !==) to avoid unexpected type conversion.

Only use loose comparisons (==, !=) when you need it.

<?php

42 == "42"; // true (type conversion)
42 === "42"; // false (different types)

$var = 0;
$var == false; // true (type conversion)
!$var; // (not operator applied to zero) true (type conversion)
$var === false; // false (different types)

strpos(string $haystack, string $needle, int $offset = 0): int|false — Find the position of the first occurrence of a substring in a string. Returns 0 if the substring is found at the beginning of the string, returns false if not found.

PHP Standards Recommendations

Set of standard recommendations for writing PHP code.

Check PSR-1: Basic Coding Standard and PSR-12: Extended Coding Style Guide.

<?php

methodNamesAreInCamelCase();

if ($condition) { // Spaces after if keyword, and before opening brace that MUST be on the same line
    // Code MUST use an indent of 4 spaces for each indent level, and MUST NOT use tabs for indenting.
}

for ($i = 0; $i < 10; $i++) { // Note spaces around operators
    // for body
}

// You MUST NOT close the PHP tag if you do not have any intended HTML after it

Rendering JSON

The objective of this exercise is to create a script that renders JSON as an HTML document.

While the topic is related to web applications, most of the functionality is not web-specific.

JSON file

Download and save JSON file with data and familiarize yourself with it.

There are two approaches to implementing this exercise.

The first approach is easier.

The second is a little more complicated and general.

Please select the approach based on your coding experience.

Both approaches are described on the following slides.

Easy version: Rendering books

Your objective is to explore the JSON structure and render it as a list of books.

For each book, render: title, year of publication, the publisher, the author, and reviews.

For each review, render author and content.

See the fragment below as an example of output.


    <ul>
      <li>
        <h2>The Quantum Enigma</h2>
        <p>by Dr. Emily Carter</p>
        <p>published by Future Horizons Press in 2023</p>
        <p>Reviews</p>
        <ul>
          <li>John Doe <br/> A fascinating dive into the mysteries of quantum mechanics. Highly recommended!</li>
          ...
        </ul>
      </li>
      ...
    </ul>
    

Do not hardcode the values; you must load the value from the JSON file.

Continue to the next slide once you are done.

Advanced version: Rendering JSON

Create a general rendering script where:

  • An array is rendered as an unordered list of item renderings.
  • An object is rendered as an unordered list, where the content contains the key value and rendering of the value, separated by a colon (":").
  • Primitive types are rendered as strings.

The algorithm should produce the following fragment:


    <ul>
      <li>
        <ul>
          <li>title: The Quantum Enigma</li>
          <li>year_of_publication: 2023</li>
          ...
          <li>reviews: <ul> ...
        </ul>
      </li>
      ...
    </ul>
    

Simple form

Objective of this exercise is to create a simple form application.

A user can fill in the form and submit it.

In the next step, the user confirms the details and submits again.

All submissions are saved using a local JSON file - do not use for production!

In addition, the user can also list all submitted data.


Warning: This is only an introductory exercise. The chosen approach is suitable for small applications at best. We will talk about better ways in the follow-up practical. For information about development and deployment of medium and larger applications, see NSWI153.

The form

Download event registration form and save it as registration.php.

Familiarize yourself with the form and the way it submits data.

Continue to the next slide once you are done.

The form processing

Create confirm-registration.php file and explore the value of the $_GET variable.

Next, generate a summary of the submitted data and a confirmation dialog.

The dialog must use POST method to finish-registration.php.

Post the data using multipart/form-data.

The objective is to allow the user to review and confirm the registration.

Continue to the next slide once you are done.

The registration

Create and implement finish-registration.php script.

The script must store the information using a JSON file.

The JSON file location should be ./database.json, relative to the finish-registration.php script file.

The overview

Create index.php file.

The site will serve as a landing page for the registration.

The page must contain a link to the registration.php file.

In addition, the page must contain a list of all registered participants.

For each participant, list the full name and workshops they registered for.

Continue to the next slide once you are done.

Wrapping up

Make sure that all generated HTML is valid and that you are using htmlspecialchars to sanitize output.

Feel free to add graphics or text to improve the overall content or visual appearance.

Upload all your files to the ~/public_html/ai-event/ directory at Webik.

Continue to the next slide once you are done.

Questions, ideas, or any other feedback?

Please feel free to use the anonymous feedback form.