Lesson Weekend

PHP has many functions built into it, but more often than not you will use these as building blocks for your own functions rather than simply on their own. Let's make a website that encrypts a secret message using a function to do the encoding.

For our encoding function, we need to think about three things: The name of the function. It's important to come up with names that make it easy to guess what the function will do. Let's call our function encode. A bad name might be enc - it's shorter, but if you don't already know what the function does, it's hard to guess its purpose. The input and output. It should take a string as an argument and return a new string. How it will work. Let's encrypt the input string by reversing it and then capitalizing it.

I'm going to jump ahead a couple steps and show you how I would write this encode function:

function encode($input_phrase) 
{
    $reversed_phrase = strrev($input_phrase);
    $capitalized_phrase = strtoupper($reversed_phrase);
    return $capitalized_phrase;
}

To call this function, I would simply run:

encode("my secret message");

Let's walk through the code defining the function step by step:

  1. The function keyword. This tells the PHP pastry chef that we're making a function - just like $ means "this is a variable".
  2. A name for our function. Just like variables, functions always need descriptive names. Function names should be in lower camel case, which means that names with multiple words should have the first letter of each word capitalized, except for the first one. Don't use underscores or spaces in function names. This makes it easy to see where you are using functions in your code. For example: function doImportantStuffWithSomeInput($input_argument)
  3. ( ) Parenthesis for any input arguments your function will receive. Our function needs a string to manipulate, so it will have one argument. The variable that accepts the argument is called a parameter. If you're confused about the difference between an argument and a parameter, in our above example, "my secret message" is the argument, and $input_phrase is the parameter. Since a parameter is just a different kind of variable, it uses a $ at the beginning of its name too. A parameter is a container for the value of an argument.
  4. { } Curly brackets starting on the next line. These show where your function begins and where it ends, just like opening and closing tags in HTML. All the code used to produce output from input in a function goes between the two curly brackets. This is also known as the body of a function - it does all the work.

Creating a function is also called declaring a function.

Now, let's use the function. First, we'll need a form to gather the user input. Create a file in your document root called "encrypt_form.html" and type this into it.

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <title>Encrypt a Message</title>
</head>
<body>
    <div class="container">
        <h1>Type in the secret message you would like to encode!</h1>
        <form action="encrypt.php">
            <div class="form-group">
                <label for="message">Message to encrypt</label>
                <input id="message" name="message" class="form-control" type="text">
            </div>
            <button type="submit" class="btn-success">Send</button>
        </form>
    </div>
</body>
</html>

Next, we'll need the PHP code to encrypt it. Create a file called encrypt.php in your document root folder and type this in:

<?php 
    $message_to_encode = $_GET["message"];
    $new_string = encode($message_to_encode);

    function encode($input_phrase)
    {
        $reversed_phrase = strrev($input_phrase);
        $capitalized_phrase = strtoupper($reversed_phrase);
        return $capitalized_phrase;
    }
?>
<!DOCTYPE html>
<html>
<head>
    <title>Encrypt a Message</title>
</head>
<body>
    <div class="container">
        <h1>Message encrypted!</h1>
        <h2>Here you go: <?php echo $new_string ?></h2>
    </div>
</body>
</html>

Incidentally, PHP doesn't care if you call your function before or after the declaration of the function. This is because all your code is read by the PHP interpreter before it is run. In other words, the PHP pastry chef always reads the recipe before starting to cook.

This is a silly website. There isn't very much code in our function. Couldn't I have just written it out, like this?

<?php 
    $input_phrase = $_GET["message"];
    $reversed_phrase = strrev($input_phrase);
    $new_string = strtoupper($reversed_phrase);
?>

Technically, yes... but what if we want to encode 3 different messages? Then you'll have to type those lines 3 times, once for each message:

<?php 
    $input_phrase1 = $_GET["message1"];
    $reversed_phrase = strrev($input_phrase1);
    $new_string = strtoupper($reversed_phrase1);

    $input_phrase2 = $_GET["message2"];
    $reversed_phrase = strrev($input_phrase2);
    $new_string = strtoupper($reversed_phrase2);

    $input_phrase3 = $_GET["message3"];
    $reversed_phrase = strrev($input_phrase3);
    $new_string = strtoupper($reversed_phrase3);
?>

When we wrap the behavior we want in a function, we can just call the function:

<?php 
    $message_to_encode1 = $_GET["message1"];
    $new_string1 = encode($message_to_encode);

    $message_to_encode2 = $_GET["message2"];
    $new_string3 = encode($message_to_encode2);

    $message_to_encode3 = $_GET["message3"];
    $new_string3 = encode($message_to_encode3);

    function encode($input_phrase)
    {
        $reversed_phrase = strrev($input_phrase);
        $capitalized_phrase = strtoupper($reversed_phrase);
        return $capitalized_phrase;
    }
?>

And what if we decide to change the method of encryption to change the words to lowercase instead of uppercase? You'll have to remember to fix that in 3 different places if we write it without a function:

<?php 
    $input_phrase1 = $_GET["message1"];
    $reversed_phrase = strrev($input_phrase1);
    $new_string = strtolower($reversed_phrase1);

    $input_phrase2 = $_GET["message2"];
    $reversed_phrase = strrev($input_phrase2);
    $new_string = strtolower($reversed_phrase2);

    $input_phrase3 = $_GET["message3"];
    $reversed_phrase = strrev($input_phrase3);
    $new_string = strtolower($reversed_phrase3);
?>

That's a lot of room for human error, and a lot of pointless extra work. With a function, we just change it in one place: inside the function declaration.

function encode($input_phrase)
{
    $reversed_phrase = strrev($input_phrase);
    $capitalized_phrase = strtolower($reversed_phrase);
    return $capitalized_phrase;
}

So whenever you notice that your code is performing a task more than once, see if you can wrap it up in a function.

Let's look at another example - we're going to expand our shipping calculator to use a function. First, here's our form, allowing the user to enter a value for the weight of the package, and the distance it is being shipped.

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <title>Shipping Calculator</title>
</head>
<body>
    <div class="container">
        <h1>We just need some information about your package... </h1>
        <form action="shipping_calculator.php">
            <div class="form-group">
                <label for="weight">Weight (lbs)</label>
                <input id="weight" name="weight" class="form-control" type="number">
            </div>
            <div class="form-group">
                <label for="distance">Distance (miles)</label>
                <input id="distance" name="distance" class="form-control" type="number">
            </div>
            <button type="submit" class="btn-success">Submit</button>
        </form>
    </div>
</body>
</html>

Now let's make shipping_calculator.php. Our function should take two arguments as input - the weight and distance. Then our function should return one value - a number representing the price of shipping, which we will display in our HTML. Let's call our function calculateShipping and let's say that we want to divide both values by 20 and then add the results. Our function declaration should look like this:

function calculateShipping($weight, $distance)
{
    $price = ($weight / 20) + ($distance / 20);
    return $price;   
}

Now let's add in the rest of the HTML, and get the distance and weight values out of our form to use them with our new function. It should look like this:

<?php 
    $input_weight = $_GET["weight"];
    $input_distance = $_GET["distance"];
    $shipping_price = calculateShipping($input_weight, $input_distance);

    function calculateShipping($weight, $distance)
    {
        $price = $weight / 20 + $distance / 20;      
        return $price;   
    }
?>
<!DOCTYPE html>
<html>
<head>
    <title>Shipping Calculator</title>
</head>
<body>
    <div class="container">
        <h1>Price Calculated!</h1>
        <h3>Your package weighs: <?php echo $input_weight . " lbs"; ?> </h3>
        <h3>Your package is traveling: <?php echo $input_distance . " miles"; ?> </h3>
        <h3>The cost will be: $<?php echo $shipping_price; ?> </h3>
    </div>
</body>
</html>

Try out some values in the form and make sure that it does what you expect when you submit it.

Lastly, an important stylistic note about spacing. Just like we indent the code between the <?php ?> tags by 4 spaces, we also need to indent all of the code inside of the body of our functions (between the curly brackets) by 4 spaces.