PHP CHAPTER 1 2019-01-02T12:17:53+00:00

PHP Chapter 1

Installation

We’ll guide you as you take your first steps beyond the static world of building web pages with the purely client-side technologies of HTML, CSS, and JavaScript. Together, we’ll explore the world of building websites, and discover the dizzying array of dynamic tools, concepts, and possibilities they open up. Before you build your first dynamic website, you must gather together the tools you’ll need for the job. Like baking a cake, you’ll need the ingredients before you can start following the recipe. In this chapter, we’ll show you how to download and set up the software packages required.

If you’re used to building websites with HTML, CSS, and perhaps even a smattering of JavaScript, you’re probably familiar with uploading the files that make up your site to a certain location. It might be a web hosting service you’ve paid for, web space provided by your Internet service provider (ISP), or maybe a web server set up by the IT department of the company you work for. In any case, once you copy your files to any of these destinations, a software program called a web server is able to find and serve up copies of those files whenever they’re requested by a web browser like Microsoft Edge, Internet Explorer, Google Chrome, Safari, or Firefox. Common web server software programs you may have heard of include Apache HTTP Server (Apache), NGINX and Internet Information Services (IIS). PHP is a server-side scripting language. You can think of it as a plugin for your web server that enables it to do more than just send exact copies of the files requested by web browsers. With PHP installed, your web server will be able to run little programs (called PHP scripts) that can do tasks like retrieve up-to-the-minute information from a database and use it to generate a web page on the fly, before sending it to the browser that requested it. PHP is completely free to download and use.

For your PHP scripts to retrieve information from a database, you must first have a database. That’s where MySQL comes in. MySQL is a relational database management system, or RDBMS. We’ll discuss the exact role it plays and how it works later, but briefly, it’s a software program that’s able to organize and manage many pieces of information efficiently while keeping track of how all those pieces of information are related to each other. MySQL also makes that information really easy to access with server-side scripting languages such as PHP. And, like PHP, it’s completely free for most uses. The goal of this first chapter is to set you up with a web server equipped with PHP and MySQL. We’ll provide step-by-step instructions that work on recent versions of Windows, macOS and Linux, so no matter what flavor of computer you’re using, the instructions you need should be right here.

Your Own Web Server

Chances are, your current web host’s web server already has PHP and MySQL installed—which is one of the reasons PHP and MySQL are so popular. If your web host is so equipped, the good news is that you’ll be able to publish your first website without having to shop for a web host that supports the right technologies. When developing static websites, you can simply load your HTML files directly from your hard disk into your browser to see how they look. There’s no web server software involved when you do this, which is fine, because web browsers can read and understand HTML code all by themselves. However, when it comes to dynamic websites built using PHP and MySQL, your web browser needs some help. Web browsers are unable to understand PHP scripts. Instead, PHP scripts contain instructions for a PHP-savvy web server to execute in order to generate the HTML code that browsers can understand.

Even if you have an existing web host that supports PHP, you’re still going to want to be able to run PHP scripts yourself without needing to use someone else’s server. For this, you’ll need to set up your own web server. The word “server” might make you think of a large, air-conditioned room filled with big computers in racks. But don’t worry, you don’t need any fancy new hardware. Your laptop or desktop will work just fine. To run PHP scripts on your web host, you need to write them in your editor, open your FTP or SSH client and upload them to the server. Only then can you see the result in your browser by navigating to the URI of the file you created. If you made a mistake and there’s an error, you’ll need to change the code, go back into your FTP program, upload the file again and then reload the page. This is tedious, and uses up precious time that you could be using to write code. By running a server on your own PC, you’ll be able to save a file in your editor and view the changes in your browser by simply refreshing the page—no file uploading required. This is a real time saver, and one of the biggest (although not only!) advantages of running a server on your PC—even if you have a perfectly good web host already. So how do you get a web server running on your PC? There are three methods of achieving this, each with its own advantages and disadvantages.

Server Setup 1: Manually Installing All the Software Components

Apache is a web server, and like most software it comes with an installer that lets you easily set it up on your PC. Without much effort, you can have it serve web pages. However, there are hundreds of configuration options, and unless you know what you’re doing, it can be time consuming and confusing to get it working for developing PHP websites.

For our purposes of running PHP scripts, a web server alone is not enough. For manual installation, you’ll also need to install PHP—which doesn’t have an installer—and configure it. As with Apache, there are lots of options, and the defaults are set up as if you’re running a live website. For developing code, this is bad, as there are no errors shown. If you made a mistake, you’ll get a blank page with no indication of what went wrong. Even a single character out of place—such as a missing brace or semicolon—will give you a blank page, with no indication of what caused the problem. To solve this, you’ll need to manually configure the PHP installation and tweak the settings to show error messages and enable other tools that make development a more pleasant task.

You’ll also need to configure Apache to talk with PHP, so that when someone connects to the server and requests a file with a .php extension, the file is first sent to PHP for processing. You’ll also want MySQL, which means manually installing and configuring that as well. Apache, MySQL and PHP each have dozens of configuration options, and unless you know exactly what you’re doing, they can be difficult to set up. Even if you’re an expert, it will take at least an hour to get everything working! This option is not for the faint hearted, and even for seasoned professionals it’s very easy to miss some important settings. Luckily for us, we don’t need to worry about setting up and configuring all the software individually.

Server Setup 2: Pre-packaged Installations

The problems with manual installations have been recognized by groups of developers over the years, and to overcome them they’ve built pre-packaged installations—a single installer that installs PHP, Apache, MySQL and other relevant software, all pre-configured with appropriate settings for developers like you. Some example packages are XAMPP (X, Apache, MySQL, PHP, Perl), WAMP (Windows, Apache, MySQL, PHP) and LAMP (Linux, Apache, MySQL, PHP). This is obviously a lot simpler than manually installing each piece of software, and doesn’t require learning how to configure your server. It’s quick and easy and a lot better than a manual installation, though there are still a couple of problems you may encounter with this method:

  1. Your web host is probably running Linux, but your PC probably isn’t. Although Apache, MySQL and PHP work in Windows, Linux or macOS, there are some big differences between the way the operating systems work. On Windows, file names are not case-sensitive, meaning that FILE.PHP is the same as file.php and fIlE.pHp. On your web host, this will almost certainly not be the case! This causes frequent problems when a script working perfectly on your Windows development server doesn’t work once it’s uploaded, because files are being referenced in the code with the wrong case.
  2. Apache and MySQL are servers, and they run in the background. Even when you’re not developing software, they’ll be running, using up your computer’s RAM and processing power.
  3. Pre-packaged software is always slightly out of date. Although security fixes aren’t a priority for a development computer (you shouldn’t be allowing people to access it across the web!), it’s always useful for developers to stay on the most recent versions of software to check for problems that might be encountered when the software on your web host is updated. If your web host

is using a newer version of PHP than your development server, this can cause problems with features that have been changed or removed. Finally, developers like to play with new features as they’re released. You won’t be able to do this if you’re not using the latest versions! Although pre-packaged installations are much better than installations, these problems don’t make them ideal. Luckily, there’s an even better approach!

Server Setup 3: Virtual Servers

The third method of getting a server up and running is a virtual server. A virtual server acts like a web server on a different computer. This computer can be running any operating system, and you can connect to it from your PC as if it were somewhere else in the world. Virtualization software such as VMWare and VirtualBox is common. As a web developer, you may be familiar with tools such as modern.ie, a helpful service provided by Microsoft that lets you download virtual machines running various versions of Windows, Microsoft Edge and Internet Explorer. If you want to see what your website looks like in Internet Explorer 8 on Windows XP, you can download the relevant virtual machine and run it in a Window on your Windows 10/macOS/Linux desktop without having to actually install and run Windows 7 with Internet Explorer 8 inside your existing Windows 10, Linux or MacOS installation.

 Windows 10 running inside Arch Linux

Software like VirtualBox allows you to run an operating system inside another operating system. For testing Internet Explorer 8, you can run Windows 7 in a virtual machine. However, for our purposes of running PHP scripts, this allows us to do something a lot cooler: we can run a Linux web server with PHP, Apache and MySQL installed on our Windows or macOS PC. This can be used to allow you to run the exact same versions of PHP, MySQL and Apache that are being used on your web host, on the exact same operating system, which prevents any issues that may exist due to version differences or differences in the operating systems being used.

One of the biggest advantages is that you can download pre-configured virtual machines, like the Windows XP and Internet Explorer 8 virtual machine provided by Microsoft, or a virtual machine that has PHP, Apache and MySQL installed and configured to work together. This is like the pre-configured package but runs on Linux as if it’s a real web server on your network. The downside to all this is that you have to download an entire operating system in order to run your code. That means more downloading, but in the era of 10 Mbit/s+ internet connections and terabyte hard drives, this isn’t really an issue worth worrying about! Because this is a best-of-both-worlds approach, and has advantages over the other two methods, I’ll be showing you how to get a virtual server up and running. It’s a lot easier than you might think!

Your Own Virtual Server

Before writing any PHP code and developing your website, you’ll need to install several pieces of software to run a virtual server:

Git, which allows you to quickly and easily download other people’s code.

VirtualBox, the software that runs the virtual machines.

Vagrant, a tool that allows quick and easy configuration of virtual machines.

This works with VirtualBox to create your server.

Installation on Windows

Firstly, download and install the latest versions of the following software:

  1. Git
  1. VirtualBox
  1. Vagrant

Once you’ve installed all the software, use your Start menu to open a newly installed program called “Git Bash” and proceed to the Getting Started with Vagrant section below. All the commands given should be typed into the Git Bash program, not Windows Command Prompt.

Installation on macOS

Firstly, download and install the latest versions of the following software:

  1. Git
  1. VirtualBox
  1. Vagrant

Once you’ve installed all the software, open up the Terminal program and proceed to the Getting Started with Vagrant section below.

Installation on Linux

Linux makes installing software very simple. On most distributions, this can be done via your package manager.

Debian/Ubuntu:

sudo apt-get install git dkms virtualbox virtualbox-dkms vagrant

Fedora/Red Hat:

sudo dnf install git VirtualBox vagrant vagrant-libvirt

Arch Linux:

sudo pacman -S git virtualbox vagrant

Once you’ve installed all the software, open up your favorite terminal program and proceed with the following steps below.

Getting Started with Vagrant

Now that you have all the software installed, it’s time to download a virtual server. From here on, the instructions are the same whether you’re using Windows, macOS or Linux. We’ll be using a pre-built virtual machine (or “box”) called Homestead Improved. This contains PHP, MySQL and NGINX already configured for development purposes. To download it, from your terminal prompt firstly navigate into the directory you wish to store your website’s files in, and then run these commands:

git clone https://github.com/swader/homestead_improved my_project

cd my_project; mkdir -p Project/public

bin/folderfix.sh

Using the Command Prompt to Navigate

If you don’t know how to navigate around using the command prompt, you use the cd command (short for change directory). Git Bash uses Unix style paths, so C:\Users\Tom\Desktop becomes /c/Users/Tom/Desktop. If you want to store your files inside your Documents directory, e.g. Documents/Website, you can navigate to it using cd /c/Users/[Account Name]/Documents/WebsiteIf you have any spaces in the directory names, simply surround the entire path with quotation marks, e.g. cd “/c/Users/[Account Name]/Documents/My Website”.

After you’ve run the commands, several files will be created inside your project directory. These files contain instructions for creating and configuring the virtual server. Finally, you just need to start the server using this single command:

vagrant up

Running the Command in the Right Place

You must run the vagrant up command from the directory that stores the files that were downloaded via the git clone command earlier. If you type ls, you should see Vagrantfile listed. If you don’t see it, you’ll need to navigate to the correct directory using the cd command.

The server will start and you’ll see something like this:

Running vagrant up

If the vagrant up Command Hangs

If the vagrant up command hangs on the line Connection timed out. Retrying… for more than a few minutes, it’s likely your PC isn’t configured for virtualization, which it needs to be for running virtual machines. To fix this, you’ll need to boot into your PC’s BIOS and enable a technology called VT-x (if you have an Intel processor) or AMD-V (for AMD processors). To do this, refer to your computer’s manual, or use Google to find instructions for getting into the BIOS on your PC. This setting is sometimes called virtualization technology, VT-x, SVM or hardware virtualization, depending on the make of your PC.

The first time vagrant runs, it will take a few minutes to load, as it requires downloading quite a large file. Don’t worry, it won’t take this long each time you want to start your server. In future, all the downloading and initial configuration is done. Unlike using a manual NGINX/PHP/MySQL installation directly on your PC, the server is only started when you want it to be, by running vagrant up. You can stop the server at any time, by running vagrant halt, and boot it again using vagrant up when you need it.

You can also use vagrant suspend, which is like shutting the lid on your laptop. It pauses the virtual machine so it doesn’t need to reboot next time you run vagrant up. Unless you’re low on disk space, suspend is preferable, as the virtual machine will start up considerably faster. One of the directories that was created is called Project. Open this directory and the public directory inside it. This is where you’ll store your PHP scripts, HMTL files, CSS files and images. Any files placed inside the public directory will be accessible on your virtual server. Using your favorite text editor, create a file called index.html that contains the following code:

<!DOCTYPE html>

<html>

<body>

        <h1>Hello World!</h1>

</body>

</html>

You can now view your web page on the server. The server acts like a computer on your local network and uses the IP address 192.168.10.10. If you open your browser and navigate to http://192.168.10.10/, you should see your Hello World test page. If you can see the page, it means your server is running and you’ve written your file to the right directory. The numeric IP address may look at little strange. Usually, when you access to a website, you connect to something like http://www.sitepoint.com/ or http://www.google.com. However, behind the scenes all websites use an IP address. If you type http://216.58.201.46/ into your browser, you’ll see the Google home page. It would be very hard to remember the IP address of every website you wanted to visit. So we typically buy a domain name and associate it with an IP address. When you type sitepoint.com into your web browser, the browser looks up the corresponding IP address and actually connects to that behind the scenes. You can think of it a bit like a phone book. Rather than remembering someone’s phone number, you can look through a contact list and find them by a more easily recognizable name. This process happens for every website you visit, and every website has an IP address similar to 129.168.10.10.It would be possible to buy a domain name and associate it with 192.168.10.10, but for our purpose we’ll just stick to the IP address, as we won’t need to type it often.

Linux Issues

If you’re using Linux and either the vagrant up command isn’t working or you’re unable to connect to the web server on http://192.168.10.10/, see Appendix B.

Text Editors

Text editors provided by your operating system, such as Notepad or TextEdit, aren’t really suitable for editing HTML and PHP scripts. However, there are a number of solid text editors with rich support for editing PHP scripts that you can download for free. Here are a few that work on Windows, macOS, and Linux:

Atom

Sublime Text

Brackets

Now, or in the near future (depending on your ISP), you might start seeing IP addresses in the format 2001:0db8:85a3:0000:0000:8a2e:0370:7334. This is an IPv6 address, which works in the exact same way as the notation shown in this chapter. The problem with IP addresses in the format 0.0.0.0 (IPv4) is that there are only around 4 billion possible addresses. That sounds like a lot, but every single website, phone or computer connected to the Internet needs a unique IP address … and we’ve pretty much run out of them! The new IPv6 addresses will keep us going for quite a while longer.

In this chapter, you’ve learned how to set up a web server with Homestead Improved, and how to host an HTML file on the server.We’ve only covered the basics in order to quickly get to the meat and bones : actually programming in PHP. However, having a good development workflow as a PHP developer is a skill in its own right.

Introducing PHP

Now that you have your virtual server up and running, it’s time to write your first PHP script. PHP is a server-side language. This concept may be a little difficult to grasp, especially if you’ve only ever designed websites using client-side languages like HTML, CSS, and JavaScript. A server-side language is similar to JavaScript in that it allows you to embed little programs (scripts) into the HTML code of a web page. When executed, these programs give you greater control over what appears in the browser window than HTML alone can provide. The key difference between JavaScript and PHP is the stage of loading the web page at which these embedded programs are executed.

Client-side languages like JavaScript are read and executed by the web browser after downloading the web page (embedded programs and all) from the web server. In contrast, server-side languages like PHP are run by the web serverbefore sending the web page to the browser. Whereas client-side languages give you control over how a page behaves once it’s displayed by the browser, server-side languages let you generate customized pages on the fly before they’re even sent to the browser. Once the web server has executed the PHP code embedded in a web page, the result takes the place of the PHP code in the page. All the browser sees is standard HTML code when it receives the page, hence the name “server-side language.” Let’s look at simple example of some PHP that generates a random number between 1 and 10 and then displays it on the screen:

 PHP-RandomNumber

<!DOCTYPE html>

<html lang=”en”>

<head>

      <meta charset=”utf-8″>

     <title>Random Number</title>

</head>

<body>

        <p>Generating a random number between 1 and 10:

<?php

    echo rand(1, 10);

?>

</p>

</body>

</html>

Most of this is plain HTML. Only the line between <?php and ?> is PHP code. <?php marks the start of an embedded PHP script and ?> marks its end. The web server is asked to interpret everything between these two delimiters and convert it to regular HTML code before it sends the web page to the requesting browser. If you right-click inside your browser and choose View Source (the text may be different depending on the browser you’re using) you can see that the browser is presented with the following:

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<title>Random Number</title>
</head>
<body>
<p>Generating a random number between 1 and 10:
5        </p></body></html>

Notice that all signs of the PHP code have disappeared. In its place the output of the script has appeared, and it looks just like standard HTML. This example demonstrates several advantages of server-side scripting …

No browser compatibility issues. PHP scripts are interpreted by the web server alone, so there’s no need to worry about whether the language features you’re using are supported by the visitor’s browser.

Access to server-side resources. In the example above, we placed a random number generated by the web server into the web page. If we had inserted the number using JavaScript, the number would be generated in the browser and someone could potentially amend the code to insert a specific number. Granted, there are more impressive examples of the exploitation of server-side resources, such as inserting content pulled out of a MySQL database.

Reduced load on the client. JavaScript can delay the display of a web page significantly (especially on mobile devices!) as the browser must run the script before it can display the web page. With server-side code, this burden is passed to the web server, which you can make as beefy as your application requires (and your wallet can afford).

Choice. When writing code that’s run in the browser, the browser has to understand how to run the code given to it. All modern browsers understand HTML, CSS and JavaScript. To write some code that’s run in the browser, you must use one of these languages. By running code on the server that generates HTML, you have a choice of many languages—one of which is PHP.

Basic Syntax and Statements

PHP syntax will be very familiar to anyone with an understanding of JavaScript, C, C++, C#, Objective-C, Java, Perl, or any other C-derived language. But if these languages are unfamiliar to you, or if you’re new to programming in general, there’s no need to worry about it. A PHP script consists of a series of commands, or statements. Each statement is an instruction that must be followed by the web server before it can proceed to the next instruction. PHP statements, like those in the aforementioned languages, are always terminated by a semicolon (;). This is a typical PHP statement:

echo ‘This is a <strong>test</strong>!’;

This is an echo statement, which is used to generate content (usually HTML code) to send to the browser. An echo statement simply takes the text it’s given and inserts it into the page’s HTML code at the position of the PHP script where it was contained. In this case, we’ve supplied a string of text to be output: This is a <strong>test</strong>!. Notice that the string of text contains HTML tags (<strong> and </strong>), which is perfectly acceptable. So, if we take this statement and put it into a complete web page, here’s the resulting code:

PHP-Echo

<!DOCTYPE html>
<html lang="en">
 <head>
        <meta charset="utf-8">
        <title>Test page</title>

</head>
       <body>
 <p><?php echo 'This is a <strong>test</strong>!'; ?></p> 
</body>

</html>

If you place this file on your web server and then request it using a web browser, your browser will receive this HTML code:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Test page</title>

</head>
    <body>
 <p>This is a <strong>test</strong>!</p>
</body>

</html>

The random.php example we looked at earlier contained a slightly more complex echo statement:

echo rand(1, 10);

You’ll notice that, in the first example, PHP is given some text to print directly, and in the second, PHP is given an instruction to follow. PHP tries to readanything that exists outside quotes as an instruction it must follow. Anything inside quotes is treated as a string, which means PHP doesn’t process it at all but just passes it to the command you called. So the following code will pass the string This is a <strong>test</strong>! directly to the echo command:

echo ‘This is a <strong>test</strong>!’;

A string is signified using a start quote and an end quote. PHP will see the first as the start of the string and find the next and use that as the end of the string. In contrast, the following code will first run the built-in function rand to generate a random number and then pass the result to the echo command:

echo rand(1, 10);

You can think of built-in functions as tasks that PHP knows how to do without you needing to spell out the details. PHP has many built-in functions that let you do everything, from sending email to working with information stored in various types of databases. PHP won’t try to run anything that’s inside a string. The following code won’t have the result you may be expecting:

echo ‘rand(1, 10)’;

Instead of running the inbuilt function rand, PHP will see it as a string, and rather than printing out a random number, it will actually send the text rand(1,10) to the browser, which probably isn’t what you wanted to do. It’s important to understand the difference between a string and code. PHP will see any text outside quotes as a series of commands it should follow. Anything inside quotes is a string and is data that PHP will work with. PHP doesn’t try to understand strings. They can contain any characters in any order. But code—which is essentially a series of instructions—must follow a rigid structure for a computer to understand it.

Syntax Highlighting

Using an editor with syntax highlighting makes it easy to quickly see if something is a string or code. Strings will be shown in a different color from code that needs to be processed.

Quotes

PHP supports both single quotes and double quotes to encase strings. For most purposes, they’re interchangeable. PHP developers tend to favor single quotes, because we deal with HTML code a lot, which tends to contain a lot of double quotes. For example:

echo ‘<a href=”http://www.sitepoint.com”>Click here</a>’;

If double quotes were used here, we’d need to tell PHP that the quote after href= is not the end of the string by placing a \ before it (known as an escape character) and do the same with any quotes we actually want to send to the browser as part of the HTML:

echo “<a href=\”http://www.sitepoint.com\”>Click here</a>”;

For this reason, PHP developers use single quotes, although there are some differences between the two quotes. For our purposes, they are effectively interchangeable.

When you invoke a function in PHP—that is, ask it to do its job—you’re said to be calling that function. Most functions return a value when they’re called; PHP then behaves as if you’d actually just typed that returned value in your code instead. In the echo ‘rand(1, 10)’; example, our echo statement contains a call to the rand function, which returns a random number as a string of text. The echo statement then outputs the value returned by the function call. Every function in PHP can have one or more arguments that allow you to make the function behave in a slightly different way. The rand function takes two arguments: the minimum random number and the maximum. By changing the values that are passed to the function, you’re able to change the way it works. For example, if you wanted a random number between 1 and 50, you could use the code:

echo rand(1, 50);

You may wonder why we need to surround the arguments with parentheses ((1, 50)). The parentheses serve two purposes. First, they indicate that rand is a function that you want to call. Second, they mark the beginning and end of a list of arguments—PHP statements that you wish to provide—in order to tell the function what you want it to do. In the case of the rand function, you need to provide a minimum and a maximum value. Those values are separated by a comma. Later on, we’ll look at functions that take different kinds of arguments. We’ll also consider functions that take no arguments at all. These functions will still need the parentheses, even though there will be nothing to type between them.

Variables, Operators, and Comments

Variables

Variables in PHP are identical to variables in most other programming languages. For the uninitiated, a variable can be thought of as a name given to an imaginary box into which any value may be placed. The following statement creates a variable called $testVariable (all variable names in PHP begin with a dollar sign) and assigns it a value of 3:

$testVariable = 3;

PHP is a loosely typed language. This means that a single variable may contain any type of data—be it a number, a string of text, or some other kind of value—and may store different types of values over its lifetime. The following statement—if you were to type it after the aforementioned statement—assigns a new value to the existing $testVariable. Where it used to contain a number, it now contains a string of text:

$testVariable = ‘Three’;

Operators

The equals sign we used in the last two statements is called the assignment operator, as it’s used to assign values to variables. Other operators may be used to perform various mathematical operations on values:

$testVariable = 1 + 1;        // assigns a value of 2

$testVariable = 1 – 1;        // assigns a value of 0

$testVariable = 2 * 2;      // assigns a value of 4

$testVariable = 2 / 2;      // assigns a value of 1

From these examples, you can probably tell that + is the addition operator, is the subtraction operator, * is the multiplication operator and / is the division operator. These are all called arithmetic operators, because they perform arithmetic on numbers.

Comments

Each of the arithmetic lines above ends with a comment. Comments enable you to describe what your code is doing. They insert explanatory text into your code—text that the PHP interpreter will ignore. Comments begin with // and they finish at the end of the same line. If you want a comment to span several lines, start it with /*, and end it with */. The PHP interpreter will ignore everything between these two delimiters. Returning to the operators, one that sticks strings of text together is called the string concatenation operator:

$testVariable = ‘Hi ‘ . ‘there!’; // Assigns a value of ‘Hi there!’

Variables may be used almost anywhere that you use a value. Consider this series of statements:

$var1 = 'PHP';        // assigns a value of 'PHP' to $var1
$var2 = 5;           // assigns a value of 5 to $var2
$var3 = $var2 + 1;   // assigns a value of 6 to $var3
$var2 = $var1;       // assigns a value of 'PHP' to $var2
$var4 = rand(1, 12); // assigns a value to $var4 using the rand() function
echo $var1;       // outputs 'PHP'
echo $var2;       // outputs 'PHP'
echo $var3;       // outputs '6'
echo $var4;       // outputs the random number generated above
echo $var1 . ' rules!'; // outputs 'PHP rules!'
echo '$var1 rules!';        // outputs '$var1 rules!'

echo "$var1 rules!"      // outputs 'PHP rules!'

Note the last two lines in particular: if you place a variable inside single quotes, it will print the name rather than the contents of the variable. In contrast, when using double quotes, the variable in the string is replaced with the variable’s contents.

Control Structures

The examples of PHP code we’ve seen so far have been either one-statement scripts that output a string of text to the web page, or a series of statements that were to be executed one after the other in order. If you’ve ever written programs in other languages (such as JavaScript, Objective-C, Ruby, or Python), you already know that practical programs are rarely so simple. PHP, just like any other programming language, provides facilities that enable you to affect the flow of control. That is, the language contains special statements that you can use to deviate from the one-after-another execution order that has dominated our examples so far. Such statements are called control structures. Don’t understand? Don’t worry! A few examples will illustrate it perfectly.

If Statements

The most basic, and most often used, control structure is the if statement. The flow of a program through an if statement can be visualized like this:

 The logical flow of an if statement

Here’s what an if statement looks like in PHP code:

if (condition) {

   ⋮ conditional code to be executed if condition is true

}

This control structure lets us tell PHP to execute a set of statements only if some condition is met. For example, we might want to create a game that mimics a dice roll and in which you have to roll a six to win. The dice roll can be modeled using the rand() function we used earlier and setting the minimum and maximum from 1 to 6:

$roll = rand(1, 6);

echo ‘You rolled a ‘ . $roll;

To print out a message if the player rolls a six and wins, you can use an if statement:

 PHP-DiceRoll

$roll = rand(1, 6);

echo ‘You rolled a ‘ . $roll;

if ($roll == 6) {

echo ‘You win!’;

}

The == used in the condition above is the equals operator, which is used to compare two values to see whether they’re equal. A single equals = is used for assignment and cannot be used for comparison.The if statement uses braces { and } to surround the code you want to run when the condition is met. You can place as many lines of code as you like between the braces and the code will only be run when the condition is met. Any code placed after the closing brace (}) will be run all the time:

$roll = rand(1, 6);

echo ‘You rolled a ‘ . $roll;

if ($roll == 6) {

echo ‘You win!’;    // This line will only be printed if they rolled a 6

}

echo ‘Thanks for playing’;    // This line will always be printed

Use the Double-Equals

Remember to type the double-equals (==). A common mistake among beginning PHP programmers is to type a condition like this with a single equals sign:

if ($roll = 6)  .   // Missing equals sign!

This condition is using the assignment operator (=) instead of the equal operator (==). Consequently, instead of comparing the value of $roll to the number 6, it will actually set the value of $roll to 6. Oops! To make matters worse, the if statement will use this assignment operation as a condition, which it will consider to be true, so the conditional code within the if statement will always be executed, regardless of what the original value of $roll happened to be.

If you run diceroll.php, you’ll see the random number being generated, and if you run it until you win, you’ll see this in the browser:

You rolled a 6You win!Thanks for playing

This isn’t very pretty, but because PHP outputs HTML you can add some paragraph tags in order to format the output:

example.css

$roll = rand(1, 6);

echo ‘<p>You rolled a ‘ . $roll . ‘</p>’;

if ($roll == 6) {

echo ‘<p>You win!</p>’;

}

echo ‘<p>Thanks for playing</p>’;

If you run the updated diceroll-html.php page, you’ll see that it now prints this in the browser:

You rolled a 6

You win!

Thanks for playing

This is much more user friendly. To make the game itself more user friendly, you might want to display a different message to people who didn’t roll a 6 and didn’t win. This can be done with an else statement. The else statement must follow an if, and will be run if the condition is not met:

 PHP-DiceRoll-Else

$roll = rand(1, 6);

echo ‘<p>You rolled a ‘ . $roll . ‘</p>’;

if ($roll == 6) {

echo ‘<p>You win!</p>’;

}

else {

echo ‘<p>Sorry, you didn\’t win, better luck next time!</p>’;

}

echo ‘<p>Thanks for playing</p>’;

Escaping the Quote

Because the word didn’t contains a single quote, it needs to be escaped. By preceding the single quote with a backslash (\), it tells PHP not to treat the in didn’t as the end of the string.

With an else statement one (and only one!) of the two blocks of code is guaranteed to run. Either the code in the if block will run if the condition is met, or the code in the else block will run if it isn’t. Conditions can be more complex than a single check for equality. An if statement can contain more than one condition. For example, imagine if the game was adjusted so that both 5 and 6 were winning numbers. The if statement could be changed to the following:

 PHP-DiceRoll-Or

if ($roll == 6 || $roll == 5) {

echo ‘<p>You win!</p>’;

}

else {

echo ‘<p>Sorry, you didn\’t win, better luck next time!</p>’;

}

The double pipe (||) operator means “or”. The condition above is now met if either expression evaluates to true. This can be read as “If they rolled a 6 or they rolled a 5”. However, this can be expressed in an even better way. if statements aren’t limited to using the equals (==) operator. They can also utilize the mathematical greater than (>) and less than (<) operators. The if statement above could also be done with a single expression:

 PHP-DiceRoll-Greater

if ($roll > 4) {

echo ‘<p>You win!</p>’;

}

else {

echo ‘<p>Sorry, you didn\’t win, better luck next time!</p>’;

}

$roll > 4 will evaluate to true if the value stored in the $roll variable is greater than 4, allowing us to have 5 and 6 as winning numbers with a single condition. If we wanted 4, 5 and 6 as winning numbers, the condition could be changed to $roll > 3Like the or expression (||), there’s another expression called and that’s is only met when both conditions evaluate to true. We could expand the game to include two dice and require players to roll two sixes to win:

 PHP-DiceRoll-TwoDice

$roll1 = rand(1, 6);

$roll2 = rand(1, 6);

echo ‘<p>You rolled a ‘ . $roll1 . ‘ and a ‘ . $roll2

. ‘</p>’;

if ($roll1 == 6 && $roll2 == 6) {

echo ‘<p>You win!</p>’;

}

else {

echo ‘<p>Sorry, you didn\’t win, better luck next time!</p>’;

}

echo ‘<p>Thanks for playing</p>’;

The expression if ($roll1 == 6 && $roll2 == 6) will only evaluate to true if $roll1 == 6 is true and $roll2 == 6. This means that the player has to roll a 6 on both dice to win the game. If we changed the and (&&) to an or (||)—that is, if ($roll1 == 6 || $roll2 == 6)—the player would win if they rolled a 6 on either dice. We’ll look at more complicated conditions as the need arises. For the time being, a general familiarity with if … else statements is sufficient.

or and and

PHP also allows the use of the or in place of || and and in place of &&. For example:

if ($roll == 6 or $roll == 5) { … }

There are some minor differences between the way or and || work that can lead to unexpected behavior. Generally speaking, avoiding the “spelled out” operators and sticking to the double pipe (||) and double ampersand (&&) will help prevent confusing bugs.

Loops

Another type of control structure that’s very useful is a loop. Loops allow repeating the same lines of code over and over. Two important kind of loops are for loops and while loops. Let’s look at how they work.

For Loops

The for loop is used when you know up front how many times you need to run the same code. The image below shows the flow of a for loop:

 The logical flow of a for loop

Here’s what it looks like in code:

for (declare counter; condition; increment counter) {

     ⋮ statement(s) to execute repeatedly as long as condition is true

}

The declare counterdeclare counter statement is executed once at the start of the loop. The condition statement is checked each time through the loop before the statements in the body are executed. The increment counter statement is executed each time through the loop after the statements in the body. To count to 10 using a for loop, you can use the following code:

for ($count = 1; $count <= 10; $count++) {

       echo $count . ‘ ‘;

}

This looks quite scary, as there’s a lot going on, but let me break it down for you:

$count = 1;: this sets the counters initial value to 1.

$count <= 10;: this is the condition. It can be read of as “keep looping while $count is less than or equal to 10”.

$count++: this says “add 1 to the counter each time”. It’s identical to $count = $count + 1.

echo $count . ‘ ‘;: this prints the value of the counter followed by a space.

The condition in this example uses the operator <=. This acts similarly to the < less than operator, but evaluates to true if the number being compared is less than or equal to the second. Other available operators include >= (greater than or equal) and != (not equal). As you can see, the statements that initialize and increment the $count variable are placed with the condition on the first line of the for loop. Although, at first glance, the code seems a little more difficult to read, putting all the code that deals with controlling the loop in the same place actually makes it easier to understand once you’re used to the syntax. Many of the examples will use for loops, so you’ll have plenty of opportunities to practice reading them. You can change each part of the for loop to have different results. For example, here’s how to add 3 each time you can change the for loop:

 PHP-For

for ($count = 1; $count <= 10; $count = $count + 3) {

    echo $count . ‘ ‘;

}

This will result in the following:

1   4   7   10

for loops can be combined with other statements such as if statements to perform specific tasks on each iteration. For example, rather than refreshing the page on our dice game each time, we might want to roll the dice 10 times and print the results:

 PHP-DiceRoll-ManyDice

for ($count = 1; $count <= 10; $count++) {

$roll = rand(1, 6);

echo ‘<p>You rolled a ‘ . $roll . ‘</p>’;

if ($roll == 6) {

      echo ‘<p>You win!</p>’;

}

else {

     echo ‘<p>Sorry, you didn\’t win, better

     luck next time!</p>’;

}

}

echo ‘<p>Thanks for playing</p>’;

This lets us roll the dice 10 times without needing to refresh the page each time. Using a loop is functionally identical to copy/pasting the code 10 times, and will produce the exact same outcome as the following:

$roll = rand(1, 6);

echo ‘<p>You rolled a ‘ . $roll . ‘</p>’;

if ($roll == 6) {

     echo ‘<p>You win!</p>’;

}

else {

      echo ‘<p>Sorry, you didn’t win, better luck

      next time!</p>’;

}

$roll = rand(1, 6);

echo ‘<p>You rolled a ‘ . $roll . ‘</p>’;

if ($roll == 6) {

     echo ‘<p>You win!</p>’;

}

else {

     echo ‘<p>Sorry, you didn’t win, better luck next

     time!</p>’;

}

$roll = rand(1, 6);

echo ‘<p>You rolled a ‘ . $roll . ‘</p>’;

if ($roll == 6) {

    echo ‘<p>You win!</p>’;

}

else {

echo ‘<p>Sorry, you didn’t win, better luck next time!</p>’;

}

// and so on …

The computer doesn’t care which method you use, whether you copy/paste or use a loop. It will just run the code. However, as a developer, you’ll quickly realize that a loop is the better choice. If you wanted to update the code to also allow 5 as a winning number, you’d need to update the condition in 10 different places. Using a loop, you can change the code in one place and it will affect each iteration of the loop. If you ever find yourself copy/pasting code, there’s always a better way of achieving what you’re trying to do.

While Loops

Another often-used PHP control structure is the while loop. Where the if … else statement allows us to choose whether or not to execute a set of statements depending on some condition, the while loop allows us to use a condition to determine how many times we’ll execute a set of statements repeatedly. The following image shows how a while loop operates:

The logical flow of a while loop

Here’s what a while loop looks like in code:

while (condition) {

   ⋮ statement(s) to execute repeatedly as long as condition is true

}

The while loop works very similarly to an if statement. The difference arises when the condition is true and the statement(s) are executed. Instead of continuing the execution with the statement that follows the closing brace (}), the condition is checked again. If the condition is still true, the statement(s) are executed a second time, and a third, and will continue to be executed as long as the condition remains true. The first time the condition evaluates false (whether it’s the first time it’s checked, or the 101st), the execution jumps immediately to the statement that follows the while loop, after the closing brace. Loops like these come in handy whenever you’re working with long lists of items, but for now I’ll illustrate with a trivial example, counting to ten:

 PHP-WhileCount

while ($count <= 10) {

  echo $count . ‘ ‘;

    ++$count;

}

This works in exactly the same way as a for loop, and you’ll notice a lot of the same statements in different places. This code may look a bit frightening, I know, but let me talk you through it line by line:

  • $count = 1;. The first line creates a variable called $count and assigns it a value of 1.
  • while ($count <= 10). The second line is the start of a while loop, the condition being that the value of $count is less than or equal (<=) to 10.
  • {. The opening brace marks the beginning of the block of conditional code for the while loop. This conditional code is often called the body of the loop, and is executed over and over again, as long as the condition holds true.
  • echo $count . ‘ ‘;. This line simply outputs the value of $count, followed by a space.
  • ++$count;. The fourth line adds one to the value of $count. ++$count is a shortcut for $count = $count + 1. $count++ will also work here! The position of the ++ can be important, but in this case it doesn’t matter. If the ++ is before the variable name, the counter is incremented before the value is read. When $count is zero, the code echo ++$count; will print 1, whereas
  • echo $count++; will print 0. Be careful when using ++, as putting it in the wrong place can cause bugs.
  • }. The closing brace marks the end of the while loop’s body.

So here’s what happens when this code is executed. The first time the condition is checked, the value of $count is 1, so the condition is definitely true. The value of $count (1) is output, and $count is given a new value of 2. The condition is still true the second time it’s checked, so the value (2) is output and a new value (3) is assigned. This process continues, outputting the values 3, 4, 5, 6, 7, 8, 9, and 10. Finally, $count is given a value of 11, and the condition is found to be false, which ends the loop.

The net result of the code is shown in the following image:

The net result of the while loop code

While loops aren’t generally used for simple counters like this, which is normally the job of the for loop. Although you can create a counter with a while loop, usually they’re used to keep running code until something happens. For example, we might want to keep rolling the dice until we get a six. There’s no way to know how many dice rolls will be needed when we write the code: it could take one roll or hundreds to get a six. So you can place the dice roll in a while loop:

PHP-DiceRoll-While

$roll = 0;

while ($roll != 6) {

    $roll = rand(1, 6);

     echo ‘<p>You rolled a ‘ . $roll . ‘</p>’;

if ($roll == 6) {

   echo ‘<p>You win!</p>’; 

}

else {

    echo ‘<p>Sorry, you didn\’t win, better luck

    next time!</p>’;

     }

}

This will keep rolling the dice until a 6 is rolled. Each time you run the code it will take a different number of rolls before you win. The while statement uses the condition $roll != 6. In order for the while loop to be run the first time, the $roll variable must be set to a value for the initial comparison. That’s the purpose of the $roll = 0; line above the while loop. By setting the value to zero initially, when the while loop runs the first time, while ($roll != 6) will evaluate to true (because $roll is equal to zero, not 6!) and the loop will start. Without this line, you’d get an error, because the $roll variable hadn’t been set to anything before it was used. There’s a variant of the while loop called do … while, which is useful in these kinds of cases. It allows you to run some code without a condition and then run it again if the code isn’t set. This takes the following structure:

do {

  statement(s) to execute and then repeat if the condition is true

}

while (condition);

For the dice roll example above, this allows you to ignore the first line:

 PHP-DiceRoll-DoWhile

do {

   $roll = rand(1, 6);

   echo ‘<p>You rolled a ‘ . $roll . ‘</p>’;

if ($roll == 6) {

     echo ‘<p>You win!</p>’;

}

else {

echo ‘<p>Sorry, you didn\’t win, better luck next time!</p>’;

      }

}

while ($roll != 6);

This time, because the condition is at the bottom, by the time the while statement is run, the $roll variable has been given a value, so you don’t need to give it an initial value of zero to force the loop to run the first time.

PSR-2

PHP doesn’t mind how you format your code and whitespace is ignored. You could express the previous example as:

do {

$roll = rand(

1,

6);

echo ‘

You rolled a ‘ .

       $roll . ‘

‘;

if (

$roll == 6

)

{

     echo ‘

You win!

‘;

}

   else

{

     echo ‘

Sorry, you didn\’t win, better luck next time!

‘;

}

}

while ($roll != 6);

The script will execute in the exact same way. Different programmers have different preferred styles, such as using tabs or spaces for indentation, or placing the opening brace on the same line as the statement or after it. We’ll be using a convention known as PSR-2 but use whatever style you feel most comfortable with.

Arrays

An array is a special kind of variable that contains multiple values. If you think of a variable as a box that contains a value, an array can be thought of as a box with compartments where each compartment is able to store an individual value. To create an array in PHP, use square brackets [ and ] containing the values you want to store, separated by commas:

$myArray = [‘one’, 2, ‘3’];

The array Keyword

Arrays in PHP can also be defined using the array keyword. The following code is equivalent to the square bracket notation above:

$myArray = array(‘one’, 2, 3);

The square bracket notation was introduced in PHP 5.4 and is preferred by PHP developers, as it’s less to type, and square brackets are more easily visible among round brackets in control structures like if statements and while loops. /p>

This code creates an array called $myArray that contains three values: ‘one’, 2, and ‘3’. Just like an ordinary variable, each space in an array can contain any type of value. In this case, the first and third spaces contain strings, while the second contains a number. To access a value stored in an array, you need to know its index. Typically, arrays use numbers as indices to point to the values they contain, starting with zero. That is, the first value (or element) of an array has index 0, the second has index 1, the third has index 2, and so on. Therefore, the index of the nth element of an array is n–1. Once you know the index of the value you’re interested in, you can retrieve that value by placing that index in square brackets after the array variable name:

echo $myArray[0]; // outputs ‘one’
echo $myArray[1]; // outputs ‘2’
echo $myArray[2]; // outputs ‘3’

Each value stored in an array is called an element. You can use a key in square brackets to add new elements, or assign new values to existing array elements:

$myArray[1] = ‘two’; // assign a new value
$myArray[3] = ‘four’; // create a new element

You can also add elements to the end of an array using the assignment operator as usual, but leaving empty the square brackets that follow the variable name:

$myArray[] = ‘five’;

echo $myArray[4]; // outputs ‘five’

Array elements can be used like any other variable, and in a lot of cases choosing to use an array or multiple variables will depend on the programmer’s preference. However, arrays can be used to solve problems that normal variables can’t! Remember the dice game from the last section? It would be more user-friendly if it showed the English word rather than the numeral for the result. For example, instead of “You rolled a 3” or “You rolled a 6”, it might be nicer to read “You rolled a three” or “You rolled a six”. To do this, we need some way of converting from a numeral to the English word for that number. This is possible with a series of if statements:

PHP-DiceRoll-English-If

$roll = rand(1, 6);

if ($roll == 1) {

    $english = ‘one’;

}

else if ($roll == 2) {

      $english = ‘two’;

}

else if ($roll == 3) {

     $english = ‘three’;

}

else if ($roll == 4) {

      $english = ‘four’;

}

else if ($roll == 5) {

     $english = ‘five’;

}

else if ($roll == 6) {

     $english = ‘six’;

}

echo ‘<p>You rolled a ‘ . $english . ‘</p>’;

if ($roll == 6) {

         echo ‘<p>You win!</p>’;

}

else {

echo ‘<p>Sorry, you didn\’t win, better luck next  time!</p>’;

}

This solution works, but it’s very inefficient, as you need to write an if statement for each possible dice roll. Instead, you can use an array to store each roll value:

$english = [

1 => ‘one’,

2 => ‘two’,

3 => ‘three’,

4 => ‘four’,

5 => ‘five’,

6 => ‘six’

];

The => notation allows you to define both the keys and the values when creating the array. This is equivalent to:

$english = [];

$english[1] = ‘one’;

$english[2] = ‘two’;

$english[3] = ‘three’;

$english[4] = ‘four’;

$english[5] = ‘five’;

$english[6] = ‘six’;

Although these are equivalent, the code required to use the shorthand notation is a lot quicker to type, is arguably easier to read, and easier to understand. Now that the array is created, it’s possible to read each English word from it:

echo $english[3]; //Prints “three”
echo $english[5]; //Prints “five”

In PHP, a number like 3 it can be replaced with a variable that contains that value.

This is also possible with array keys. For example:

$var1 = 3;

$var2 = 5;

echo $english[$var1];   //Prints “three”

echo $english[$var2];   //Prints “five”

Knowing this, we can piece it all together and adjust the dice game to display the English word of the dice roll by reading the relevant value from the array using the $roll variable:

 PHP-DiceRoll-English-Array

$english = [
    1 => 'one',
   2 => 'two',
    3 => 'three',
    4 => 'four',
    5 => 'five',
    6 => 'six'

];
   $roll = rand(1, 6);
   echo '<p>You rolled a ' . $english[$roll]
 . '</p>';

    if ($roll == 6) {
    echo '<p>You win!</p>';

}
else {
       echo '<p>Sorry, you didn\'t win, better luck
       next time!</p>';
}

As you can see, this is a lot cleaner and tidier than a long list of if statements.

There are two big advantages here:

1. If you wanted to represent a 10-sided dice, it’s a lot easier to add to the array than add an extra if statement for each number.

2. The array is reusable. For the version with two dice, you can just reuse the $english array rather than repeating all the if statements for each dice roll:

PHP-DiceRoll-English-If-TwoDice

$roll1 = rand(1, 6);

$roll2 = rand(1, 6);

if ($roll1 == 1) {

       $english = ‘one’;

}

else if ($roll1 == 2) {

    $english = ‘two’;

}

else if ($roll1 == 3) {

   $english = ‘three’;

}

else if ($roll1 == 4) {

    $english = ‘four’;

}

else if ($roll1 == 5) {

    $english = ‘five’;

}

else if ($roll1 == 6) {

    $english = ‘six’;

}

if ($roll2 == 1) {

    $englishRoll2 = ‘one’;

}

else if ($roll2 == 2) {

    $englishRoll2 = ‘two’;

}

else if ($roll2 == 3) {

   $englishRoll2 = ‘three’;

}

else if ($roll2 == 4) {

    $englishRoll2 = ‘four’;

}

else if ($roll2 == 5) {

   $englishRoll2 = ‘five’;

}

else if ($roll2 == 6) {

    $englishRoll2 = ‘six’;

}

echo ‘<p>You rolled a ‘ . $english . ‘ and a ‘

. $englishRoll2 . ‘</p>’;

Instead, the array can be used for both rolls:

PHP-DiceRoll-English-Array-TwoDice

$english = [
1 => ‘one’,

2 => ‘two’,
3 => ‘three’,
4 => ‘four’,
5 => ‘five’,
6 => ‘six’

];
$roll1 = rand(1, 6);
$roll2 = rand(1, 6);

echo ‘<p>You rolled a ‘ . $english[$roll1] . ‘ and
a ‘ . $english[$roll2] . ‘</p>’;

While numbers are the most common choice for array indices, there’s another possibility. You can also use strings as indices to create what’s called an associative array. It’s called this because it associates values with meaningful indices. In this example, we associate a date (in the form of a string) with each of three names:

$birthdays[‘Kevin’] = ‘1978-04-12’;

$birthdays[‘Stephanie’] = ‘1980-05-16’;

$birthdays[‘David’] = ‘1983-09-09’;

Like the numerical indexes, you can use the shorthand notation for associative arrays as well:

$birthdays = [

‘Kevin’ => ‘1978-04-12’,

‘Stephanie’ => ‘1980-05-16’,

‘David’ => ‘1983-09-09’

];

Now, if we want to know Kevin’s birthday, we look it up using the name as the index:

echo ‘Kevin\’s birthday is: ‘ . $birthdays[‘Kevin’];

This type of array is especially important when it comes to user interaction in PHP, as we’ll see in the next section.

Escaping Quotes

Because Kevin’s contains an apostrophe (single quote) and PHP would see this as the end of the string, it must be escaped with a \ so that PHP treats it as part of the string, rather than marking the end.

User Interaction and Forms

For most database-driven websites these days, you need to do more than dynamically generate pages based on database data. You also need to provide some degree of interactivity, even if it’s just a search box. Veterans of JavaScript tend to think of interactivity in terms of event listeners, which let you react directly to the actions of the user—for example, the movement of the cursor over a link on the page. Server-side scripting languages such as PHP have a more limited scope when it comes to support for user interaction. As PHP code is only activated when a request is made to the server, user interaction occurs solely in a back-and-forth fashion: the user sends requests to the server, and the server replies with dynamically generated pages. The key to creating interactivity with PHP is to understand the techniques we can employ to send information about a user’s interaction, along with a request for a new web page. As it turns out, PHP makes this quite easy.

Passing Variables in Links

The simplest way to send information along with a page request is to use the URL query string. If you’ve ever noticed a URL containing a question mark that follows the filename, you’ve seen this technique in use. For example, if you search for “SitePoint” on Google, it will take you to a search result page with a URL like this:

http://www.google.com/search?hl=en&q=SitePoint

See the question mark in the URL? The text that follows the question mark contains your search query (SitePoint). That information is being sent along with the request for http://www.google.com/searchLet’s code up an easy example of our own. Create a regular HTML file called name.html (no .php filename extension is required, since there won’t be any PHP code in this file) and insert this link:

<a href=”name.php?name=Kevin”>Hi, I&rsquo;m Kevin!</a>

This is a link to a file called name.php, but as well as linking to the file, you’re also passing a variable along with the page request. The variable is passed as part of the query string, which is the portion of the URL that follows the question mark. The variable is called name, and its value is Kevin. So, you’ve created a link that loads name.php, and informs the PHP code contained in that file that name equals KevinTo really understand the effect of this link, we need to look at name.php. Create it as a new HTML file, but this time, note the .php filename extension: this tells the web server that it can expect to interpret some PHP code in the file. In the body of this new web page, type the following:

PHP-GET

$name = $_GET[‘name’];

echo ‘Welcome to our website, ‘ . $name . ‘!’;

?>

Now, put these two files (name.html and name.php) in the Project folder, and load the first file in your browser (the URL should be http://192.168.10.10/ name.html). Click the link in that first page to request the PHP script. The resulting page should say “Welcome to our website, Kevin!”, as shown in the following image:

The welcome message, seen in the browser

Let’s take a closer look at the code that made this possible. This is the most important line:

$name = $_GET[‘name’];

Using what you learned from the Arrays section above, you may be able to figure out what this line does. It assigns the value stored in the ‘name’ element of the array called $_GET to a new variable called $name. But where does the $_GET array come from?

It turns out that $_GET is one of a number of variables that PHP automatically creates when it receives a request from a browser. PHP creates $_GET as an array variable that contains any values passed in the URL query string. $_GET is an associative array, so the value of the name variable passed in the query string can be accessed as $_GET[‘name’]. Your name.php script assigns this value to an ordinary PHP variable ($name), then displays it as part of a text string using an echo statement:

echo ‘Welcome to our website, ‘ . $name . ‘!’;

The value of the $name variable is inserted into the output string using the string concatenation operator (.) that we looked at in the Variables, Operators, and Comments section. But watch out! There’s a security hole lurking in this code! Although PHP is an easy programming language to learn, it turns out it’s also especially easy to introduce security issues into websites using PHP if you’re unaware of what precautions to take. Before we go any further with the language, we want to make sure you’re able to spot and fix this particular security issue, since it’s probably the most common one on the Web today.

The security issue here stems from the fact that the name.php script is generating a page containing content that’s under the control of the user—in this case, the $name variable. Although the $name variable will normally receive its value from the URL query string in the link on the name.html page, a malicious user could edit the URL to send a different value for the name variable. To see how this would work, click the link in name.html again. When you see the resulting page (with the welcome message containing the name “Kevin”), take a look at the URL in the address bar of your browser. It should look similar to this:

http://192.168.10.10/name.php?name=Kevin

Edit the URL to insert a <b> tag before the name and a </b> tag following the name:

http://192.168.10.10/name.php?name=<b>Kevin</b>

Hit Enter to load this new URL, and note that the name in the page is now bold, as shown in the following image:

The name shown in bold

See what’s happening here? The user can type any HTML code into the URL, and your PHP script includes it in the code of the generated page without question. If the code is as innocuous as a <b> tag, there’s no problem, but a malicious user could include sophisticated JavaScript code that performs some low action like stealing the user’s password. All the attacker would have to do is publish the modified link on some other site under the attacker’s control, and then entice one of your users to click it. The attacker could even embed the link in an email and send it to your users. If one of your users clicked the link, the attacker’s code would be included in your page and the trap would be sprung!

We don’t want to scare you with this talk of malicious hackers attacking your users by turning your own PHP code against you, particularly when you’re only just learning the language. The fact is that PHP’s biggest weakness as a language is how easy it is to introduce security issues like this. Some might say that much of the energy you spend learning to write PHP to a professional standard is spent on avoiding security issues. The sooner you’re exposed to these issues, however, the sooner you become accustomed to avoiding them, and the less of a stumbling block they’ll be for you in future. So, how can we generate a page containing the user’s name without opening it up to abuse by attackers? The solution is to treat the value supplied for the $name variable as plain text to be displayed on your page, rather than as HTML to be included in the page’s code. This is a subtle distinction, so let me show you what we mean. Open up your name.php file again and edit the PHP code it contains so that it looks like this:

 PHP-GET-Sanitized

<?php

$name = $_GET[‘name’];

echo ‘Welcome to our website, ‘ .

htmlspecialchars($name, ENT_QUOTES, ‘UTF-8’) . ‘!’;

?>

There’s a lot going on in this code, so let me break it down for you. The first line is the same as it was previously, assigning to $name the value of the ‘name’ element from the $_GET array. But the echo statement that follows it is drastically different. Whereas previously we simply dumped the $name variable, naked, into the echo statement, this version of the code uses the built-in PHP function htmlspecialchars to perform a critical conversion. Remember, the security hole occurs because, in name.php, HTML code in the $name variable is dumped directly into the code of the generated page, and can therefore do anything that HTML code can do. What htmlspecialchars does is convert “special HTML characters” like < and > into HTML character entities like &lt; and &gt;, which prevents them from being interpreted as HTML code by the browser.  First, let’s take a closer look at this new code. The call to the htmlspecialchars function is the first example  of a PHP function that takes more than one argument. Here’s the function call all by itself:

htmlspecialchars($name, ENT_QUOTES, ‘UTF-8’)

The first argument is the $name variable (the text to be converted). The second argument is the PHP constant.A PHP constant is like a variable whose value you’re unable to change. Unlike variables, constants don’t start with a dollar sign. PHP comes with a number of built-in constants like ENT_QUOTES that are used to control built-in functions like htmlspecialchars./span> ENT_QUOTES, which tells htmlspecialchars to convert single and double quotes in addition to other special characters. The third parameter is the string ‘UTF-8’, which tells PHP what character encoding to use to interpret the text you give it.

Text Encoding

You may have discerned that all the example HTML pages  contain the following meta tag near the top:

<meta charset=”utf-8″>

This tag tells the browser receiving this page that the HTML code of the page is encoded as UTF-8 text. UTF-8 is one of many standards for representing text as a series of ones and zeros in computer memory, called character encodings. If you’re curious to learn all about character encodings, check out http://www.sitepoint.com/article/guide-web-character-encoding/. In a few pages, we’ll reach the section on “Passing Variables in Forms”. By encoding your pages as UTF-8, your users can submit text containing thousands of foreign characters that your site would otherwise be unable to handle. Unfortunately, many of PHP’s built-in functions, such as htmlspecialchars, assume you’re using the much simpler ISO-8859-1 (or Latin-1) character encoding by default. Therefore, you need to let them know you’re using UTF-8 when utilizing these functions. If you can, you should also tell your text editor to save your HTML and PHP files as UTF-8 encoded text. This is only required if you want to type advanced characters (such as curly quotes or dashes) or foreign characters (like “é”) into your HTML or PHP code. The code plays it safe and uses HTML entity references (for example, &rsquo; for a curly right quote), which will work regardless.

Open up name.html in your browser and click the link that now points to your updated name.php. Once again, you’ll see the message “Welcome to our website, Kevin!” As you did before, modify the URL to include <b> and </b> tags surrounding the name:

http://192.168.10.10/name.php?name=<b>Kevin</b>

When you hit Enter this time, instead of the name turning bold in the page, you should see the actual text that you typed as shown in the following image:

It sure is ugly, but it’s secure!

If you view the source code of the page, you can confirm that the htmlspecialchars function did its job and converted the < and > characters into the &lt; and &gt; entity references respectively. This prevents malicious users from injecting unwanted code into your site. If they try anything like that, the code is harmlessly displayed as plain text on the page. We’ll make extensive use of the htmlspecialchars function throughout to guard against this sort of security hole. No need to worry too much if you’re having trouble grasping the details of how to use it just at the minute. Before long, you’ll find its use becomes second nature. For now, let’s look at some more advanced ways of passing values to PHP scripts when we request them.

Passing a single variable in the query string was nice, but it turns out you can pass more than one value if you want to! Let’s look at a slightly more complex version of the previous example. Open up your name.html file again, and change the link to point to name.php with this more complicated query string:

<a href=”name.php?firstname=Kevin&amp;lastname=Yank”>

Hi, I&rsquo;m Kevin Yank!</a>

This time, our link passes two variables: firstname and lastname. The variables are separated in the query string by an ampersand (&, which should be written as &amp; in HTML—yes, even in a link URL! … although, if you do wrongly use &browsers will mostly fix it for you). You can pass even more variables by separating each name=value pair from the next with an ampersand. As before, we can use the two variable values in our name.php file:

PHP-GET-TwoVars

$firstName = $_GET[‘firstname’];

$lastName = $_GET[‘lastname’];

echo ‘Welcome to our website, ‘ .

   htmlspecialchars($firstName, ENT_QUOTES, ‘UTF-8’) . ‘ ‘ .

    htmlspecialchars($lastName, ENT_QUOTES, ‘UTF-8’) . ‘!’;

?>

The echo statement is becoming quite sizable now, but it should still make sense to you. Using a series of string concatenations (.), it outputs “Welcome to our website,” followed by the value of $firstName (made safe for display using htmlspecialchars), a space, the value of $lastName (again, treated with htmlspecialchars), and finally an exclamation mark. The result looks like this:

The echoed welcome

This is all well and good, but we’re still yet to achieve our goal of true user interaction, where the user can enter arbitrary information and have it processed by PHP. To continue with our example of a personalized welcome message, we’d like to invite the user to type their name and have it appear in the resulting page. To enable the user to type in a value, we’ll need to use an HTML form.

Passing Variables in Forms

Rip the link out of name.html and replace it with this HTML code to create the form:

PHP-GET-Form

<form action=”name.php” method=”get”>

<label for=”firstname”>First name:</label>

<input type=”text” name=”firstname” id=”firstname”>

<label for=”lastname”>Last name:</label>

<input type=”text” name=”lastname” id=”lastname”>

<input type=”submit” value=”GO”>

</form>

This is how the browser displays the form produced from this code:

The form as it appears in a browser

Adding Some CSS

I’ve added some CSS to the form (available in form.css in the sample code) to make it look a little prettier. The CSS I’ve used is very generic, and can be used to display any form in the format label-input-line break. I’ll be including this CSS file on any page that contains a form.

This form has the exact same effect as the second link we looked at in the “Passing Variables in Links” section above (with firstname=Kevin&amp;lastname=Yank in the query string), except that you can now enter whichever names you like. When you click the submit button (labeled GO), the browser will load name.php and add the variables and their values to the query string for you automatically. It retrieves the names of the variables from the name attributes of the type=”text” inputs, and obtains the values from the text typed into the text fields by the user.

The method attribute of the form tag is used to tell the browser how to send the variables and their values along with the request. A value of get (as used in name.html above) causes them to be passed via the query string (and appear in PHP’s $_GET array), but there is an alternative. It can be undesirable—or even technically unfeasible—to have the values appear in the query string. What if we included a textarea element in the form, to let the user enter a large amount of text? A URL whose query string contained several paragraphs of text would be ridiculously long, and would possibly exceed the maximum length for a URL in today’s browsers. The alternative is for the browser to pass the information invisibly, behind the scenes. Edit your name.html file once more. Modify the form method by setting it to post:

<form action=”name.php” method=”post”>

     <label for=”firstname”>First name:</label>

     <input type=”text” name=”firstname” id=”firstname”>

    <label for=”lastname”>Last name:</label>

    <input type=”text” name=”lastname” id=”lastname”>

    <input type=”submit” value=”GO”>

</form>

This new value for the method attribute instructs the browser to send the form variables invisibly as part of the page request, rather than embedding them in the query string of the URL. As we’re no longer sending the variables as part of the query string, they stop appearing in PHP’s $_GET array. Instead, they’re placed in another array reserved especially for “posted” form variables: $_POST. We must therefore modify name.php to retrieve the values from this new array:

PHP-POST-Form

<?php

$firstname = $_POST[‘firstname’];

$lastname = $_POST[‘lastname’];

echo ‘Welcome to our website, ‘ .

    htmlspecialchars($firstname, ENT_QUOTES, ‘UTF-8’) . ‘ ‘ .

     htmlspecialchars($lastname, ENT_QUOTES, ‘UTF-8’) . ‘!’;

?>

Here’s what the resulting page looks like once this new form is submitted:

The resulting page once the form is submitted

The form is functionally identical to the previous one. The only difference is that the URL of the page that’s loaded when the user clicks the GO button will be without a query string. On the one hand, this lets you include large values (or sensitive values such as passwords and credit card numbers) in the data that’s submitted by the form without them appearing in the query string. On the other hand, if the user bookmarks the page that results from the form’s submission, that bookmark will be useless, as it lacks the submitted values. This, incidentally, is the main reason why search engines use the query string to submit search terms. If you bookmark a search results page on Google, you can use that bookmark to perform the same search again later, because the search terms are contained in the URL.

GET or POST?

As a rule of thumb, you should only use GET forms if, when the form is submitted, nothing on the server changes—such as when you’re requesting a list of search results. Because the search terms are in the URL, the user can bookmark the search results page and get back to it without having to type in the search term again. But if, after submitting the form, a file is deleted, or a database is updated, or a record is inserted, you should use POST. The primary reason for this is that if a user bookmarks the page (or presses back in their browser) it won’t trigger the form submission again and potentially create a duplicate record. That covers the basics of using forms to produce rudimentary user interaction with PHP. We’ll look at more advanced issues and techniques in later examples.

Hiding the Seams

You’re now armed with a working knowledge of the basic syntax of the PHP programming language. You understand that you can take any HTML web page, rename it with a .php file name extension, and inject PHP code into it to generate page content on the fly. Before we go any further, however, we want to stop and cast a critical eye over the examples we’ve discussed so far. Assuming your objective is to create database-driven websites that hold up to professional standards, there are a few unsightly blemishes we need to clean up. The techniques in the rest of this chapter will help advance your programming skills beyond the beginner level, giving them a certain professional polish.

PHP Templates

In the simple examples we’ve seen so far, inserting PHP code directly into your HTML pages has been a reasonable approach. As the amount of PHP code that goes into generating your average page grows, however, maintaining this mixture of HTML and PHP code can become unmanageable. Particularly if you work in a team of not-so-savvy web designers, PHP-wise, having large blocks of cryptic PHP code intermingled with the HTML is a recipe for disaster. It’s far too easy for designers to accidentally modify the PHP code, causing errors they’ll be unable to fix.

A much more robust approach is to separate out the bulk of your PHP code so that it resides in its own file, leaving the HTML largely unpolluted by PHP code. The key to doing this is the PHP include statement. With an include statement, you can insert the contents of another file into your PHP code at the point of the statement. To show you how this works, let’s rebuild the “count to ten” for loop example we looked at earlier. Start by creating a new file, count.php, in this directory. Open the file for editing and type in this code:

<?php

$output = ”;

for ($count = 1; $count <= 10; $count++) {

       $output .= $count . ‘ ‘;

}

include ‘count.html.php’;

Yes, that’s the complete code for this file. It contains no HTML code whatsoever. The for loop should be familiar to you by now, but let me point out the interesting parts of this code:

  • Instead of echoing out the numbers 1 to 10, this script will add these numbers to a variable named $output. At the start of this script, therefore, we set this variable to contain an empty string.
  • The line $output .= $count . ‘ ‘; adds each number (followed by a space) to the end of the $output variable. The .= operator you see here is a shorthand way of adding a value to the end of an existing string variable, by combining the assignment and string concatenation operators into one. The longhand version of this line is $output = $output . $count . ‘ ‘;, but the .= operator saves you some typing.
  • The include statement instructs PHP to execute the contents of the count.html.php file at this location. You can think of the include statement as a kind of copy and paste. You would get the same result by opening up count.html.php, copying the contents and pasting them into count.php, overwriting the include line.
  • Finally, you might have noticed that the file doesn’t end with a ?> to match the opening <?php. You can put it in if you really want to, but it’s unnecessary. If a PHP file ends with PHP code, there’s no need to indicate where that code ends; the end of the file does it for you. The big brains of the PHP world generally prefer to leave it off the end of files like this one that contain only PHP code.

Since the final line of this file includes the count.html.php file, you should create this next:

PHP-Count-Template

<!DOCTYPE html>

<html lang=”en”>

<head>

     <meta charset=”utf-8″>

     <title>Counting to Ten</title>

</head>

<body>

<p>

        <?php echo $output; ?>

</p>

</body>

</html>

This file is almost entirely plain HTML, except for the one line that outputs the value of the $output variable. This is the same $output variable that was created by the index.php file. What we’ve created here is a PHP template: an HTML page with only very small snippets of PHP code that insert dynamically generated values into an otherwise static HTML page. Rather than embedding the complex PHP code that generates those values in the page, we put the code to generate the values in a separate PHP script—index.php in this case.

Using PHP templates like this enables you to hand over your templates to HTML-savvy designers without worrying about what they might do to your PHP code. It also lets you focus on your PHP code without being distracted by the surrounding HTML code. We like to name  PHP template files so that they end with .html.php. As far as your web server is concerned, though, these are still .php files; the .html.php suffix serves as a useful reminder that these files contain both HTML and PHP code.

Security Concerns

One problem with separating out the HTML and PHP code into different files is that someone could potentially run the .html.php code without having had it included from a corresponding PHP file. This isn’t a big problem, but anyone could visit count.html.php directly. If you type http://192.168.10.10/ count.html.php into your web browser, instead of seeing the count from one to ten, you’ll see an error message: Notice: Undefined variable: output in /home/vagrant/Code/Project/public/count.html.php on line 9It’s better not to let people run code in a manner you’re not expecting. Depending on what the page is doing, this might let them bypass security checks you have in place and view content they shouldn’t have access to. For example, consider the following code:

if ($_POST[‘password’] == ‘secret’) {

         include ‘protected.html.php’;

}

Looking at this code, it appears that you need to submit a form and type secret in the password box to see the protected content in protected.html.php. However, if someone can navigate directly to protected.html.php and see the contents of the page, it makes the security check redundant. There are other potential security issues introduced by making all your files accessible via a URL. Avoiding security problems like these is easy. You can actually include files from a directory other than the public directory.

You may have wondered earlier why we created a Project directory and then wrote all our files to the public directory inside Project. Well, this issue of security is the reason why. None of the files outside the public directory are accessible via a URL (by someone typing the file name into their web browser). The include command can be tweaked to include files from another directory. In our case, that directory is going to the Project directory, which contains the files we’ve been working on so far. So the question is, when the include file is in a different directory, how does a PHP script find it? The most obvious method is to specify the location of the include file as an absolute path. Here’s how this would look on a Windows server:

<?php include ‘C:/Program Files/Apache Software Foundation/Apache2.2/protected.html.php’; ?>

And here’s how it would look using the Homestead Improved box:

<?php include ‘/home/vagrant/Code/Project/protected.html.php’; ?>

While this method will work, it’s undesirable because it ties your site’s code to your web server configuration. Ideally, you should be able to drop your PHP-based website onto any PHP-enabled web server and just watch it run. This is particularly important because many developers will build a site on one server, then deploy it publicly on a different server. That’s impractical if your code refers to drives and directories that are specific to one particular server. Even if you do have the luxury of working on a single server, you’ll be kicking yourself if you ever need to move your website to another drive/directory on that server. A better method is to use a relative path. That is, the location of a file relative to the current file. When you use include ‘count.html.php’ this is actually a relative path, count.html.php is being included from the same directory as the script that was executed. To include a file from the directory above, you can use the following code:

include ‘../count.html.php’;

../ tells PHP to look for the file in the directory above the directory of the current script. It will look for count.html.php in the Project directory instead of the public directory.

Go ahead and move count.html.php up a level into the Project directory and amend count.php to reference the new location:

PHP-Count-Template-Secured

<?php

$output = ”;

for ($count = 1; $count <= 10; $count++) {

       $output .= $count . ‘ ‘;

}

include ‘../count.html.php’;

If you run the code above, it will work. But there’s a potential problem when you include files in this way. Relative paths are relative to the script that was run, not to each file. That is, if you open up Project/count.html.php and add the line include ‘count2.html.php’; you would expect count2.html.php to be included from the Project directory. However, the path is relative to something called the current working directory, which, when you run a PHP script, is initially set to the directory that script is stored in. So running include ‘count2.html.php’; from count.html.php will actually try to load count2.html.php from the public directory! The current working directory is set at the start of the script and applies to all the include statements, regardless of what file they are in. To make things even more confusing, it’s possible to change the current working directory using the chdir() function. Because of this, we can’t rely on this:

include ‘../count.html.php’;

It will work, but if the directory is changed, or count.php itself is an include file, it may not have the result we’re expecting. To overcome this, we do actually need to use relative paths. Luckily, PHP provides a constant called __DIR__ (that’s two underscores, before and after the word DIR) which will always contain the path that contains the current fileFor example, you could create a file called dir.php inside the public directory with the following code:

echo __DIR__;

This will display /home/vagrant/Code/Project/public, which is the full path to the directory containing dir.php. To read count.html.php from the directory above public, it’s possible to combine the /../ operator and the __DIR__constant:

include __DIR__ . ‘/../count.html.php’;

This will now include the file /home/vagrant/Code/Project/public/../count.html. That is, PHP will look in the public directory, then go up one level into Project and include count.html.php.

This approach will work on any server, because __DIR__ will differ depending on where the file is stored, and it doesn’t depend on the changing current working directory.From now on, we’ll only write files to the public directory that we actually want users to be able to access directly from their web browser. The public directory will contain any PHP scripts the user needs to access directly along with any images, JavaScript and CSS files required by the browser. Any files only referenced by an include statement will be placed outside the public directory so users can’t access them directly. We are going to introduce you to several different types of include files. To keep things organized, it’s sensible to store different types of include file in different directories. We’ll store template files (with a .html.php extension) inside a directory called templates inside the Project folder. We can then reference them in an include statement using include __DIR__ . ‘../templates/file.html.php’;.

Many Templates, One Controller

What’s nice about using include statements to load your PHP template files is that you can have multiple include statements in a single PHP script, as well as have it display different templates under various circumstances! A PHP script that responds to a browser request by selecting one of several PHP templates to fill in and send back is commonly called a controller. A controller contains the logic that controls which template is sent to the browser.

Let’s revisit one more example from earlier in this chapter: the welcome form that prompts a visitor for a first and last name. We’ll start with the PHP template for the form. For this, we can just reuse the name.html file we created earlier. Create a directory templates inside Project if you haven’t already, and save a copy of name.html called form.html.php into this directory. The only code you need to change in this file is the action attribute of the form tag:

PHP-Form-Controller

<html>

<head>

    <title>Enter your name</title>

    <link rel=”stylesheet” href=”form.css” />

    <meta charset=”utf-8″>

</head>

<body>

<form action=”” method=”post”>

      <label for=”firstname”>First name:</label>

     <input type=”text” name=”firstname” id=”firstname”>

     <label for=”lastname”>Last name:</label>

     <input type=”text” name=”lastname” id=”lastname”>

    <input type=”submit” value=”GO”>

</form>

</body>

</html>

As you can see, we’re leaving theaction attribute blank. This tells the browser to submit the form back to the same URL it received it from—in this case, the URL of the controller that included this template file. Let’s take a look at the controller for this example. Create an index.php inside the public directory containing the following code:

<?php

if (!isset($_POST[‘firstname’])) {

       include __DIR__ . ‘/../templates/form.html.php’;

} else {

    $firstName = $_POST[‘firstname’];

    $lastName = $_POST[‘lastname’];

if ($firstName == ‘Kevin’ && $lastName == ‘Yank’) {

    $output = ‘Welcome, oh glorious leader!’;

} else {

    $output = ‘Welcome to our website, ‘ .

   htmlspecialchars($firstName, ENT_QUOTES, ‘UTF-8’) . ‘ ‘ .

  htmlspecialchars($lastName, ENT_QUOTES, ‘UTF-8’) . ‘!’;

}

include __DIR__ . ‘/../templates/welcome.html.php’;

}

This code should look quite familiar at first glance. It’s a lot like the name.php script we wrote earlier. Let me explain the differences:

The controller’s first task is to decide whether the current request is a submission of the form in form.html.php or not. You can do this by checking if the request contains a firstname variable. If it does, PHP will have stored the value in $_POST[‘firstname’].

isset is a built-in PHP function that will tell you if a particular variable (or array element) has been assigned a value or not. If $_POST[‘firstname’] has a value, isset($_POST[‘firstname’]) will be true. If $_POST[‘firstname’] is unset, isset($_POST[‘firstname’]) will be false.

For the sake of readability, I like to put the code that sends the form in my controller first. We need this if statement to check if $_POST[‘firstname’] is not set. To do this, we use the not operator (!). By putting this operator before the name of a function, you reverse the value that function returns—from true to false, or from false to true.

Thus, if the request does not contain a firstname variable, then !isset($_POST[‘firstname’]) will return true, and the body of the if statement will be executed.

If the request is not a form submission, the controller includes the form.html.php file to display the form.

  • If the request is a form submission, the body of the else statement is executed instead.
  • This code pulls the firstname and lastname variables out of the $_POST array, and then generates the appropriate welcome message for the name submitted.
  • Instead of echoing the welcome message, the controller stores the welcome message in a variable named $output.
  • After generating the appropriate welcome message, the controller includes the welcome.html.php template, which will display that welcome message.

All that’s left is to write the welcome.html.php into the templates directory. Here it is:

<!DOCTYPE html>

<html lang=”en”>

<head>

   <meta charset=”utf-8″>

  <title>Form Example</title>

</head>

<body>

<p>

     <?php echo $output; ?>

</p>

</body>

</html>

That’s it! Fire up your browser and point it at http://192.168.10.10/index.php. You’ll be prompted for your name, and when you submit the form, you’ll see the appropriate welcome message. The URL should stay the same throughout this process.

You’ll have noticed I asked you to name the file index.php instead of name.php or similar. The reason I used index.php is because it has a special meaning. index.php is known as a directory index. If you don’t specify a filename when you visit the URL in your browser, the server will look for a file named index.php and display that. Try typing just http://192.169.10.10 into your browser and you’ll see the index page.

Web Server Configuration

Web servers can have different configurations and specify a different file to be the directory index. However, on most web servers index.php will work without any further configuration.

One of the benefits of maintaining the same URL throughout this process of prompting the user for a name and displaying the welcome message is that the user can bookmark the page at any time during this process and gain a sensible result. Whether it’s the form page or the welcome message that’s bookmarked, when the user returns, the form will be present once again. In the previous version of this example, where the welcome message had its own URL, returning to that URL without submitting the form would have generated a broken welcome message (“Welcome to our website, !”), or a PHP error message if, like Homestead Improved, the server is running with error reporting enabled.

Bring on the Database

In this chapter, we’ve seen the PHP server-side scripting language in action as we’ve explored all the basic language features: statements, variables, operators, comments, and control structures. The sample applications we’ve seen have been reasonably simple, but we’ve still taken the time to ensure they have attractive URLs, and that the HTML templates for the pages they generate are uncluttered by the PHP code that controls them. As you may have begun to suspect, the real power of PHP is in its hundreds (even thousands) of built-in functions that let you access data in a MySQL database, send email, dynamically generate images, and even create Adobe Acrobat PDF files on the fly.We’ll delve into the MySQL functions built into PHP, and then create a database of jokes. Then, we’ll see how to publish the joke database we created to the Web. These tasks will set the scene for the ultimate goal: to create a complete content management system for your website in PHP and MySQL.

Introducing MySQL

We booted the Homestead Improved virtual machine. The virtual machine contains all the software we need, including a MySQL server.PHP is a server-side scripting language that lets you insert instructions into your web pages that your web server software will execute before it sends those pages to browsers that request them. We’ve looked at a few basic examples including generating random numbers and using forms to capture input from a user. Now, that’s all well and good, but it really gets interesting when a database is added to the mix. We’ll learn what a database is, and how to work with your own MySQL databases using Structured Query Language (SQL).

An Introduction to Databases

A database server (in our case, MySQL) is a program that can store large amounts of information in an organized format that’s easily accessible through programming languages like PHP. For example, you could tell PHP to look in the database for a list of jokes that you’d like to appear on your website. In this example, the jokes would be stored entirely in the database. The advantage of this approach is twofold. First, instead of writing an HTML page for each joke, you could write a single PHP script that was designed to fetch any joke from the database and display it by generating an HTML page for it on the fly. Second, adding a joke to your website would be a simple matter of inserting the joke into the database. The PHP code would take care of the rest, automatically displaying the new joke along with the others when it fetched the list from the database.

Let’s run with this example as we look at how data is stored in a database. A database is composed of one or more tables, each of which contains a list of items, or things. For our joke database, we’d probably start with a table called joke that would contain a list of jokes. Each table in a database has one or more columns, or fields. Each column holds a certain piece of information about each item in the table. In our example, our joke table might have one column for the text of the jokes, and another for the dates on which the jokes were added to the database. Each joke stored in this way would be said to be a row or entry in the table. These rows and columns form a table that looks like this:

A typical database table containing a list of jokes

Notice that, in addition to columns for the joke text (joketext) and the date of the joke (jokedate), there’s included a column named id. As a matter of good design, a database table should always provide a means by which each row can be identified uniquely. Since it’s possible that two identical jokes could be entered on the same date, we can’t rely on the joketext and jokedate columns to tell all the jokes apart. The function of the id column, therefore, is to assign a unique number to each joke, so that we have an easy way to refer to them and to keep track of which joke is which. We’ll take a closer look at database design issues like this laterTo review, the table in the figure above is a three-column table with two rows (or entries). Each row in the table contains three fields, one for each column in the table: the joke’s ID, its text, and the date of the joke. With this basic terminology under your belt, you’re ready to dive into using MySQL.

Using MySQL Workbench to Run SQL Queries

Just as a web server is designed to respond to requests from a client (a web browser), the MySQL database server responds to requests from client programs. Later, we’ll write our own MySQL client programs in the form of PHP scripts, but for now we can use a client program written by the same people who write MySQL: MySQL Workbench. You can download MySQL Workbench for freeThere are many different MySQL clients available to use, like phpMyAdmin, a web-based MySQL client that has many of the same features. However, it’s not as easy to use as MySQL Workbench, and can often be very slow.Once you’ve downloaded and installed MySQL Workbench, open it up, and you should see a screen that looks like this:

If you can see this, you have MySQL Workbench running

Before you can add any data to your database, you need to connect to it. MySQL is a server running in the Vagrant box you downloaded before, and you can connect to it using a MySQL client such as MySQL Workbench.Connecting to the database requires three pieces of information:

  • a server address
  • a username
  • a password

For the Homestead Improved Vagrant box, the information is:

  • Server: 192.168.10.10
  • Username: homestead
  • Password: secret

You’ll notice that the server IP is identical to the IP you’ve been connecting to in your web browser to view your PHP scripts. The virtual machine is running both the web server and the database server, so you only need to remember a single IP address. To connect to a database in MySQL Workbench, press the plus button next to the label “MySQL Connections” in the centre of the window. (Admittedly, it isn’t very clearly labeled, and its purpose isn’s very clear, but never mind!)

Add a connection

When you press the plus button, you’ll see a new window that looks like this:

 Add a connection

Enter the server address and username. You’ll also need to give your connection a name. I’ve called it “Homestead”, but you can call it whatever you like. This is just a name that it’s listed as for future reference in MySQL Workbench. Once you’ve entered the username and server, you can try connecting to the database by pressing the “Test Connection” button at the bottom of the window. You should get a password prompt box that looks like this:

Password prompt

If you don’t, follow these steps:

1.Double check that your Vagrant box is running. (If you’ve rebooted your PC since setting it up, you may need to run vagrant up again in the project’s folder to get it running!)

2.Make sure the username and server address are correct.

Case Sensitivity

Usernames and passwords are case-sensitive, so make sure you type them both in lowercase!

Enter the password secret into the box and tick the box that says “Save password”. By checking the box, you won’t have to enter the password each time you connect. Then press OKIf the password was entered correctly, you’ll see a message telling you the connection was successful. Press OK in the “Set up new connection” window and you’ll see a box appear in the main MySQL window with some of the information you entered:

i

The main MySQL window showing information that was entered

Now that the connection is set up, it will be there each time you open MySQL workbench, you won’t need to add the connection each time. You’re finally ready to actually connect to the database. To do this, simply double-click on the newly created box representing your connection and you’ll be presented with a different screen:

Initial screen

This looks a little daunting at first, as there are a lot of different buttons and panels all representing different things. Down the left-hand side is a menu with lots of different options. The only one you need to worry about is the bottom section titled “Schemas”. Schema is just a fancy word for “database”. MySQL is a database server. In practical terms, this means that it can host lots of different databases, similarly to how a web server can host lots of different websites.

Creating a Database

Before you can add any information to a database, you need to create one. There are already two entries in the Schemas panel, homestead and sys. These come with Homestead, and although you could use them, for our purposes it would be better to create a database with a more suitable name. To create a database, right-click in the Schemas panel and select “Create schema”. This gives you a window with several options, but you only need to enter one: the schema name.

Creating a schema

We chose to name the database ijdb, for Internet Joke Database, because that fits with the example we gave at the beginning: a website that displays a database of jokes. Feel free to give the database any name you like, though. Once you’ve typed a name, you can safely leave the other options at their default values and press Apply. When you do this, MySQL Workbench will ask you to confirm your action. (Get used to these dialogs. MySQL Workbench insists on confirmation for almost everything you do!) Press Apply again on this screen:

Confirming the schema creation

Once you’ve pressed Apply, you’ll need to press Finish on the next screen. This is one of the annoying things about MySQL Workbench: it forces you to confirm and then Finish every action. However, it’s better than the alternative, as we’ll see shortly! In the screenshot above, you’ll see a white panel with the words CREATE SCHEMA ijdb. This is an SQL Query, and you’ll see a lot more of these. You could have typed out this command yourself and run it, avoiding the GUI and saving yourself going through MySQL Workbench’s confirmation dialogs. And for a command as simple as CREATE SCHEMA ijdb, the GUI is probably overkill. However, as you’ll see shortly, not all of the commands are this simple, and it’s a lot easier to use MySQL Workbench’s GUI for some of the more complex queries. If you want to be able to delete databases (and this is probably a good ability to have, given the amount of experimentation), MySQL Workbench makes this easy. In the Schemas panel in the main window, right-click on the schema you want to delete and select DROP Schema. MySQL uses the word DROP for deleting things. (Somewhat inconsistently, Delete is also used for some things!)

Structured Query Language

Like the CREATE SCHEMA command we just saw, the commands we’ll use to direct MySQL throughout are part of a standard called Structured Query Language, or SQL (pronounced as either “sequel” or “ess-cue-ell”—take your pick). Commands in SQL are also referred to as queries; we’ll use these two terms interchangeably.SQL is the standard language for interacting with most databases, so, even if you move from MySQL to a database like Microsoft SQL Server in the future, you’ll find that the majority of commands are identical. It’s important that you understand the distinction between SQL and MySQL. MySQL is the database server software that you’re using. SQL is the language that you use to interact with that database. Most of these commands can be generated by MySQL Workbench, and that’s what we’ll use to create the structure of our database. However, you’ll need to learn some commands, as you’ll be executing them from your PHP scripts rather than MySQL Workbench!

Dive Deeper Into SQL

We’ll teach you the essentials of SQL that every PHP developer needs to know. If you decide to make a career out of building database-driven websites, it pays to know some of the more advanced details of SQL, especially when it comes to making your sites run as quickly and smoothly as possible.

Case Sensitivity and Convention

Most MySQL commands are not case-sensitive, which means you can type CREATE DATABASE, create database, or even CrEaTe DaTaBaSe, and it will know what you mean. Database names and table names, however, are case-sensitive when the MySQL server is running on an operating system with a case-sensitive file system (such as Linux or macOS, depending on your system configuration). Additionally, table, column, and other names must be spelled exactly the same when they’re used more than once in the same query. For consistency, we will respect the accepted convention of typing database commands in all capitals, and database entities (databases, tables, columns, and so on) in all lowercase. This also makes it easier for people (like you!) to read the queries. MySQL doesn’t care, but you’ll be able to identify a command quickly and easily because it’s in capitals, and a reference to a table, column or database because it’s in lowercase.

Once your database has been created, it will appear in the Schemas list on the left-hand side:

The Internet Joke Database schema

Now that you have a database, you need to tell MySQL Workbench that you want to use it. To do this, simply double-click the newly created schema and its name will go bold. You can only have one schema selected at a time, and you need to tell MySQL Workbench which you’d like to use:

The ijdb schema selected

You’re now ready to use your database. Since a database is empty until you add tables to it, our first order of business is to create a table that will hold your jokes. (Now might be a good time to think of some!)

Creating a Table

If you expand your newly created ijdb schema by pressing the arrow next to the name, you’ll see a few entries:

The ijdb schema expanded

The only one we’re concerned for now is the Tables entry. Because your schema has just been created, it doesn’t have any tables. A table describes the format of your data. You’ll need to know the structure of the data you’d like to store. Before creating a table, you need to think about exactly what you want to store. For the jokes example, we want to store these pieces of information:

  • the text of the joke
  • the date it was added

Along with the text and date, we’ll also need some way to identify each joke. To do this, we’ll give each joke a unique ID. Each piece of information is placed in a field in the table, and each field has a type. Types can be used to store data in different formats like numbers, text and dates. There are three main kinds of types that you’ll encounter:

  • numbers, for storing numeric values
  • text, for storing strings
  • dates/times for storing timestamps

There are lots of column types in MySQL, but you only really need an understanding of three for most purposes! To create a table using MySQL Workbench, expand the database in the Schemas list, then right-click on the Tables entry and select Create TableThe middle panel of the window will change to show you something like this:

MySQL Workbench’s New Table window

Every table is given a name to identify it and a series of columns. Firstly, enter the table’s name as “joke” and add the following columns in the column list:

  • id, which will act as a unique identifier for each joke so we can retrieve it later
  • joketext, which will store the text of the joke
  • jokedate, which will store the date the joke was added

Creating the joke table

You’ll notice there’s a second column called Datatype. Each column in a database table must be assigned a type. The three types we will need are:

  • INT, meaning “integer” for the numeric jokeid
  • TEXT, to store some text for the joke
  • DATE, to store the date the joke was published

This helps to keep your data organized, and allows you to compare the values within a column in powerful ways, as we’ll see later. If we were to stop setting up the table at this point, you could start adding records to the table (and we’ll show you how to do that very shortly!). However, you would have to provide all three pieces of information: the joke ID, the joke text and the joke date. This means that, to add the next joke, you’d need to keep track of how many were in there in order to assign the next ID. This sounds like extra work, but fortunately MySQL Workbench provides a convenient way of avoiding it. Along with the name of the column and data type it stores, you’ll notice there’s a series of checkboxes for each field in the table. There are three we’re interested in here for our ID field:

  • PK. This means “primary key”. Ticking this box specifies that this column is to act as a unique identifier for the entries in the table, so all values in this column must be unique, ensuring that no two jokes will share the same ID.
  • NN. This stands for “Not Null”, and means that when a record is added, a value must be placed in the field. For our ID column, ticking this box tells MySQL not to accept jokes that don’t have an ID.
  • AI. This is the clever bit that will save us work. No, “AI” is not “Artificial Intelligence”, some kind of computer-brain doing our work for us. In this case, it stands for “Auto Increment”, and by checking this box (and it’s only allowed on INT fields!), whenever a record (in our case, a joke) is added to the table, it will automatically be assigned the next available ID. This is a real time saver and a feature worth remembering.

Your table should now look like this:

The joke table complete

Press the Apply button and the joke table will be created. You’ll see the following query appear in the window:

CREATE TABLE `ijdb`.`joke` (

`id` INT NOT NULL AUTO_INCREMENT,

`joketext` TEXT NULL,

`jokedate` DATE NULL,

PRIMARY KEY (`id`));

You’ll notice a lot of the same information has been repeated that we entered into the GUI. The GUI just generates this code for us, which is a much quicker and easier way of creating tables than remembering all of the syntax and vocabulary needed to write the query yourself.As a developer, you don’t need to create tables often. You will need to interact with them, though—adding and removing records and retrieving them from the database—so it’s worth spending time learning how to write queries to do this. But for creating tables, it’s usually a lot quicker and easier to use the MySQL Workbench GUI, because once a table has been created, you won’t need to write another create table statement. We need to look at just one more task: deleting a table. This task is frighteningly easy, so be careful! If you delete a table, you can’t get it back.

In the Schemas list, right-click on the table you you want to delete and select Drop Table. Don’t run this command with your joke table, unless you actually do want to be rid of it. If you really want to try it, be prepared to re-create your joke table from scratch. When you delete a table, the table is removed permanently, along with any data stored inside it. There is no way to recover the data after the table has been dropped, so be very careful when using this command!

Adding Data

Now that the table has been created, it’s time to add some data to it. Although this can be done using MySQL Workbench’s GUI, this time we’re going to write the query ourselves. Eventually, we’ll need to be able to write our own database queries directly from PHP, so it’s good to get some practice writing them. To run a query, you need to open up a query window. The simplest way to do this is to expand your database in the Schema list. Expand the Tables entry, and you’ll see the joke table that you just created. Right-click on the table and click on the topmost option “Select Rows – Limit 1000”. This will give you a slightly different screen that’s split into two panels:

A new query panel

The top half is a text box into which you can type commands to ask your database server questions or make it perform tasks. The bottom half is the result of that query. You’ll see there’s already a query in the top panel:

SELECT * FROM `ijdb`.`joke`;

We’ll come back to what this means shortly. Along with this query in the top panel, there’s a list of rows in the bottom panel—or rather there would be, if there were anything in the table! Because the table was just created, it’s currently empty. Before you can view the contents of the table, you need to add some records. All that’s left is to put some jokes into the database. The command that inserts data into a database is called, appropriately enough, INSERT. This command can take two basic forms:

INSERT INTO tableName SET

column1Name = column1Value,

column2Name = column2Value,

INSERT INTO tableName

(column1Name, column2Name, …)

VALUES (column1Value, column2Value, …)

So, to add a joke to our table, we can use either of these commands:

INSERT INTO joke SET

joketext = “A programmer was found dead in the shower. The instructions read: lather, rinse, repeat.”,

jokedate = “2017-06-01”

INSERT INTO joke

(joketext, jokedate) VALUES (

“A programmer was found dead in the shower. The instructions read: lather, rinse, repeat.”,

“2017-06-01”)

Note that the order of the column/value pairs isn’t important, but pairing the right values with the right columns, position-wise, is. If the first column mentioned in the first set of parentheses is joketext, then the first entry in the VALUES list must be the text that’s going to be placed in the joketext column. The second column name in the first parentheses gets its values from the same position in the VALUES list. Otherwise, the order of the columns isn’t important. Go ahead and swap the order of the column and value pairs and try the query.

As you typed the query, you’ll have noticed that we used double quotes () to mark where the text of the joke started and ended. A piece of text enclosed in quotes this way is called a text string, and this is how you represent most data values in SQL. For instance, the dates are typed as text strings, too, in the form “YYYY-MM-DD”If you prefer, you can type text strings surrounded with single quotes () instead of double quotes:

INSERT INTO joke SET

joketext = ”,

jokedate = ‘2017-06-01’

You might be wondering what happens when there are quotes used within the joke’s text. Well, if the text contains single quotes, you would surround it with double quotes. Conversely, if the text contains double quotes, surround it with single quotes. If the text you want to include in your query contains both single and double quotes, you’ll have to escape the conflicting characters within your text string. You escape a character in SQL by adding a backslash (\) immediately before it. This tells MySQL to ignore any “special mea ing” this character might have. In the case of single or double quotes, it tells MySQL not to interpret the character as the end of the text string. To make this as clear as possible, here’s an example of an INSERT command for a joke containing single quotes, even though single quotes have been used to mark the string:

INSERT INTO joke

(joketext, jokedate) VALUES (

‘!false – it\’s funny because it\’s true’,

“2017-06-01”)

As you can see, we’ve marked the start and end of the text string for the joke text using single quotes. We’ve therefore had to escape the two single quotes (the apostrophes) within the string by putting backslashes before them. MySQL would see these backslashes and know to treat the single quotes as characters within the string, rather than end-of-string markers. If you’re especially clever, you might now be wondering how to include actual backslashes in SQL text strings. The answer is to type a double-backslash (\\), which MySQL will treat as a single backslash in the string of text. Write your insert query into the top text box in MySQL Workbench and press the yellow lightning bolt icon above it to execute the query.

i

Executing a query using MySQL Workbench

When the query executes, a panel will appear at the bottom of the screen telling you if the query was executed successfully:

“Checking a query has executed successfully

If you get an error and the query isn’t successful, take a look at the error message and it should give you a hint where to look. Double-check your syntax, and check your quotes and parentheses are in the right place.

Displaying the Bottom Panel on Low-Res Screens

If you have a lower screen resolution than it’s expecting, MySQL Workbench hides the bottom panel. To display it, hover your mouse just below the scroll bar at the bottom of the window and you’ll get a resize cursor. You can then drag the panel into view.

Add both the jokes (and any others you can think of!) to the database using INSERT queries. Now that you know how to add entries to a table, let’s see how we can view those entries.

A Word of Warning

You’ll have noticed something slightly peculiar about the queries that have been generated by MySQL Workbench. Instead of a query that looks like this:

SELECT * FROM joke

The query generated will be:

SELECT * FROM `joke`

With those strange quotes around joke. Those aren’t actually quotes, or even apostrophes like we’ve been using to designate strings. They’re backticksThis is a safety precaution. There are lots of words in SQL that have meaning to the language. You’ve seen a few already: SELECT, FROM and INSERT, but there are hundreds of others, known as reserved words. Imagine if you called your table SELECT. The query you would need to run would look like this:

SELECT * FROM SELECT

Unfortunately, this can cause MySQL to get a little confused. It may see SELECT as a command rather than as a table name. What’s worse, date is one of these words, and it’s not improbable that you might think to create a column in one of your tables called date. What would you expect to happen when the following query runs?

INSERT INTO joke

(joketext, date) VALUES (

‘!false – it\’s funny because it\’s true’,

“2012-04-01”)

Because the word date already has meaning in SQL, it may not be seen as a column name but as part of the query, like VALUES or INTOMySQL is usually good at guessing whether you’re referring to a table/column name or a command it needs to follow, but there are times when it isn’t able to make that distinction. To avoid this kind of confusion, it’s good practice to surround all table and column names with backticks. The backticks tell MySQL to treat the string as a name rather than an instruction. It’s good to get into the habit of doing this from the very start, as it avoids issues later on that often aren’t immediately obvious. From now on, we’ll surround all table, schema and column names with backticks. This will also help you—as a programmer—to distinguish between commands and column names. For instance, the INSERT query above would be written like this:

INSERT INTO `joke`

(`joketext`, `date`) VALUES (

‘!false – it\’s funny because it\’s true’,

“2012-04-01”)

Where’s the Darned Backtick Key?

On many English keyboard layouts, the backtick key is the one to the immediate left of the numeric 1 key and below Esc. On Macs, it’s often located to the left of the Z key. Its location may differ on non-English keyboards and/or on various devices such as laptops and tablets.

Viewing Stored Data

The command that we use to view data stored in database tables is SELECT. You saw an example SELECT query generated for you by MySQL Workbench earlier. The SELECT query is the most complicated command in SQL. The reason for this complexity is that the chief strength of a database is its flexibility in data retrieval. At this early point in our experience with databases, we need only focus on fairly simple lists of results, so let’s consider the simpler forms of the SELECT command here. This command will list everything that’s stored in the joke table:

SELECT * FROM `joke`

This command says “select everything from joke”, with the * meaning “all columns”. By default, a SELECT query will return every record in the table. If you try this command, your results will resemble this:

MySQL Workbench results

Notice that there are some values in the id column, even though you didn’t specify them in the INSERT queries you ran earlier. MySQL has automatically assigned an ID to the joke. This is because you checked the “AI” (Auto Increment) checkbox when you created the table. If you hadn’t checked the box, you’d have needed to specify the ID for each joke you inserted. If you were doing serious work on such a database, you might be tempted to stop and read all the hilarious jokes in the database at this point. To save yourself the distraction, you might want to tell MySQL to omit the joketext column. The command for doing this is as follows:

SELECT `id`, `jokedate` FROM joke

This time, instead of telling it to “select everything,” we told it precisely which columns we wanted to see. The result should look like this:

You can select only what you need

What if we’d like to see some of the joke text? As well as being able to name specific columns that we want the SELECT command to show us, we can use functions to modify each column’s display. One function, called LEFT, enables us to tell MySQL to display a column’s contents up to a specified number of characters. For example, let’s say we wanted to see only the first 20 characters of the joketext column. Here’s the command we’d use:

SELECT `id`, LEFT(`joketext`, 20), `jokedate` FROM `joke`

i

The LEFT function trims the text to a specified length

See how that worked? Another useful function is COUNT, which lets us count the number of results returned. If, for example, you wanted to find out how many jokes were stored in your table, you could use the following command:

SELECT COUNT(`id`) FROM `joke`

As you can see in the image below, you have just two jokes in your table:

The COUNT function counts the rows

Using * Instead

You can use COUNT(*) for the same result, but this is slower, as all the columns will be selected from the table. By using the primary key, only one column needs to be retrieved.

So far, the examples we’ve looked at have fetched all the entries in the table. However, you can limit your results to only those database entries that have the specific attributes you want. You set these restrictions by adding what’s called a WHERE clause to the SELECT command. Consider this example:

SELECT COUNT(*) FROM `joke` WHERE `jokedate` >= “2017-01-01”

This query will count the number of jokes that have dates greater than or equal to January 1, 2017. In the case of dates, “greater than or equal to” means “on or after”. Another variation on this theme lets you search for entries that contain a certain piece of text. Check out this query:

SELECT `joketext` FROM `joke` WHERE `joketext` LIKE “%programmer%”

This query displays the full text of all jokes containing the text “programmer” in their joketext column. The LIKE keyword tells MySQL that the named column must match the given pattern.2 In this case, the pattern we’ve used is “%programer%”. The % signs (called wildcards) indicate that the text “programmer” may be preceded and/or followed by any string of text. Conditions may also be combined in the WHERE clause to further restrict results. For example, to display knock-knock jokes from April 2017 only, you could use the following query:

SELECT `joketext` FROM `joke` WHERE

`joketext` LIKE “%knock%” AND

`jokedate` >= “2017-04-01” AND

`jokedate` < “2017-05-01”

Enter a few more jokes into the table. (For example, “Why did the programmer quit his job? He didn’t get arrays.”) Then experiment with SELECT queries . You can do a lot with the SELECT command, so I’d encourage you to become quite familiar with it. We’ll look at some of its more advanced features later, when we need them.

Modifying Stored Data

Having entered data into a database table, you might find that you’d like to change it. Whether you’re correcting a spelling mistake, or changing the date attached to a joke, such alterations are made using the UPDATE command. This command contains elements of the SELECT and INSERT commands, since the command both picks out entries for modification and sets column values. The general form of the UPDATE command is as follows:

UPDATE `tableName` SET

    `colName` = newValue, …

WHERE conditions

So, for example, if we wanted to change the date on the joke we entered earlier, we’d use the following command:

UPDATE `joke` SET `jokedate` = “2018-04-01” WHERE id = “1”

Here’s where that id column comes in handy, enabling you to easily single out a joke for changes. The WHERE clause used here works just as it did in the SELECT command. This next command, for example, changes the date of all entries that contain the word “programmer”:

UPDATE `joke` SET `jokedate` = “2018-04-01”

WHERE `joketext` LIKE “%programmer%”

WHERE is Optional

Believe it or not, the WHERE clause in the UPDATE command is optional. Consequently, you should be very careful when typing this command! If you leave the WHERE clause out, the UPDATE command will then apply to all entries in the table. The following command will set the date for all the records in the table!

UPDATE `joke` SET `jokedate` = “2018-04-01”

Deleting Stored Data

Deleting entries in SQL is dangerously easy, which you’ve probably noticed is a

recurring theme. Here’s the command syntax:

DELETE FROM `tableName` WHERE conditions

To delete all programmer jokes from your table, you’d use the following query:

DELETE FROM `joke` WHERE `joketext` LIKE “%programmer%”

Again, WHERE is Optional

As with UPDATE, the WHERE clause in the DELETE command is optional. Consequently, you should be very careful when using it. If you leave the WHERE clause out, the DELETE command will then apply to all entries in the table.The following command will empty the joke table in one fell swoop:

DELETE FROM `joke`

Let PHP Do the Typing

There’s a lot more to the MySQL database server software and SQL than the handful of basic commands I’ve presented here, but these commands are by far the most commonly used and useful! At this stage, you might be thinking that databases seem a little cumbersome. SQL can be tricky to type, as its commands tend to be long and verbose compared with those of other computer languages. You’re probably dreading the thought of typing in a complete library of jokes in the form of INSERT commands.

You’ll be surprised at how few SQL queries you actually type by hand. Generally, you’ll be writing PHP scripts that type your SQL for you. For example, if you want to be able to insert a bunch of jokes into your database, you’ll typically create a PHP script for adding jokes that includes the necessary INSERT query, with a placeholder for the joke text. You can then run that PHP script whenever you have jokes to add. The PHP script prompts you to enter your joke, then issues the appropriate INSERT query to your MySQL server. For now, however, it’s important to gain a good feel for typing SQL by hand. It will give you a strong sense of the inner workings of MySQL databases, and will make you appreciate all the more the work that PHP will save you!

To date, we’ve only worked with a single table, but to realize the true power of a relational database, you’ll need to learn how to use multiple tables together to represent potentially complex relationships between the items stored in your database.  In the meantime, we’ve accomplished our objective, and you can comfortably interact with MySQL using the MySQL Workbench query window. The fun continues as we delve into the PHP language, and use it to create several dynamically generated web pages. If you like, you can practice with MySQL a little before you move on, by creating a decent-sized joke table (for our purposes, five should be enough). This library of jokes will come in handy later.

This Is A Custom Widget

This Sliding Bar can be switched on or off in theme options, and can take any widget you throw at it or even fill it with your custom HTML Code. Its perfect for grabbing the attention of your viewers. Choose between 1, 2, 3 or 4 columns, set the background color, widget divider color, activate transparency, a top border or fully disable it on desktop and mobile.

This Is A Custom Widget

This Sliding Bar can be switched on or off in theme options, and can take any widget you throw at it or even fill it with your custom HTML Code. Its perfect for grabbing the attention of your viewers. Choose between 1, 2, 3 or 4 columns, set the background color, widget divider color, activate transparency, a top border or fully disable it on desktop and mobile.