facebook twitter
Webucator's Free PHP Tutorial

Lesson: PHP Basics

Welcome to our free PHP tutorial. This tutorial is based on Webucator's Introduction to PHP Training course.

In this lesson, you will get a thorough introduction to how PHP works and you will write your first PHP scripts. We will also introduce you to the website you will be building throughout this course.

Lesson Goals

  • How server-side programming works.
  • How PHP works.
  • To write a simple PHP page.
  • About variable scope.
  • The difference between single and double quotes.
  • To pass values from one page to another via the URL.
  • To recognize and look up documentation on PHP functions.
  • To understand and work with simple PHP variables.
  • To write user-defined functions.
  • To include files in other files to avoid rewriting the same content.
  • To display error messages during development.

Welcome to the Server-side

As this may be your first experience programming on the server, we'll start with an introduction to how the server-side works. Client-side pages (HTML, CSS, and JavaScript) are executed by the browser, but the browser needs to get those pages somehow. Generally, they are delivered by a server. For static websites, the server will simply fetch and deliver those pages. For dynamic websites, some magic gets done on the server, which could affect the content of the pages returned.

For students who have taken Creating, Styling, and Validating Web Forms

If you have already taken our Creating, Styling, and Validating Web Forms course, the rest of the content in this reading will be familiar to you. You are welcome to review it or skip ahead to the next activity.

What is a web server?

The first step to understanding server-side programming is to understand how a web server works. The diagram below shows how a web server delivers static pages, such as HTML, JavaScript, CSS, image files, audio and video files, PDFs, all of which browsers have a built-in way of handling; and other files that can be downloaded but not handled by the browser, such as Microsoft Word documents, zip files, and executables. All these files, both the ones the browser handles and the ones it just downloads, are static, meaning they are simply fetched by the web server and returned to the client without any processing on the server.Static website

Dynamic Websites

Dynamic websites are websites that do more than just fetch and return files. They have software on the server that reviews the client request before deciding what to do. Depending on the client request, the server may just return a static file or it may perform any number of processes on the server before returning a dynamically created file to the client. Here are some examples of what a dynamic site might do when it receives a request:

  1. Perform a database search and return a list of search results.
  2. Log a user into a website by checking the database for the user's credentials.
  3. Redirect the user to a login page if the user requests a members-only page.
  4. Record a user's support request in a database, email the user a friendly "we-will-be-in-touch-soon" message and the auto-generated support ticket number, email the support team letting them know a new request has come in, and return a dynamically created HTML page with a friendly "we-will-be-in-touch-soon" message and the auto-generated support ticket number.

Web servers can have access to all sorts of software on the computer on which they sit and can even reach across networks to make requests of other servers, so the variety of tasks they can perform is infinite. Follow the numbers in the diagram below to see how a dynamic website works:Dynamic website

At the time of this writing, the most widely used web servers are:

  1. Apache
  2. nginx
  3. Microsoft-IIS

And the most widely used server-side programming languages are:

  1. PHP
  2. ASP.NET
  3. Java
  4. Ruby
  5. Python
  6. Scala
  7. JavaScript
  8. ColdFusion
  9. Perl

Server-side JavaScript

While JavaScript is more well known as a client-side technology, it is now often used in server-side programming as well, most often with Node.js.

Google Chrome DevTools: Network Tab

The Google Chrome DevTools' Network tab shows which files are delivered when the browser makes a request. Let's first take a look at what it shows when we request a file from our local file system without going through a server:

  1. Open PhpBasics/Demos/no-server/hello-world.html from your class files in Google Chrome. The URL in the browser's location bar should begin with file:///:No Server: Chrome
  2. Open Chrome DevTools
    1. Click on the three-vertical-dot icon in the upper right of Google Chrome.
    2. Select More Tools.
    3. Select Developer Tools.Chrome DevTools
  3. The tools will usually be docked on the right or bottom of your screen. Select the Network tab:Google Chrome DevTools Network tab
  4. Now reload the page and look at the Network tab:Static files from file system This shows what documents were delivered to the browser, their status, what type of documents they were, and what initiated the delivery.
  5. Here are the same static files delivered from a web server. We will look further at how this was delivered soon:Static files delivered from web server.The only difference is the Status column. The web server sends back a status code to let the client know the status of the file. The 200 status code means that everything is fine. The 304 status code means that the file hasn't been modified since the last time it was requested, so the browser can use the version it has in cache if it has one.

Status Codes

The most common status codes returned by a web server are listed below along with their meanings:

  • 200 OK.
  • 301 Moved Permanently. The file used to be at this URL, but it isn't anymore.
  • 304 Not Modified. The file hasn't changed from the last time it was sent to the client.
  • 400 Bad Request. Something about the way the request was made has baffled the web server.
  • 401 Unauthorized. You have to be logged in to access this file.
  • 403 Forbidden. You can't have this even if you are logged in.
  • 404 Not Found. There is no file here.
  • 500 Internal Server Error. Something went wrong on the server.
  • 503 Service Unavailable. The web server is down or overloaded.

As the server-side developer, you have the ability to return these status codes and to decide what pages get returned with them. For example, it is common to return a special "404 Page Not Found" page when the user navigates to a URL on your website that doesn't exist. The screenshot below shows how Google handles this:Google 404Notice the 404 status on the Network tab.

How PHP Works

When a user browses to a page that ends with a .php extension, the request is sent to a web server, which directs the request to the PHP interpreter. The PHP interpreter processes the page, communicating with file systems, databases, and email servers as necessary, and then delivers a web page to the web server to return to the browser.

The php.ini File

Before we look at PHP syntax, we should briefly mention the php.ini file. This is a plain text file that is used to configure PHP. When the PHP interpreter is started, it reads the php.ini file to determine what settings to use. We will mention this file from time to time throughout the course, but for now, it is enough that you are aware of its existence.

PHP Tags

PHP code must be contained in special tags so that the PHP interpreter can identify it. The open tag is:

<?php

And the close tag is:

?>

Hello, World!

It is an unwritten rule that every programming course must contain a "Hello, World!" script. Here it is:

Code Sample:

PhpBasics/Demos/hello-world.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title>Hello, World!</title>
</head>
<body>
<main>
<?php
  // Write out Hello World!
  echo '<p>Hello, World!</p>';
?>
</main>
</body>
</html>

Code Explanation

Notice the following about the above code:

  • Code between <?php and ?> is processed by the PHP interpreter.
  • The echo command is used to print text back to the browser.

This code isn't very exciting. In fact, PHP doesn't buy us anything here as we could have just as easily output the result using straight HTML. There is nothing dynamic about this script. After learning about variables, we'll take a look at some more interesting examples.

Open this page in your browser by navigating to http://localhost:8888/Webucator/php/PHPBasics/Demos/hello-world.php. You should see the following page:Hello, World!

Your Local Server's Address

In this course, we assume that you are using port 8888 to serve your PHP pages. We also assume that your class files are located in htdocs/Webucator/php/.

If you're using a different port or your file structure is different from this, you will need to modify the localhost URLs accordingly.

Static Files

Many of our class files will reference static image, JavaScript, and CSS files that are stored in a folder called static in the php folder: static Folder These files are used throughout the demo site, which we will introduce soon, and the class files, but don't have any bearing on the PHP you are learning.

Comments

PHP has two forms of comments:

  • Single-line comments begin with a double slash (//).
  • Multi-line comments begin with "/*" and end with "*/".

Syntax

// This is a single-line comment

/*
	This is
	a multi-line
	comment.
*/

PHP Statements and Whitespace

  1. PHP statements must be inside of PHP tags to be processed by the PHP interpreter.
  2. Each PHP statement must end with a semi-colon, which tells the PHP interpreter that the statement is complete. If a semi-colon does not appear at the end of a line, the interpreter will assume that the statement continues onto the next line.
  3. The PHP interpreter condenses all sequential whitespace in PHP scripts to a single whitespace. This convenient feature allows PHP developers to structure their code in a readable format without being concerned about the effects of line breaks and tabs.

Comments

PHP has two forms of comments:

  • Single-line comments begin with a double slash (//).
  • Multi-line comments begin with "/*" and end with "*/".

Syntax

// This is a single-line comment

/*
	This is
	a multi-line
	comment.
*/

PHP Functions

There are literally hundreds of built-in PHP functions that do everything from returning the current date and time on the server to pulling data out of a database. A function might take zero arguments (e.g, pi(), which simply returns the value of Π) or it might take multiple arguments (e.g, trim(), which takes one required and one optional argument). The syntax for calling a function is straightforward:

function_name(arguments);

The example below shows how to call a simple function: phpinfo():

Code Sample:

PhpBasics/Demos/PhpInfo.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title>PHPINFO</title>
</head>
<body>
<?php
  //Output information on the PHP environment
  phpinfo();
?>
</body>
</html>

Code Explanation

Open this page in your browser by navigating to http://localhost:8888/Webucator/php/PHPBasics/Demos/phpinfo.php. This will return a page similar to the following that shows how PHP is configured on the server:phpinfo()

php.net

PHP functions are well documented at https://www.php.net. You can quickly look up documentation on a function by going to https://www.php.net/function_name. For example, to see documentation on phpinfo(), go to https://www.php.net/phpinfo. You should see something like this: php.net phpinfo

The function signature shows what a function will return and what parameters it must or can take. Here is how it is broken out:function signature

  1. returnType: The type of object returned by the function. Some possible values are:
    1. int
    2. bool
    3. string
    4. array
    5. mixed - the function can return different types of data
  2. required parameters: Any required parameters must be listed first. The php_info() function doesn't have any required parameters.
  3. optional parameters: Any optional parameters must be listed after the required parameters. In the signature, optional parameters appear in square brackets and must have default values. The $what parameter of phpinfo() is optional and has the default value of INFO_ALL, which is a constant (to be covered soon).

Take a look at the function signature for date (from https://www.php.net/date):

string date (string $format [, int $timestamp = time() ])
  1. The function returns a string.
  2. The $format parameter is required and must be a string.
  3. The $timestamp parameter is optional and defaults to the value returned by the build-in time() function, which you will explore in the following exercise.

The Epoch

The epoch is the moment that a computer or computer language considers time to have started. PHP considers the epoch to be January 1, 1970 at midnight (1970-01-01 00:00:00). Times before the epoch are expressed internally as negative numbers.

PHP Statements and Whitespace

  • PHP statements must be inside of PHP tags to be processed by the PHP interpreter.
  • Each PHP statement must end with a semi-colon, which tells the PHP interpreter that the statement is complete. If a semi-colon does not appear at the end of a line, the interpreter will assume that the statement continues onto the next line.
  • The PHP interpreter condenses all sequential whitespace in PHP scripts to a single whitespace. This convenient feature allows PHP developers to structure their code in a readable format without being concerned about the effects of line breaks and tabs.

Using php.net

Duration: 10 to 15 minutes.

Find and read through the php.net documentation on the following functions:

  1. date()
  2. time()
  3. mktime()
  4. min()
  5. max()

Pay attention to the function signature and the parameter descriptions. You may also find it interesting to read some of the user-contributed comments. Those can sometimes be very useful.

Challenge

Create a new PHP file and experiment with the functions.

There is no real solution to this exercise. The documentation for the functions is located at:

  1. date() - https://www.php.net/date
  2. time() - https://www.php.net/time
  3. mktime() - https://www.php.net/mktime
  4. min() - https://www.php.net/min
  5. max() - https://www.php.net/max

Variables

Variables are used to hold data in memory.

Variable Types

The main variable types in PHP are listed in the table below:

Variable Type Explanation
Integer whole number
Float floating-point number
String string of characters
Boolean true or false
Array list of items
Object instance of a class

Variable Names (Identifiers)

Variable names and all other identifiers in PHP (e.g., function names) are case sensitive and must begin with a dollar sign followed by letters, digits, and underscores. As a convention, variable names in PHP are written in lowerCamelCase. Here are some example variable assignments:

$firstName = 'Thomas';
$birthWeight = 9.6;
$yearOfBirth = 1743;
$favoriteFruit = 'banana';
$isAdmin = false;

More on Identifiers

Variable, function and class names are all identifiers and all follow these rules, with the exception that function names are not case sensitive, though the best practice is to treat function names as if they were.

Type Juggling and Casting

PHP variables are not assigned a type (e.g, integer) at the time they are declared. Rather, the type of a PHP variable is determined at runtime by the value the variable holds and the way in which it is used. Most of the time, this is useful, but it can cause problems as we will see later in the course. Because of these potential problems, it can be useful to explicitly change the type of a variable by casting it to a different type. This is done by putting the new type in parentheses before the variable to be cast, like this:

$a = '1'; // $a is a string
$a = (int) $a; // $a is now an integer
$a = (bool) $a; // $a is now a boolean

See PhpBasics/Demos/gettype.php, which uses the gettype() function to show the current type of $a after each cast. Then run the file by visiting http://localhost:8888/Webucator/php/PHPBasics/Demos/gettype.php.

Hello Variables!

Here is the "Hello, World!" script again, but this time we use a variable:

Code Sample:

PhpBasics/Demos/hello-variables.php
<?php
  $greeting = 'Hello, World!';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title><?php echo $greeting; ?></title>
</head>
<body>
<main>
  <p>
<?php
  echo $greeting;
?>
  </p>
</main>
</body>
</html>

Code Explanation

This time the string "Hello, World!" is stored in the $greeting variable, which is output in the title and body of the page with an echo command.

First PHP Script

Duration: 5 to 10 minutes.

In this exercise, you will write a simple PHP script from scratch. The script will declare a variable called $today that stores the day of the week and outputs it to the page in the title and the body.

  1. Open a new document and save it as today.php in the PhpBasics/Exercises folder.
  2. Declare a variable called $today that holds the current day of the week as literal text.
  3. Output $today in the title and body of the page.
  4. Navigate to http://localhost:8888/Webucator/php/PHPBasics/Exercises/today.php in your browser to test your solution. The resulting HTML page should look like this:Today

Challenge

Instead of assigning a literal string (e.g, "Monday") to $today, use the built-in date() function so that the script won't have to be manually updated every day to stay current. For documentation, visit https://www.php.net/date.

Solution:

PhpBasics/Solutions/today.php
<?php
  $today = 'Monday';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title><?php echo $today; ?></title>
</head>
<body>
<?php
  echo $today;
?>
</body>
</html>

Challenge Solution:

PhpBasics/Solutions/today-challenge.php
<?php
  $today = date('l');
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title><?php echo $today; ?></title>
</head>
<body>
<?php
  echo $today;
?>
</body>
</html>

Variable Scope

A variable's scope determines the locations from which the variable can be accessed. PHP variables are either superglobal, global, or local.

Variable Scope Explanation
superglobal Superglobal variables, also called automatic globals, are predefined arrays, including $_POST and $_GET. They are accessible everywhere.
global Global variables are accessible throughout the script in which they are declared and any files that are included by that script. However, they are not visible within functions in the script unless they are re-declared within the function as global variables.
local Variables in the function scope are called local variables. Local variables are local to the function in which they are declared.

Superglobals

Again, superglobal variables are predefined arrays, including $_POST and $_GET, and are accessible from anywhere on the page. The list of superglobals is shown below:

  • $_GET - variables passed into a page on the query string.
  • $_POST - variables passed into a page through a form using the post method.
  • $_SERVER - server environment variables (e.g, $_SERVER['HTTP_REFERER'] returns the URL of the referring page).
  • $_COOKIE - cookie variables.
  • $_FILES - variables containing information about uploaded files.
  • $_ENV - PHP environment variables (e.g, $_ENV['HTTP_HOST'] returns the name of the host server.
  • $_REQUEST - variables passed into a page through forms, the query string and cookies.
  • $_SESSION - session variables.

The elements within superglobal variables are accessed using the following syntax:

$_GET['var-name']

We will revisit superglobals throughout the course.

Single Quotes vs. Double Quotes

In PHP, for simple strings you can use single quotes and double quotes interchangeably. However, there is one important difference of which you need to be aware. Text within single quotes will not be parsed for variables and escape sequences (e.g., \n for a newline and \t for a tab). Compare the examples below:

Code Sample:

PhpBasics/Demos/single-quotes.php
---- C O D E   O M I T T E D ----
<?php
  $person = 'George';
  echo '<p>Hello, $person!!</p>';
?>
---- C O D E   O M I T T E D ----

Code Explanation

Because of the use of single quotes above, the string <p>Hello, $person!!</p> will be output literally, as shown below:Single Quotes

Code Sample:

PhpBasics/Demos/double-quotes.php
---- C O D E   O M I T T E D ----
<?php
  $person = 'George';
  echo "<p>Hello, $person!!</p>";
?>
---- C O D E   O M I T T E D ----

Code Explanation

This time, because of the double quotes, the string will be parsed for variables and special characters and will be output as shown below:Double Quotes

Escaping Quotation Marks

To include an apostrophe in a string denoted with single quotes, use a backslash to escape the apostrophe. For example:

$author = 'Madeleine L\'Engle';

Do the same thing to include a quotation mark in a string denoted with double quotes:

echo "Madeleine L'Engle said \"The great thing about getting older
is that you don't lose all the other ages you've been.\"";

Concatenation

Concatenation is a fancy word for stringing strings of text together. In PHP, concatenation is done with the . operator. It is often used to combine variables with literals as in the following example:

$firstName = 'Nat';
echo 'Hello, ' . $firstName;

Using the .= operator, it is possible to do one-step concatenation, in which you append a string on to the end of another string as shown below:

$name = 'Nat';
$name .= ' Dunn';
echo $name; // will echo 'Nat Dunn'

Passing Variables on the URL

A common way to pass values from the browser to the server is by appending them to the URL as follows:

https://www.example.com/hello.php?greet=Hello&who=World

The part of the URL that follows the question mark is called the query string. One or more name-value pairs can be passed to the server in this way. Each name-value pair is separated by an ampersand (&). The processing page can read these name-value pairs and use them to determine its response.

The HTML page below shows an example of how these name-value pairs might be passed.

Code Sample:

PhpBasics/Demos/hello-hi.html
---- C O D E   O M I T T E D ----
  <p>Do you prefer a formal or informal greeting?</p>
  <ul>
    <li><a href="hello-hi.php?greeting=Hello">Formal</a></li>
    <li><a href="hello-hi.php?greeting=Hi">Informal</a></li>
    <li><a href="hello-hi.php?greeting=Howdy">Friendly</a></li>
  </ul>
---- C O D E   O M I T T E D ----

Code Explanation

Code Sample:

PhpBasics/Demos/hello-hi.php
<?php
  // Assign the passed variable to a variable with
  // a more convenient name.
  $greeting = $_GET['greeting'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title><?= $greeting ?>, World!</title>
</head>
<body>
<main>
<?php
  echo "<p>$greeting, World!</p>";
?>
</main>
</body>
</html>

Code Explanation

Notice the following about the code above.

  1. Variable names begin with a dollar sign ($).
  2. Values passed in the query string are part of the $_GET array and can be accessed using the following syntax: $_GET['var-name'].
  3. We use double quotes so that the variable is evaluated and not output literally.
  4. A shortcut for <?php echo 'text to print'; ?> is: <?= 'text to print' ?>

Passing Variables via the Query String

Duration: 10 to 15 minutes.

In this exercise, you will write a script that says "hello" to different people based on what is passed through the query string.

  1. Open PhpBasics/Exercises/hello-who.html in your editor. You will see that it is the same as the demo we looked at earlier.
  2. Modify hello-who.html so that it has four links, each of which passes the name of one of the Beatles (Paul, John, George, and Ringo) to hello-who.php, which is in the same directory.
  3. Open PhpBasics/Exercises/hello-who.php in your editor. Modify the code so that it outputs a greeting based on the link clicked on hello-who.html.
  4. Navigate to http://localhost:8888/Webucator/php/PhpBasics/Exercises/hello-who.html in your browser to test your solution. The page should look like this: Greeting the Beatles
  5. Clicking on a link should take you to a page that looks like this:Greeting Paul

Challenge

Change the links so that each Beatle gets a custom greeting (e.g, 'Howdy, Paul!', 'Hi, John!', 'Bye, George!', 'Hey, Ringo!').

Solution:

PhpBasics/Solutions/hello-who.html
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title>Greeting the Beatles</title>
</head>
<body>
<main>
  <p>Choose a Beatle to greet.</p>
  <ul>
    <li><a href="hello-who.php?beatle=Paul">Paul</a></li>
    <li><a href="hello-who.php?beatle=John">John</a></li>
    <li><a href="hello-who.php?beatle=George">George</a></li>
    <li><a href="hello-who.php?beatle=Ringo">Ringo</a></li>
  </ul>
</main>
</body>
</html>

Code Explanation

Solution:

PhpBasics/Solutions/hello-who.php
<?php
  $beatle = $_GET['beatle'];
?>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title>Hello, <?= $beatle ?>!</title>
</head>
<body>
<main>
<?php
  echo "<p>Hello, $beatle!</p>";
?>
</main>
</body>
</html>

Code Explanation

Challenge Solution:

PhpBasics/Solutions/hello-who-challenge.html
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title>Greeting the Beatles</title>
</head>
<body>
<main>
  <p>Choose a Beatle to greet.</p>
  <ul>
    <li>
      <a href="hello-who-challenge.php?beatle=Paul&greeting=Hi">
        Paul</a>
    </li>
    <li>
      <a href="hello-who-challenge.php?beatle=John&greeting=Hello">
        John</a>
    </li>
    <li>
      <a href="hello-who-challenge.php?beatle=George&greeting=Bye">
        George</a>
    </li>
    <li>
      <a href="hello-who-challenge.php?beatle=Ringo&greeting=Hey">
        Ringo</a>
    </li>
  </ul>
</main>
</body>
</html>

Code Explanation

Challenge Solution:

PhpBasics/Solutions/hello-who-challenge.php
<?php
  $beatle = $_GET['beatle'];
  $greeting = $_GET['greeting'];
?>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title><?= $greeting . ', ' . $beatle ?>!</title>
</head>
<body>
<main>
<?php
  echo "<p>$greeting, $beatle!</p>";
?>
</main>
</body>
</html>

User-defined Functions (UDFs)

User-defined functions (UDFs) are used to make common tasks easier and to make code more modular and easier to read.

Defining and Calling Functions

A simple function is defined as follows:

function myFunction() {
  doThis();
  doThat();
  doThisOtherThing();
}

Like built-in functions, UDFs can receive parameters. To define a function with parameters, place receiving variables in the parentheses:

function addNums($param1, $param2, $param3) {
  $sum = $param1 + $param2 + $param3;
  echo 'The sum is ' . $sum;
}

UDFs can also return values:

function addNums($param1, $param2, $param3) {
  $sum = $param1 + $param2 + $param3;
  return $sum;
}

UDFs are called in the same way that built-in functions are. For example, the following code calls the addNums() function to get the sum of three numbers:

$total = addNums(1,3,5);

The following file shows the above code in action:

Code Sample:

PhpBasics/Demos/simple-udf.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title>Simple User-defined Function</title>
</head>
<body>
<main>
<?php
function addNums($param1, $param2, $param3) {
  $sum = $param1 + $param2 + $param3;
  return $sum;
}

$total = addNums(1,3,5);

echo $total;
?>
</main>
</body>
</html>

Code Explanation>

Note that calling addNums() without passing in the correct number of values will result in a fatal error. You can fix this by providing default values.

Default Values

You can make function parameters optional by assigning default values to them as shown in the example below:

Code Sample:

PhpBasics/Demos/default-values.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title>User-defined Function with Default Values</title>
</head>
<body>
<main>
<?php
  function addNums($param1=0, $param2=0, $param3=0) {
    $sum = $param1 + $param2 + $param3;
    return $sum;
  }

  $total = addNums(1,3);

  echo $total;
?>
</main>
</body>
</html>

Code Explanation

In this case, if you don't pass a value into the function for one or more of the parameters, the default value of 0 will be used. When defining a function, all required parameters must precede optional parameters.

Variable Scope

In PHP, variables declared outside of functions are not available by default inside of functions. The following code illustrates this:

Code Sample:

PhpBasics/Demos/local-vars.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title>Local Variables</title>
</head>
<body>
<main>
<?php
  $a = 10;

  function incrNumBy($incr) {
    return $a + $incr;
  }
  $c = incrNumBy(5); 
  echo '<hr>';
  echo $c; // outputs 5 to the browser
?>
</main>
</body>
</html>

Code Explanation

As $a is not available within incrNumBy(), a warning is generated, which depending on your settings (more on this soon) may or may not be output to the browser:Local Vars Notice that the function doesn't take into account the value of $a and returns only the value passed in as $incr: 5.

The global Keyword

To make global variables available within a function, they must be declared within the function as global variables using the global keyword as shown below:

Code Sample:

PhpBasics/Demos/global-vars.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title>Global Variables</title>
</head>
<body>
<main>
<?php
  $a = 10;

  function incrNumBy($incr) {
    global $a;
    return $a + $incr;
  }
  $c = incrNumBy(5); 
  echo $c; // outputs 15 to the browser
?>
</main>
</body>
</html>

Code Explanation

This time the call to incrNumBy() will output 15 as expected.

By Reference vs. By Value

By default, variables are passed to functions by value, meaning that the function's receiving variables get copies of the values received rather than pointers to them. If the receiving variables are modified, the passed variables remain unaffected. The following code illustrates this:

Code Sample:

PhpBasics/Demos/by-value.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title>By Value</title>
</head>
<body>
<main>
<?php
  $a = 10;
  $b = 5;
  function incrNumBy($num, $incr)   {
    $num += $incr;
  }
  
  incrNumBy($a,$b);
  echo $a; //outputs 10 to the browser
?>
</main>
</body>
</html>

Code Explanation

The code above outputs "10" to the browser. Although $num was incremented by 5, $a was unaffected by the function call. To pass a variable by reference, put an ampersand (&) before the parameter in the function definition as shown below:

Code Sample:

PhpBasics/Demos/by-reference.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../static/styles/normalize.css">
<link rel="stylesheet" href="../../static/styles/styles.css">
<title>By Reference</title>
</head>
<body>
<main>
<?php
  $a = 10;
  $b = 5;
  function incrNumBy(&$num, $incr)   {
    $num += $incr;
  }
  
  incrNumBy($a,$b);
  echo $a; //outputs 15 to the browser
?>
</main>
</body>
</html>

Code Explanation

This time the function outputs "15" because $num references the variable $a itself. So, any change in $num will affect $a.

Introduction to the Poet Tree Club

Throughout this course, we will be building a complete website for reading and writing poems. Some of the features the website includes are:

  1. User authentication - anyone can read poems, but you must be logged in to submit your own.
  2. Poem browsing, including filtering and pagination.
  3. New poem submission.
  4. Contact form.
  5. Image uploading.
  6. Administration area for approving poems and viewing user data.

Let's take a look at the complete site, a live version of which is available at http://www.phppoetry.com:

  1. Navigate to http://www.phppoetry.com in your browser:phppoetry.com home page
  2. Click on the More Poems link in the bottom right of the table:phppoetry.com poems
    1. Note that we are currently only showing three poems per page, but you will learn how to configure this to show any number.
    2. Click the Next and Previous links to page through the poems.
    3. Click on the table headers to sort the poems.
    4. Filter the poems by category and author.
  3. Click on the About us link in the footer to see the About us page:phppoetry.com About us
  4. Click on the Contact us link in the top navigation. You will see a contact form:phppoetry.com Contact us
    1. Press Send without filling out the form. You should see the errors shown below followed by the same form: phppoetry.com Contact us - Invalid
    2. Fill out the form with valid data, including a valid email address that you can check. Submit the form. You should receive an email letting you know that your message has been received: phppoetry.com Contact Form email
  5. Click on the Submit Poem link in the top navigation. You'll see that you must be logged in to submit a poem: phppoetry.com Submit Poem - Not logged in
  6. Click on the Login / Register link in the top navigation bar and then the Register link to register: phppoetry.com Register
  7. If you submit an invalid form, you will get errors. If you submit a valid form, you will get a success message telling you to check your email: phppoetry.com Register Success Note that you will have to confirm your registration before you can log in. This is to prevent other people from registering you for the site.
  8. You should receive an email similar to this one:phppoetry.com Registration Confirmation Email
  9. Click on the click here link. That will take you to a login page: phppoetry.com Login after confirming registration. Note that when you go to this same page in the future, it won't show the "You are now registered" poem. The login.php page knows that you have arrived by clicking on the link in the email.
  10. Log in with your username and password. If you check the Remember Me checkbox, you will not have to log in the next time you visit.
  11. On a successful login, you will see the home page again: phppoetry.com home page - logged in The site knows you are logged in. Notice that the menus have changed. There is now a My Account link in place of the Login / Register link in the top navigation and there is a new Log out link in the footer.
  12. Click on the Submit Poem link in the top navigation. Now that you are logged in, you can access this page: phppoetry.com Submit poem
  13. Go ahead and try your hand at some poetry and submit your poem. If there are no errors, it should take you to a page showing your new poem: phppoetry.com - The Poet Tree
  14. Because you wrote the poem, you get Edit and Delete buttons. If you click the Delete button, you will get a confirmation page: phppoetry.com - Delete PoemDelete the poem if you like. You will get a page letting you know it was deleted.
  15. Now click the My Account link in the top navigation: phppoetry.com - My Account
  16. Press the Choose File button below the Profile Picture heading and select a profile picture (a png or jpg) from your computer to upload. Then press the Update button.phppoetry.com - My Account with profile pic
  17. Log out.

Throughout this course, you will learn to build this "PHP Poetry" site. The site you buld will also have an "admin" section, accessible via an Admin link in the footer:phppoetry.com - Admin link in footer

Admins can edit, delete, and approve and unapprove poems. They can also update users and make other users administrators.

Including Files

Most websites, including PHP Poetry, have a header and footer that are common to many pages. Rather than rewrite the header and footer with every new page, wouldn't it be nice if you could just write them once and include them on multiple pages on the site? Enter PHP.

PHP provides two common constructs for including files in web pages: require and include. They are basically the same with one minor difference: require throws a fatal error when it fails; whereas, include only gives a warning. If the included file is necessary (i.e., required) to continue to process the page, you should use require.

It is important to keep in mind that a PHP tag cannot start in a calling file and continue in an included file. All PHP code in the included file must be nested in PHP tags.

require

require is not actually a function, but a language construct, so require statements do not need parentheses:

require path_to_file;

path_to_file can be an absolute or a relative path.

require_once

require_once can be used just like require. The difference is that if the included file has already been included by earlier code, it will not be re-included.

The following code samples demonstrate how to include files using require:

Code Sample:

PhpBasics/Demos/includes/header.php
<?php
  $headerText = 'Hello!';
  $footerText = 'Goodbye!';
  echo $headerText;
?>
<hr>

Code Sample:

PhpBasics/Demos/includes/footer.php
<hr>
<?php
  echo $footerText;
?>

Code Sample:

PhpBasics/Demos/include-demo.php
<?php
  require 'includes/header.php';
?>
<h1>Body of Page</h1>
<p>This the body.</p>
<?php
  require 'includes/footer.php';
?>

Code Explanation

The above code is relatively straightforward. include-demo.php contains two included (required) files: header.php and footer.php, both of which are in the includes folder.

Visit http://localhost:8888/Webucator/php/PHPBasics/Demos/include-demo.php to see the page in the browser. When the browser requests include-demo.php, PHP combines the two included files into the main file and the web server returns the result to the browser:Include DemoView the page source to see the resulting markup of the page, showing you exactly what PHP created:Include Demo Source

Note that this demo is intentionally kept very simple. Normally, you would create a complete HTML page starting with the open <html> tag and ending with the close </html> tag.

Using Header and Footer Includes

Duration: 15 to 20 minutes.

In this exercise, you will start with a full HTML page and break out the reusable parts into include files.

Navigate to http://localhost:8888/Webucator/php/PHPBasics/Exercises/phppoetry.com in your browser:phppoetry.com home page, logged in as adminClicking the More Poems link will bring you to the poem listing:phppoetry.com PoemsThen clicking on the Dancing Dogs in Dungarees link will take you to that poem:phppoetry.com Poem

Notice that the top and bottom of these three pages are identical.

  1. In your editor, in PHPBasics/Exercises/phppoetry.com, review the following three files:
    1. index.php
    2. poems.php
    3. poem.php
    Notice that, except for the titles, they begin and end with identical code.
  2. Create a new folder called includes in the Exercises/phppoetry.com folder.
  3. Add two files to the new includes folder:
    1. header.php
    2. footer.php
  4. Using copy and paste, take code from index.php to make the header.php and footer.php includes:
    1. For header.php, include all content from the beginning of the file to the close </header> tag.
    2. For footer.php, include all content from the open <footer> tag to the end of the file.
  5. Replace the common beginning and ending code in index.php, poems.php, and poem.php with PHP code to include the new header.php and footer.php files.
  6. Navigate to http://localhost:8888/Webucator/php/PHPBasics/Exercises/phppoetry.com and then visit the poems and poem pages to test your solution. They should look exactly as they did before with one exception: they will all now share the same title.
  7. Add PHP code to the beginning of poems.php that sets a variable named $pageTitle to 'Poems'.
  8. Add PHP code to the beginning of poem.php that sets a variable named $pageTitle to 'Dancing Dogs in Dungarees'.
  9. Modify header.php so that the text in the <title> tag starts with the $pageTitle value followed by "| The Poet Tree Club". For example, the title for poem.php, once interpreted by PHP, should end up being:
    <title>Dancing Dogs in Dungarees | The Poet Tree Club</title>

Solution:

PHPBasics/Solutions/phppoetry.com/includes/header.php
<!DOCTYPE HTML>
<html lang="en">
<head>
---- C O D E   O M I T T E D ----
<title><?= $pageTitle ?> | The Poet Tree Club</title>
</head>
<body>
<header>
  <nav id="main-nav">
    <!-- Bar icon for mobile menu -->
    <div id="mobile-menu-icon">
      <i class="fa fa-bars"></i>
    </div>
    <ul>
      <li><a href="index.php">Home</a></li>
      <li><a href="poems.php">Poems</a></li>
      <li><a href="poem-submit.php">Submit Poem</a></li>
      <li><a href="my-account.php">My Account</a></li>
      <li><a href="contact.php">Contact us</a></li>
    </ul>
  </nav>
  <h1>
    <a href="index.php">The Poet Tree Club</a>
  </h1>
  <h2>Set your poems free...</h2>
</header>

Solution:

PHPBasics/Solutions/phppoetry.com/includes/footer.php
<footer>
  <span>Copyright &copy; 2019 The Poet Tree Club.</span>
  <nav>
    <a href="logout.php">Log out</a>
    <a href="admin/index.php">Admin</a>
    <a href="about-us.php">About us</a>
  </nav>
</footer>
</body>
</html>

Solution:

PHPBasics/Solutions/phppoetry.com/poems.php
<?php
  $pageTitle = 'Poems';
  require 'includes/header.php';
?>
<main id="poems">
---- C O D E   O M I T T E D ----
</main>
<?php
  require 'includes/footer.php';
?>

Code Explanation

This page should look just as it did before. Notice the title: Title of poems.php

Solution:

PHPBasics/Solutions/phppoetry.com/poem.php
<?php
  $pageTitle = 'Dancing Dogs in Dungarees';
  require 'includes/header.php';
?>
<main id="poem">
---- C O D E   O M I T T E D ----
</main>
<?php
  require 'includes/footer.php';
?>

Code Explanation

This page should look just as it did before. Notice the title (you may need to hover over it to see the whole thing): Title of poem.php

Solution:

PHPBasics/Solutions/phppoetry.com/index.php
<?php
  require 'includes/header.php';
?>
<main>
---- C O D E   O M I T T E D ----
</main>
<?php
  require 'includes/footer.php';
?>

Code Explanation

This page should look just as it did before with one tiny exception. Notice the pipe at the beginning of the title: Title of index.phpThe code in header.php that outputs the title looks like this:

<title><?= $pageTitle ?> | The Poet Tree Club</title>

But we don't declare a $pageTitle variable in index.php, so nothing gets output. In fact, this generates a low-level error in PHP called a warning. Normally, warnings are simply ignored, but you can change this as we will soon see.

Constants

Constants are like variables except that, once assigned a value, they cannot be changed. Constants are created using the define() function and by convention (but not by rule) are in all uppercase letters. Constants can be accessed from anywhere on the page.

Syntax

define('CONST_NAME',VALUE);

If you try to reassign a value to a constant, it will fail and trigger an E_NOTICE, which is a low-level error that will likely go unnoticed. For example:

<?php
  define('BASE_YEAR', 1970);
  define('BASE_YEAR', 1971); // Fails
  echo BASE_YEAR; // 1970
?>

PHP includes a large number of predefined constants. You won't have to worry about most of these, but there are a couple of interesting ones:

  1. PHP_VERSION - The version of PHP that you are running.
  2. DEFAULT_INCLUDE_PATH - The path to the directory in which PHP will look for included files after it looks in the current directory. More on this soon.

Visit http://localhost:8888/Webucator/php/PHPBasics/Demos/predefined-constants.php to see the value of both of these constants. The code for this page is shown below:

Code Sample:

PhpBasics/Demos/predefined-constants.php
---- C O D E   O M I T T E D ----
<main>
  <table>
    <thead>
      <tr>
        <th>Constant</th>
        <th>Value</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><code>PHP_VERSION</code></td>
        <td><?= PHP_VERSION ?></td>
      </tr>
      <tr>
        <td><code>DEFAULT_INCLUDE_PATH</code></td>
        <td><?= DEFAULT_INCLUDE_PATH ?></td>
      </tr>
    </tbody>
  </table>
</main>
---- C O D E   O M I T T E D ----

Code Explanation

When you run this file in your browser, you should see something like this:Predefined Constants

Error Reporting

Many of the predefined constants in PHP are error reporting constants. They are used to set the types of errors that you would like to have reported. All of the error reporting constants are prefixed with E_. For example:

  1. E_ERROR: Report fatal run-time errors - errors that will stop execution of the script.
  2. E_WARNING: Report run-time warnings - errors that will not stop the execution of the script.
  3. E_DEPRECATED: Report notices about deprecated code- code that may not work in future versions of PHP.
  4. E_ALL: Report all errors.

The level of error reporting is set with the error_reporting directive in the php.ini file and defaults to E_ALL. You should most likely leave that default in place.

Two other error-reporting directives in the php.ini file are display_errors and log_errors. On a production server, you should set display_errors to Off and log_errors to On. They are almost certainly already set that way, but you can confirm this in the following two ways:

  1. Use phpinfo(). Navigate to http://localhost:8888/Webucator/php/PHPBasics/Demos/phpinfo.php and search for the names of the directives: php.ini Error DirectivesRemember that this file simply calls the phpinfo() function.
  2. Look in the php.ini file:
    1. Navigate to http://localhost:8888/Webucator/php/PHPBasics/Demos/find-php.ini.php. The script uses the php_ini_loaded_file() function to let you know where the php.ini file is located. You should see something like this:Location of php.ini
    2. Open that file in a text editor and search for the names of the directives:php.ini Error Settings

Boolean Values in php.ini

Within the php.ini file, you can turn boolean directives on using 1, On, True or Yes.

You can turn them off using 0, Off, False or No.

As already mentioned, on a production server, you will likely leave these settings unchanged, but you can change them on your development server if you like. Alternatively, you can change them using the ini_set() function. The most likely setting you will want to change during development is display_errors, which controls whether errors are output to the browser. During production, you definitely don't want that to happen, but during development, you probably do. To do so, at the beginning of every script or in the included header.php file, add the following code:

ini_set('display_errors', '1');

Displaying Errors

Duration: 5 to 10 minutes.

In this exercise, you will turn on the display_errors setting whenever the site is not running on the production server.

  1. In PHPBasics/Exercises/phppoetry.com/includes, create a new file called utilities.php. You will keep useful user-defined functions in this file.
  2. Add the following code to utilities.php:
    function isProduction() {
      // Provide way of knowing if the code is on production server
      return false;
    }
    
    function isDebugMode() {
      // Set to true if not on production
      // You may want to provide other ways for setting debug mode
      return !isProduction();
    }
    • The isProduction() function will provide a mechanism for the code to know if it is running on a development or production server.
    • You will use the isDebugMode() function now. Note that eventually you might have a more nuanced way of setting debug mode. For example, you might give superadmin users a way of turning on debug mode in their settings in an admin section of the website.
  3. Open PHPBasics/Exercises/phppoetry.com/includes/header.php in your editor.
  4. Add code to include utilities.php once. Note that it's possible we will want to include the utilities.php file on pages that may or may not include the header.php. On such pages, we want to make sure that we don't include the file twice.
  5. Below the code that includes utilities.php, write the following:
    if (isDebugMode()) {
      ini_set('display_errors', '1');
    }
    This code uses ini_set() to turn on the display_errors setting, but only when in debug mode.
  6. Navigate to http://localhost:8888/Webucator/php/PHPBasics/Exercises/phppoetry.com/index.php in your browser.
  7. As the error takes place in the <title> tag, the error message shows up on the browser tab. Hover over it to see the full error message: Title of index.php - warning The beginning of the error reads:
    Notice: Undefined variable: pageTitle

Solution:

PHPBasics/Solutions/phppoetry.com/includes/utilities.php
<?php
  function isProduction() {
    // Provide way of knowing if the code is on production server
    return false;
  }

  function isDebugMode() {
    // Set to true if not on production
    // You may want to provide other ways for setting debug mode
    return !isProduction();
  }
?>

Code Explanation

Solution:

PHPBasics/Solutions/phppoetry.com/includes/header-2.php
<?php
  require_once 'utilities.php';
  if (isDebugMode()) {
    ini_set('display_errors', '1');
  }
?>
<!DOCTYPE HTML>
<html lang="en">
<head>
---- C O D E   O M I T T E D ----
<title><?= $pageTitle ?> | The Poet Tree Club</title>
</head>
---- C O D E   O M I T T E D ----

Code Explanation

Setting display_errors to 1 during development allows us to catch these errors, so that we can improve our code. In the next lesson, we will learn how to fix this error, so that on our home page, we do not try to prepend anything to the site name (i.e., "The Poet Tree Club").

Including a Secure Configuration File

Any file under the web root can potentially be accessed over the web. Navigate to http://localhost:8888/Webucator/php/PHPBasics/Demos/find-document-root.php to find the path to your web root. That will output the path to the root and the paths to the current files and directory:Location of document root

If included files are under the web root, they can be accessed just as any other file can. If they have an extension such as inc then the browser may display them as plain text. With other extensions, the browser may attempt to download the file. If the included file is a PHP file and a user navigates to it, the server will try to process the file and may return errors. It is also possible that your web server becomes misconfigured and returns a PHP file as plain text showing your sensitive data in the browser. As a precaution, you should place any included files with sensitive data in a directory outside of the web root. This will prevent users from accessing the files directly.

In order to be able to include files that are outside of the web root, you will need to modify the include_path directive in the php.ini file. The include_path directive takes a list of paths to directories in which PHP should look for included files. In the following exercise, you will change your setup to be able to include a configuration file outside of your web root.

Including a Configuration File

Duration: 10 to 15 minutes.

In this exercise, you will:

  1. Create an includes directory outside of the web root and place a configuration file in that directory.
  2. Modify the include_path directive in the php.ini file.
  3. Run a test to make sure you can include the configuration file in the new includes directory.

Follow these instructions:

  1. In Windows Explorer or Finder, navigate to the folder that contains your document root (as shown in the last demo). For example, if your document root is /Applications/MAMP/htdocs, navigate to /Applications/MAMP. Add a new folder called includes next to your root folder (e.g., htdocs):Finder includes
  2. In PhpBasics/Exercises, you will find a file called config-sample.php. Copy and paste that file into your new includes folder and then rename it config.php:Finder includes/config.php
  3. Open the php.ini file in your editor. Remember that you can find out where it is by navigating to http://localhost:8888/Webucator/php/PHPBasics/Demos/find-php.ini.php.
  4. In the php.ini file, find the include_path directive and append a colon (Mac) or semi-colon (Windows) followed by the path to the new includes folder to the end. Also, be sure to uncomment the line by removing the leading semi-colon.
    1. On a Mac, the path will look something like this:
      ; UNIX: "/path1:/path2"
      include_path = ".:/Applications/MAMP/bin/php/php7.2.10/lib/php:/Applications/MAMP/includes"
    2. On Windows, the path will look something like this:
      ; Windows: "\path1;\path2"
      include_path = ".;c:\php\includes;c:\MAMP\includes"
    Note that semi-colons at the beginning of lines in the php.ini file denote comments. If there is a semi-colon before the include_path line, you should remove it.
  5. After making the change above, save the php.ini file.
  6. Stop and start the MAMP Servers. This is required as the php.ini settings are loaded when PHP first starts up.
  7. Run http://localhost:8888/Webucator/php/PHPBasics/Exercises/config-test.php in the browser to test your setup. If successful, it will output:Config File Include Success If it fails, it will output:Config File Include Fail
  8. There is no solution file for this exercise as it relates to your computer setup. It's important for future lessons that you have this working correctly, so make sure it does before moving on.