Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
372 lines (263 sloc) 8.42 KB

Practical Work #1

The goal of this practical is to play with the PHP language. You should focus on understanding how things work rather than trying to do things by yourself, especially because most of the work is already done for you. Be sure to understand everything before starting the exercises!

Interactive Command Line

1. Hello World

PHP embeds a nice interactive shell that is often underused, because developers don't really know about it. However, in most cases, it is really handy as it allows you to quickly write and execute PHP. Unfortunately, it is not a real Read-Eval-Print-Loop (REPL) per se. Boris is a real and powerful REPL for PHP. Facebook has its own interactive shell too: phpsh.

In the following, you will use the default PHP interactive shell though:

$ php -a
Interactive mode enabled

php >

Type:

php > echo "hello world\n";

Now, hit enter to execute your first line of PHP. You should get the following result:

hello world

Now, execute the following line in the shell :

php > echo sprintf("Hello %s\n", "Votre prenom");

Hit enter:

Hello Votre prenom

To quit the shell, type quit or exit at the php prompt.

The PHP command line is also able to execute PHP code directly from the command line thanks to the -r option:

$ php -r 'print "hello world\n";'
hello world

This is particularly useful when you have to deal with OS restrictions. For instance, Composer, the PHP package manager, uses php -r "file_get_contents('...');" to download files on Windows machines because curl or wget don't exist by default.

2. Variables

Back to the PHP interactive shell, declare your very first variable:

php > $a = 1;
php > var_dump($a);

The result should be:

int(1)

Now, declare two variables:

php > $a = 1;
php > $b = 3;
php > printf("%d + %d = %d\n", $a, $b, $a + $b);

The result should be:

1 + 3 = 4

Working with strings is easy:

php > $b = "foo";
php > var_dump($b);

The result should be:

string(3) "foo"

print_r() is another function to print variables:

php > $b = "foo";
php > print_r($b);

The result should be:

foo

var_export() is a function that formats a variable. You can pass an optional argument, be sure to understand why:

php > $b = "foo";
php > echo var_export($b, true);
php > var_export($b);

The result should be:

'foo'
'foo'

3. Include

Create the ~/php/tp1/shell.php file, and insert:

<?php
$foo = 1;

Then, from the interactive shell:

php > var_dump($foo);   // foo is not defined

You should get the following result:

PHP Notice:  Undefined variable: foo in php shell code on line 1
PHP Stack trace:
PHP   1. {main}() php shell code:0

Notice: Undefined variable: foo in php shell code on line 1

Call Stack:
    3.4535     221408   1. {main}() php shell code:0

NULL

Now, include your file (you might have to write the absolute path to your shell.php):

php > include "~/php/tp1/shell.php";
php > var_dump($foo);   // all code in file is executed

The result should be:

int(1)

Cli Programs

It is possible to execute PHP code directly from the command line by giving php command a file as first argument:

$ php file.php

You can also use the #!/usr/bin/env php shebang and make the file a script à la shell script:

$ echo '#!/usr/bin/env php' > /path/to/your/php/file.php
$ chmod a+x !$

Executing such a script would be doable by running:

$ /path/to/your/php/file.php

Remember that running php file.php will always work though.

Exercises!

Hello, World!

Write "Hello, World!" to the console using a PHP script that can be executed by running the following commands:

$ php hello.php
// should output: "Hello, World!"

$ ./hello.php
// should output: "Hello, World!"

User Interactions

Write a script that takes your name as first argument, and print:

Hello, <your name>!

Client and Server

MVC Architecture

Let's create a few directories and files:

$ mkdir -p ~/php/tp1/{public,model,view}
$ touch ~/php/tp1/public/cities.php ~/php/tp1/model/cities.php ~/php/tp1/view/cities.php
<?php
// ~/php/tp1/public/cities.php

// include model
include __DIR__ . '/../model/cities.php';

// include view
include __DIR__ . '/../view/cities.php';
<?php
// ~/php/tp1/model/cities.php

$cities = array(
    [ "name" => "San Francisco", "country" => "USA"       ],
    [ "name" => "Paris",         "country" => "France"    ],
    [ "name" => "New york",      "country" => "USA"       ],
    [ "name" => "Berlin",        "country" => "Germany"   ],
    [ "name" => "Bamako",        "country" => "Malia"     ],
    [ "name" => "Buenos Aires",  "country" => "Argentina" ],
    [ "name" => "Santiago",      "country" => "Chile"     ],
    [ "name" => "Bombay",        "country" => "India"     ],
    [ "name" => "Vancouver",     "country" => "Canada"    ],
);
<!-- ~/php/tp1/view/cities.php -->
<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>All Cities</title>
    </head>
    <body>
        <h1>All Cities</h1>
        <table>
        <?php foreach ($cities as $cityId => $city) : ?>
            <tr>
                <td><a href="/city.php?id=<?= $cityId; ?>"><?= $city['name']; ?></a></td>
                <td><?= $city['country']; ?></td>
            </tr>
        <?php endforeach; ?>
        </table>
    </body>
</html>

Run:

php -S localhost:8080 -t ~/php/tp1/public/

Then, open: http://localhost:8080/cities.php.

Add a Dynamic Controller

Let's define a page to present a city. You need:

  • a front controller (dynamic controller);
  • a view template;
  • a 404 page if the city does not exist (in your dataset).
<?php
// ~/php/tp1/public/city.php

include __DIR__ . '/../model/cities.php';

/**
 * render a 404 page
 */
function page_not_found()
{
    header("HTTP/1.0 404 Not Found");
    include __DIR__ . '/../view/404.html';
    die();
}

// retrieve id from url parameter
$cityId = $_GET["id"];
if (!isset($cityId) || !is_numeric($cityId) || !isset($cities[$cityId])) {
    // No id given or invalid id
    page_not_found();
}

// retrieve city from dataset
$city  = $cities[$cityId];
// define some more variables
$title = sprintf("City %s", $city["name"]);

// include view
include __DIR__ . '/../view/city.php';
<!-- ~/php/tp1/view/city.php -->
<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title><?php echo $title ?></title>
    </head>
    <body>
        <h1><?php echo $city["name"] ?></h1>
        <footer>
            <a href="/cities.php">Back to list</a>
        </footer>
    </body>
</html>
<!-- ~/php/tp1/view/404.html -->
<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>404 Not Found</title>
    </head>
    <body>
        <h1>404 Not Found</h1>
        <h2>We are unable to find the city you are looking for :-(</h2>
        <p>Please accept this gif as an apology:</p>
        <p><img src="https://raw.github.com/willdurand-edu/php-practicals/master/src/images/nyan.gif" /></p>
        <footer>
            <a href="/cities.php">Back to list</a>
        </footer>
    </body>
</html>

Run PHP's built-in server again if you stopped it, then open: http://localhost:8080/cities.php, and click on some cities.

Open: http://localhost:8080/city.php?id=-1, and see the result.

Exercises!

Filter Cities By Country

Add a link to the country list and create a page for a country, listing all its cities.

Data Store

Read cities from a CSV file:

San Francisco;USA
Paris;France
New york;USA
Berlin;Germany
Bamako;Malia
Buenos Aires;Argentina
Santiago;Chile
Bombay;India
Vancouver;Canada

You may need filesystem related functions, and the explode function.


You can jump to: Practical Work #2 - Part 1.