Back to top

PHP

Online Resources

W3Schools: PHP Tutorial

PHP Coding Style Guide - 1

PHP Coding Style Guide - 12

Setting Up a Development Server

First, to run PHP files, you need to run them through a server. It is best to work with a development server while you are still working on your site so that you do not need to worry about what the public can see during that time.

AMPPS (available for Windows or Mac)

Accessing the Document Root (macOS)

View Your PHP Files on Your Computer

Basic Syntax

Semicolons

All PHP statements must end with a semicolon, or it will give an error. If you forget one, it treats multiple statements like one statement, which then throws a Parse error.

$ Symbol

In PHP the $ symbol must be placed in front of all variables (no spaces).

Examples

Line Break

To execute a line break in PHP, you will use "\n"

Concatination

To concatenate (join) multiple strings together you use a period in between them

Example:

Interpolation

To interpolate (join) a string with a variable together you can include them inside double quotes

Example:

Variables

Variable-Naming Rules

  1. Variable names, after the dollar sign, must start with a letter or the _ (underscore)
  2. They can contain only the characters a-z, A-Z, 0-9, and _ (underscore) (No hyphens allowed)
  3. They may not contain spaces. Use an underscore to separate words if name has multiple words ($snake_case)
  4. They are case sensitive. The variable $My_score is not the same as $my_score.
  5. As always, use logical variable names

Strings

Strings must be enclosed with quotation marks or single quotes. There is a slight difference between the two.

  1. Single Quotes - Literal String (preserving the exact content)
  2. Double Quotes - Utilizes Variable Interpolation

Single Quotes - Example of Literal String:

Double Quotes - Example of Variable Interpolation:

Numeric Values

Variables can contain integers (positive or negative whole numbers) or floating-point numbers (positive or negative numbers containing a decimal point).

Booleans - Null

You can set a boolean value to true or false.

Null values are null if no value has been added to a variable, or if it has been assigned null.

Constants

A constant is a variable that cannot change

It is case sensitive and written in ALL CAPS by convention

Arrays

W3Schools: Array Reference

Arrays

W3Schools: PHP Arrays

Arrays store one or multiple values within one variable.

There are two ways to create an array in PHP:

  1. Use square brackets with a list of values separated with commas (like JavaScript).
    • $articles = [
        "First post",
        "Another post",
        "Read this!"
      ];
  2. Use the array() function. This one uses parentheses instead of square brackets. You will still separate your list of values with commas.
    • $paints = array (
        "oil",
        "acrylic",
        "watercolor",
        "tempera"
      );

Call them using their index/key [0, 1, 2, etc] in square brackets following the variable name:

Add Item to End of Array

To add an item to the end of an array, list the name of the array with empty square brackets = the item you want to add in quotes.

Example:

Remove Item from Array

Use the unset command, name of the array, and position.

Example:

Manually assign Indexes

  • Initiate an array
  • Inside brackets you assign an index with a number
  • Then add equals sign and greater than sign and then the value
  • You don't have to assign an index to every value. Any value not assigned an index will be given an index automatically, continuing from the previous one.
  • Example:

    Associative Arrays

    W3Schools: Associative Arrays

    These allow you to give a custom name using a string to the index/key, rather than just using a number.

    1. Initiate an array
    2. Inside you assign an index with a string (word in quotes)
    3. Then add equals sign and greater than sign and then the value
    4. You don't have to assign an index to every value. Any not assigned an index will be given an index automatically, continuing from the previous one.

    Example:

    Display specific info from array:

    Multi-Dimensional Arrays

    W3Schools: PHP Multidimensional Arrays

    An array containing one or more arrays

    To access $alice_email from the array:

    If / Else / Elseif Statements

    If / Else statements syntax:

    Else if statements syntax:

    If / Else Example:

    Elseif Example:

    While Loop

    While loops are the simplest type of loop in PHP. A while loop tells PHP to execute the nested statement(s) repeatedly, as long as the while expression evaluates to true.

    Syntax:

    Example:

    For Loop

    Use a for loop to run code a specific number of times

    Syntax:

    Example:

    Foreach Loop (Through an Array)

    Foreach Loop - Return Value Only

    Easier than the For Loop!

    Use a foreach loop to loop through a key/value pair in an array

    Syntax:

    Example:

    Foreach Loop - Return Value and Index Position

    Switch Statements

    php.net: PHP Swtich Statement

    W3School: PHP Switch Statement

    The switch statement is similar to a series of if statements on the same expression.

    In many different situations you may want to compare the same variable (or expression) with many different values, and execute a different piece of code depending on which value it equals. This is exactly what a switch statement is for.

    You can list two cases in a row if they have the same output

    default statement is in case there is no match to switch statement

    break is used to stop the statement from continuing to run

    If you intentially do not want a break, comment out no break where the break would have been

    Syntax

    Example:

    Do While Loop

    The Do While loop is kind of like the While loop, but there's one major difference: The While loop will only start if the condition is true; whereas the Do While loop will always execute the first time, and then evaluate whether the condition is true afterwards.

    Syntax:

    • do {
    •  // execute this code
    • } while (condition to be met);

    Example:

    • $i = 1;
    • do {
    •  echo "Number: $i < br>";
    •  $i++;
    • } (Then evaluate this condition and loop if True)
    •   while ($i <=10);

    Common PHP Functions

    PHP has hundreds of built in functions. You can find a list of all of them on php.net.

    print_r()

    Print results of an array on the screen

    echo $my_array does not work in PHP. Instead, you need to use print_r (human readable)

    Example:

    • $paints = array("oil", "acrylic", "watercolor", "tempera");
    • print_r($paints);
      • → Array ( [0] => oil [1] => acrylic [2] => watercolor [3] => tempera )

    sizeof() / count()

    Both functions return the number of elements in an array.

    • $cars = array("Volvo", "BMW", "Toyota");
    • echo count($cars);
      • → 3

    var_dump()

    This function can be used to see what a variable contains by having it print it on the screen

    You can pass multiple variables at once by separating them with a comma

    • $message = "Hello";
    • var_dump($message);
      • → string(5)"Hello"

    sort() / rsort()

    sort() - Alphabetical sort of an array

    rsort() - Reverse alphabetical sort of an array

    First, create an array

    • $dinner = array("Meat", "Potatoes", "Beans", "Rice");

    Then add the array as a parameter to sort() function

    • sort($dinner);

    Echo the array with a foreach loop

    • foreach($dinner as $ingredients) {
    •  echo "$ingredients< br>";
    • }
      • → Beans
      • → Meat
      • → Potatoes
      • → Rice

    strtolower()

    Change all text to lowercase

    • $dinner = array("Meat", "Potatoes", "Beans", "Rice");

    No separate line to call here

    Echo the array with a foreach loop

    • foreach($dinner as $ingredients) {
    •  echo strtolower($ingredients)."< br>";
    • }
      • → beans
      • → meat
      • → potatoes
      • → rice

    Mixing HTML and PHP

    • Save file as .php
    • PHP needs opening and closing tags when mixing with HTML
      • <h1>Mixing it Up!</h1>
      • <p>Hello. <?php echo "Katie"; ?>!</p>

    Shortcut echo tag

    • Instead of: <?php echo ?>
    • Use <?= (put whatever you want here) ?>

    PHP Control Structure Mixed with HTML

    This way you can have HTML inside a PHP control structure

    Replace opening brace with colon, replace closing brace with endif (endfor, etc)

    • HTML: <h1>Heading< /h1>
    • PHP: <?php if (condition): ?>
    • HTML: <p>...< /p>
    • PHP: <?php endif; ?>
    • HTML: <p>more HTML< /p>

    Example:

    (First three lines of code would be placed above the < !DOCTYPE html>)

    • <?php
    • $hour = 14;
    • ?>

    Rest of the code is set within the body of the HTML

    • <?php if ($hour < 12): ?>
    •  Good morning
    • <?php elseif ($hour < 18): ?>
    •  Good afternoon
    • <?php elseif ($hour < 22): ?>
    •  Good evening
    • <?php else: ?>
    •  Good night
    • <?php endif; ?>

    HTML Forms with PHP in General

    To add a form to a webpage, we use <form> element. Inside the <form> we place controls such as <button> , text boxes, etc.

    Add action attribute to tell server where to send the information submitted through the form

    • <form action="process_form.php">

    Example:

    • <body>
    •  <form action="process_form.php">
    •   <input name="search">
    •   <button>Send</button>
    •  </form>
    • </body>

    We can access the query string by using a GET array (in file: process_form.php)

    • <?php
    • var_dump($_GET);
    • Using this array, we can access the data that was entered into the form

    If no action attribute was added, then form will be submitted to itself. This could be useful if you want your user to review the information on the screen before submitting.

    Basic Input Types of HTML Forms

    • An input element with no type specified is a simple text box
    • You can add a type= element to change what type of input is shown
    • If you don't specify anything, or specify type=, then you get a single line text field
      • Type in the box below to test it out
      • <form method="">
      •  <input name="user">
      • </form>
    • If you specify type=password you will get a one-line plain text where text is obscured with a * or .
      • Type in the box below to test it out
      • <form method="">
      •  <input id="userPassword" type="password">
      • </form>
    • If you specify type="number" it will add controls on the side to click to increase or decrease the number
      • Use the box below to test it out
      • <form method="">
      •  <input type="number">
      • </form>
    • Mobile: Some types change on mobile devices

    GET & POST Variables

    W3Schools: PHP Superglobal = $_GET

    W3Schools: PHP Superglobal = $_POST

     GET vs. POST   GET   POST 
     bookmarkable?   yes   no 
     sensitive data?   no   yes 
     size limit?   yes, 3000 char.   no 

    $_GET

    $_GET is a PHP super global variable which is used to collect data after submitting an HTML form with method="get". This is the default and sends data in the query string making it less secure.

    → Tip: Use $_GET for search results

    PHP options:

    • <?php
    • echo $_GET["name"]; (OR) print_r($_GET);
    • ?>

    Or send message to someone with their name from form:

    • <?php
    • echo "Hi there, " . $_GET["name"] ."!";
    • ?>

    $_GET - Data Sent in URL

    If you have a hyperlink with parameters, i.e.:

    • <a href="test_get.php?subject=PHP&web=W3schools.com">Test $GET</a>
    • Starts with a ?
    • Parameter has a name and it equals something. (subject=PHP)
    • Multiple parameters are separated with & (no spaces) (?subject=PHP&web=W3schools.com)

    When a user clicks on the link "Test $GET", the parameters "subject" and "web" are sent to "test_get.php", and you can then access their values in "test_get.php" with $_GET.

    • <?php
      echo "Study " . $_GET['subject'] . " at " . $_GET['web'];
      ?>
    • → Study PHP at W3schools.com

    $_POST

    $_POST is also a PHP super global variable which is used to collect form data after submitting an HTML form with method="post". This sends data separately from the query string. This would be used for sensitive data such as username, password, etc.

    → Tip: Use $_POST for changing data on server - inserting, updating, or deleting

    Example:

    • <body>
    •  <form method="post">
    •   <input name="username">
    •   <input name="password" type="password">
    •   <button>Send</button>
    •  </form>
    • </body>

    → Tip: Add var_dump($_POST); to top of page (inside php brackets) with form. This will display data submitted in form at top of screen on page reload after clicking submit.

    Example:

    • <?php
    • var_dump($_POST);
    • ?>

    REQUEST_METHOD

    You can check to see which method a form used when it was submitted by checking the REQUEST_METHOD (which request method was used to access the page, ie. 'GET', 'HEAD', 'POST', 'PUT'.)

    You can use this following code to only print out the array if the form was submitted

    • <?php
    • if ($_SERVER["REQUEST_METHOD"]=="POST") {
    •  var_dump($_POST);
    • }
    • ?>

    Access Data from a Form on the Server

    • An input needs a name= so it can be used as the index for the GET or POST array. Make the name logical, lowercase, and no spaces. Each name in the form needs to be unique.
    • You can use value="#" on any field and it will be included in both GET or POST arrays. This provides a default value in a field, and will be submitted if not changed.
    • Use type="hidden" name="invisible" when you want data sent with the form, but the user doesn't need to see it. Since you cannot type in this field, you also have to add value="#" atttribute. But, if you view the source you can see the value="#", so don't use it for sensitive information.

    Three types of input where no value can be entered:

    1. <input type="image" - Elements do not accept value attributes. For example, Submit buttons that are an image rather than text.
    2. <input type="button" - Simple buttons. Can be custom when assigned an event handler function (ie - click event). This can also include HTML inside the area of the clickable button.
    3. <input type="submit" - If you add value=" " it will be used as button label. However, <button> element is preferred for submit button. If cursor is in a text field and user presses Enter, form will be submitted.

    Create a New Page To Insert New Articles

    Example:

    New Article


    Code:

    • <?php if($_SERVER['REQUEST_METHOD'] == "POST") {
       var_dump($_POST);
      }
      ?>
      <?php require 'includes/header.php'; ?>
      <h2>New Article</h2>
       <form method="post">
        <div>
         <label for="title">Title</label>
         <input name="title" id="title" placeholder="Article Title">
        </div>
        <div>
         <label for="content">Content</label>
         <textarea name="content" rows="4" cols="40" id="content"
      placeholder="Article content"></textarea>
        </div>
        <div>
         <label for="published_at">Publication date and time</label>
         <input type="datetime-local" name="published_at" id="published_at">
        </div>
        <button>Add</button>
       </form>
      <?php require 'includes/footer.php'; ?>

    Insert New Article & Get the ID of the New Record

    • Replace the var_dump statement from above with following code
    • Took the $sql and if/else statement from article.php and adapted it for this purpose
    • Under else statement: take out mysqli_fetch_assoc and replace with mysqli_insert_id to get automatically assigned id

    mysqli_insert_id

    mysqli_insert_id returns the auto-generated id used in the last query

    Example:

    • <?php
      if($_SERVER['REQUEST_METHOD'] == "POST") {
       require 'includes/database.php';
       $sql = "INSERT INTO article (title, content, published_at)
         VALUES (' ".$_POST['title']." ',
             ' ".$_POST['content']." ',
             ' ".$_POST['published_at']." ')";
       $results = mysqli_query($conn, $sql);
       if($results === false) {
        echo mysqli_error($conn);
       } else {
        $id = mysqli_insert_id($conn);
        echo "Inserted record with ID: $id";
       }
      }

    How SQL Injection Attacks Work

    Here is the SQL statement in our code:

    •  $sql = "INSERT INTO article (title, content, published_at)
         VALUES (' ".$_POST['title']." ',
             ' ".$_POST['content']." ',
             ' ".$_POST['published_at']." ')";

    This is the value typed into title column of form...

    • ', (SELECT password FROM user WHERE user='root' LIMIT 1),' '), ('

    This is the resulting SQL string...

    • INSERT INTO article (title, content, published_at)
    • VALUES (' ', (SELECT password, FROM user, WHERE user='root' LIMIT 1), ' '), (' ',' ',' ')

    What does it mean?

    • It posts a new article to the blog index page with the password as the title and the rest is blank
    • No need for PHPmyadmin to get password
    • The hashed password they get can be put into many different crack sql password generators to get the real password used

    Avoid SQL Injection: Escape Input

    mysqli_real_escape_string

    The mysqli_real_escape_string - escapes special characters in a string for user in an SQL statement, taking into acount the current charset to the connection

    Can also use mysqli_escape_string

    How does it work?

    • Wrap the VALUES statements with escape string
    • Need to pass in the database connection variable because it takes into account the charset setting
    • This technique is god for short SQL statements, but could get messy for more complicated situations (reference prepared statements)
    •  $sql = "INSERT INTO article (title, content, published_at)
         VALUES (' ".mysqli_escape_string($conn, $_POST['title']." ',
             ' ".mysqli_escape_string($conn, $_POST['content']." ',
             ' ".mysqli_escape_string($conn, $_POST['published_at']." ')";

    (This code would be used in the new-article.php file)

    Avoid SQL Injection: Prepared Statements

    Prepared Statements

    (This code would be used in the new-article.php file)

    This is used to execute the same statement repeatedly with high efficiency.

    It consists of two stages:

    1. Prepare - a statement template is sent to the database server
      • Write a SQL statement with placeholders
    2. Execute - the server preforms a syntax check and initializes server internal serources for later use
      • Bind data to the placeholders and send them to the server.
      • The server creates a statement from the statement template and the bound values.
      • To execute it it uses the previously created internal resources

    Repeated Execution:

    • A prepared statement can be executed repeatedly
    • Upon every execution the current value of the bound variable is evaluated and sent to the server
    • The statement is not passed again
    • The statement template is not transferred to the server again

    Step 1 - Prepare

    • $sql = "INSERT INTO article (title, content, published_at)
    •    VALUES (?, ?, ?)";

    Then, instead of this...

    • $results = mysqli_query($conn, $sql);

    Use...

    mysqli_prepare

    PHP.net - mysqli_prepare

    • $stmt = mysqli_prepare($conn, $sql);
    • if ($stmt === false) {
    •  echo mysqli_error($conn);

    Next...

    mysqli_stmt_bind_param

    PHP.net - mysqli_stmt_bind_param

    • } else {
    •  mysqli_stmt_bind_param($stmt, "sss", $_POST['title'], $_POST['content']), $_POST['published_at'];

    Then...

    mysqli_stmt_execute()

    PHP.net - mysqli_stmt_execute

    • if (mysqli_stmt_execute($stmt)) {
    • $id = mysqli_insert_id($conn);
    • echo "Inserted record with ID: $id";
    • } else {
    •  echo mysqli_stmt_error($stmt);
    •  }
    • }

    Create a PHP Function to Connect to the Database

    Inside file new-article.php, move require 'includes/database.php'; it above the if statement.

    • We don't need to connect to the database when the page is first accessed, only when the form is submitted.
    • We also have a problem because we declared a variable ($conn) in the database file, but then use that variable on the new-article.php page. This is bad because you don't know where the variable came from on the new-article.php page.
    • We can solve both these problems by creating a function.

    In the database.php file, wrap all of the code inside of a function.

    • function getDB() {}

    In the new-article.php file, call the function just below the first if statement.

    • getDB()

    We still have a problem because the $conn variable was declared inside a function, and its use is limited to inside of that function. We can fix this by returning the value of the variable on the database.php file inside of the function:

    • In database.php file: Below the if statement, but before the last closing bracket, return $conn;.
    • Then, in the new-article.php file, before calling the function, assign the returned value to a variable, $conn = getDB();.

    Now that we've changed the database.php include, we've broken our existing pages.

    • At the top of index.php and article.php add the $conn = getDB(); below the require statement.

    Return a Value

    To return a value, it sends a value back from a function or included file. Sof if you have a function like this:

    • function getMessage() {
    •  $message = "Hello";
    • }

    When you call this function, there's no way to get the value of $message from outside the function:

    • getMessage();

    To do this, you need to use return inside the function:

    • function getMessage() {
    •  $message = "Hello";
    • return $message;
    • }

    Then when you call the function, you can use its return value:

    • $return_value = getMessage();

    → Return value will equal "Hello"

    As for included files, if you just include or require a file (ie - file called example.php)

    • $data = [1,2,3];

    And then you included it in another file:

    • require "example.php";

    Then this file is included into the script as though you'd copied and pasted its contents into the calling script.

    If you want, you can return a value from the included file by putting a return at the end, just like in a function:

    • $data = [1,2,3];
    • return $data;

    Then you can get that value in the same way when you include it:

    • $data = require("example.php");

    Basically, return is used to pass a value back to calling code.

    Validate Form Data & Redisplay Form with Error Messages

    Before we enter a new entry in the database, you should validate the data in the form. It should be done once the form has been submitted, but before we build the $sql statement.

    • This will be done in the new-article.php file, just below the if statement, but above the $conn variable.

    It is possible that the user will have more than one error. Create a variable to hold the error messages. Set its initial value to an empty array.

    • $errors = [];

    Start by checking that the title is not blank. It is best to redisplay the form along with the error message so that the user can correct the errors.

    • if ($_POST['title'] == '') {
    •  $errors[] = 'Title is required';
    • }

    Also check to see if the content is blank.

    • if ($_POST['content'] == '') {
    •  $errors[] = 'Content is required';
    • }

    Then to test it, you need to print out the array to see the error messages, and then exit the script.

    • var_dump($errors); exit;

    Once you know it is working, change the var_dump to check to see if the $errors array is empty. If it is empty the script should continue. Need to wrap the entire rest of the code in that block with the following if statement. The closing bracket should be second level from the bottom.

    • if (empty($errors)) {}

    Next, in the HTML you will add to display the errors. Just to test that our code is working - under the h2 heading, add:

    • <?php var_dump($errors); ?>

    This will cause an error because the $errors variable was initialized inside the if block at the top. To correct this error, move the $errors = []; just above the if statement, but below the require statement.

    We don't just want the var_dump at the top of the form, so now change it to the following. This will check to see if there are any errors. If there are, it will loop around and display any error messages as an unordered list.

    • <?php if (! empty($errors)): ?>
    •  <ul>
    •   <?php foreach ($errors as $error): ?>
    •    <li>?= $error ?></li>
    •   <?php endforeach; ?>
    •  </ul>
    • <?php endif; ?>

    We could have added the required attributes inside the form in the HTML, but these can be bypassed.

    You should always validate data on both the server-side and client-side every time new data is being submitted from a website.

    Maintain Form Data When Redisplaying Invalid Form

    For this section we are accessing the new-article.php

    Set the value attribute of the title input to the variable $title

    • <input name='title' id='title' placeholder='Article title' value="<?= $title; ?>">

    Then, if the form is submitted, assign the value of the title field to the variable $title. Add this just under the if statement at the top, but above the if statement that checks to see if the title field is empty.

    • $title = $_POST['title'];

    Also need to initialize the $title variable outside of the if block, so add the following above the if statement:

    • $title = '';

    Now the same needs to be done for the other two controls:

    Add the value to each appropriate input:

    • <input type="text" name="published_at" id="published_at" value="<?= $published_at; ?>">
    • <textarea name="content" rows="4" cols="40" id="content" placeholder="Article content"><?= $content; ?></textarea>
    • Notice, the textarea field is different. No value=, and goes in between the opening and closing tags.

    Initiate the variables at the top:

    • $content = '';
    • $published_at = '';

    Add the post statements to fill in the blanks with what was there before if there are errors:

    • $content = $_POST['content'];
    • $published_at = $_POST['published_at'];

    Now to clean up the code, replace the global variables ($_POST['title'], etc. with the new variables just created.

    • At top where you are checking to see if the field is empty, replace:
    • if ($_POST['content'] == '') {

    • if ($content == '') {
    • And the same for title at the top
    • Also change the binding statement a little further down the page:
    • mysqli_stmt_bind_param($stmt, "sss", $_POST['title'], $_POST['content'], $_POST['published_at']);
    • mysqli_stmt_bind_param($stmt, "sss", $title, $content, $published_at);

    Avoid Cross-Site Scripting (XSS) Attacks: Escape Untrusted Content

    htmlspecialchars() - converts special characters to HTML entities

    • For example, < would be converted into ampersand(&)lt;

    Following changes should be applied to new-article.php

    In HTML where we just added new PHP code, we need to add this new htmlspecialchars

    • <input...value="<?=htmlspecialchars($title); ?>
    • <textarea...<?=htmlspecialchars($content); ?>
    • <input...value="<?=htmlspecialchars($published_at); ?>

    Following changes should be applied to index.php

    • <h2><a href="article.php?id=<?=$article['id']; ?>"><?=htmlspecialchars($article['title']); ?></a></h2>
    • <p><?=htmlspecialchars($article['content']); ?></p>

    Following changes should be applied to article.php

    • <article>
       <h2><?= htmlspecialchars($article['title']); ?></h2>
       <p><?= htmlspecialchars($article['content']); ?></p>
      </article>

    Insert NULL if the Publication Date is Empty

    Following changes should be applied to new-article.php

    Inside the else statement, right before mysqli_stmt_bind_param, add:

    • if ($published_at == '') {
    •  $published_at = null;
    • }

    Dates in PHP

    • <?php $now=date('Y-m-d H:i:s');
      $query='INSERT INTO chat SET user="hello",chat_date="'.mysqli_escape_string($now).'"';
      ?>

    W3Schools: PHP date() Function

    • D = 3 letter abbreviation of day of week
      • → Mon through Sun
    • j = date without leading zeros
      • → 1 - 31
    • F = full month written out
      • → January, December
    • M = 3 letter abbreviation of month
      • → Jan, Dec
    • Y = 4 digit year
      • → 2020

    Redirect to the Article Page After Inserting a New Article

    header - send a raw HTTP header

    Following changes apply to new-article.php

    Inside if statement of mysqli_stmt_bind_param:

    • if(mysqli_stmt_execute($stmt)) {
    •  $id = mysqli_insert_id($conn);
    • (delete echo "Inserted record with ID")
    • header("Location: article.php?id=$id");
    • exit;

    → This is redirecting to a relative url and will work in modern browers, but not old ones. Instead, use an absolute url.

    $_SERVER - server and execution environment information

    Instead of hardcoding your server information, you can get it using the superglobal $_SERVER

    Insert the following code just below $id = mysqli_insert_id($conn);

    • if (isset($_SERVER['HTTPS'] && $_SERVER['HTTPS'] != 'off') {
    •  $protocol = "https";
    • } else {
    •  $protocol = "http";
    • }

    Next, you can get the server name using the $_SERVER['HTTP_HOST']

    • header("Location: $protocol://".$_SERVER['HTTP_HOST']."/CompleteWebDev/php/article.php?id=$id");
    • exit;

    Following change on index.php

    Add a link on index page to add a new article. Place it underneath: require 'includes/header...';

    • <a href = "new-article.php">Add new blog post</a>

    Edit Existing Articles

    Create a Function to Get a Single Article

    • We already have a $sql statement in article.php requesting a particular article by its id. Instead of repeating that code again in edit-article.php, we will write a function that we can then use in both files. We will write this function in a new file called article-functions.php (in the includes folder)

    Create new file: edit-article.php

    Create new file in includes folder: article-functions.php

    Following code in article-functions.php

    • <?php
    • function getArticle($conn, $id) {
    •  $sql = "SELECT * FROM article WHERE id = ?";
    •  $stmt = mysqli_prepare($conn, $sql);
    •  if ($stmt === false) {
    •   echo mysqli_error($conn);
    •  } else {
    •   mysqli_stmt_bind_param($stmt, "i", $id);
    •   if (mysqli_stmt_execute($stmt)) {
    •    $result = mysqli_stmt_get_result($stmt);
    •    return mysqli_fetch_array($result, MYSQLI_ASSOC);
    •   }
    •  }
    • }

    mysqli_fetch_array

    mysqli_fetch_array - fetch a result row as an associative aaray, a numeric array, or both.

    • By default you get an array with both numberic and string indexes mysqli_fetch_array($result)
    • But if we add a 2nd argument to this, we only get an associative array mysqli_fetch_array($result, MYSQLI_ASSOC);

    Add a PHP doc comment block at top of article-functions.php

    • /**
    • * @param object $conn - Connection to the database
    • * @param integer $id - The article id
    • *
    • * @return mixed - An associative array containing
    • * the article with that ID, or null if not found
    • */

    Following code in article.php

    Add require statement at top:

    • require 'includes/article-functions.php';

    Delete code:

    • from... $sql = "SELECT... through $article = mysqli_fetch_assoc...}

    Replace with a call to the new function:

    • $article = getArticle($conn, $_GET['id'];

    Since we are now using a prepared statement in our new article-functions.php, we can delete our check to see if the id is numberic. This prepared statement will protect us from SQL injection. Delete:

    • && is_numeric($_GET['id'])

    Now copy code from article.php and paste into edit-article.php

    • Copy from top at <?php through require statements, $conn, and if/else statement

    Add a Form for Editing an Existing Article

    • We have already created a form in the new-article.php file. We'll extract it into it's own file and then we can use it in both the new-article.php file and the edit-article.php file.

    Create new file in includes folder: article-form.php

    Copy code from new-article.php and paste into article-form.php

    • Copy from <?php if(!empty... until end of form </form>
    • After pasted in, change button text from Add to Save

    Once pasted into new file, delete form in new-article.php, and replace with:

    • <?php require 'includes/article-form.php'; ?>

    Copy lines of code from new-article.php and paste at end of edit-article.php

    • Cut from...
    • <?php require 'includes/header...
    • through
    • <?php require 'includes/footer...

    Once pasted at end of edit-article.php, Change <h2 to:

    • <h2>Edit Article</h2>

    Add to edit-article.php under $article = getArticle:

    • $title = $article['title'];
    • $content = $article['content'];
    • $published_at = $article['published_at'];

    Edit-article.php - add checks to see if id that is passed is valid, and if not show error message and stop script.

    • Under: } else { remove $article = null; and replace with die ("id not supplied, article not found");

    Continue on edit-article.php. Above $title = $article... add:

    • if(article) {

    Under $published_at = $article ['published_at']; add:

    • } else {
    •  die ("article not found");
    • }

    Add a Validation Function & Validate the Form Data

    Create a function to validate an article so that it can be used in both new-article.php and the edit-article.php forms.

    Start by creating new function in article-functions.php

    • function validateArticles ($title, $content, $published_at) {

    Then go to new-article.php and copy validation code:

    • from: if ($title == '') {
    • through: $errors[] = 'Invalid date and time'; }}}

    Paste it in new function.

    After pasting:

    • The errors array may or may not exist, but it's being used in the function. Declare it as first line of function just to be sure.
    • $errors = [];
    • At end of function, return the variable:
    • return $errors; }

    Add php doc comment above function:

    • /**
      * Validate the article properties
      *
      * @param string $title Title, required
      * @param string $content Contente, required
      * @param string $published_at Published date and time, yyyy-mm-dd hh:mm:ss if not blank
      *
      * @return array An array of validation error messages
      */

    Following code in new-article.php

    Add require statement at top (under other require statement)

    • require 'includes/article-functions.php';

    Replace validation code in new-article.php with call to new function:

    • $errors = validateArticles($title, $content, $published_at);

    Now we can use some of that code from new-article.php in edit-article.php. Paste under die ("id not supplied... }

    • Copy from new-article.php:
    • if($_SERVER["REQUEST_METHOD"]...
    • through...
    • if(empty($errors)) {
    • add to bottom of snippet...
    •   die("Form is valid");

    •  }

    • }

    Delete following code in new-article.php

    • Delete $errors = []; at top

    Change Existing Data in the Database: SQL UPDATE Statement

    SQL UPDATE statement

    Example:

    • UPDATE table_name
    • SET column1 = value1,
    •   column2 = value2
    • WHERE condition;

    Example: (update title for article with id=6)

    This code would be used in the Query tab of Sequel Pro

    • UPDATE article
    • SET title = "Updated Title""
    • WHERE id=6;

    IMPORTANT: If you don't include a WHERE clause, every single row in the table will be updated

    Note: Any columns used in the WHERE clause should be indexed, or they could take a long time to execute

    Update an Existing Article in the Database using PHP

    Copy from new-article.php:

    • from...
    • $conn = getDB()
    • through...
    •  echo mysqli_stmt_error($stmt);
    •  }
    • }

    Paste into edit-article.php:

    • Paste under...
    • if(empty($errors)) {
    • After pasting, delete...
    • die("Form is valid");

    Delete from edit-article.php. It is in the pasted section already at the top of the file right about the $sql = statement.

    • $conn = getDB()

    Change INSERT statement to UPDATE in edit-article.php

    • $sql = "UPDATE article
    •   SET title = ?,
    •    content = ?,
    •    published_at = ?,
    •   WHERE id = ?";

    Add: (edit-article.php at top)

    • Add under...if ($article) {
    • $id = $article['id'];

    Add $id to bind_param function call, and add i for integer:

    • mysqli_stmt_bind_param($stmt, "sssi", $title, $content, $published_at, $id);

    Since we're updating and not inserting, delete:

    • $id = mysqli_insert_id($conn);

    Following change to article.php:

    Add a link back to edit-article.php page after data has been displayed.

    • Under <article></article> section:
    • <a href="edit-article.php?id=<?= $article['id']; ?>">Edit</a>

    Create a Function to Redirect to Another URL

    Create a new file in includes folder: url-redirect.php

    Create new function in url-redirect

    • <?php
    • function redirect($path) {
    • }

    Copy from new-article.php:

    • Copy from...
    • if (isset)$_SERVER['HTTPS'])
    • Through...
    • header...exit;

    Paste inside new function in url-redirect.php

    Delete following code:

    • "/php/article.php?id=$id");

    And replace with:

    • $path);

    Add a php doc comment block above new function:

    • /**
    • * Redirect to another URL on the same site
    • *
    • * @param string $path The path to redirect to
    • *
    • * @return void
    • */

    In both edit-article.php and new-article.php, add require statement:

    • require 'includes/url-redirect.php';

    Replace code from both edit-article.php and new-article.php (The same code that was copied to the new function) with a call to the new function:

    • redirect("/php/article.php?id=$id");
    • redirect("/CompleteWebDev/php/article.php?id=$id");

    Stopped at end of Section 13. Some problem after editing article, does not accept changes nor redirect to article page.

    Coding Challenges

    Is this number Prime?

    Using an input box allow a user to enter any whole number, and use PHP to determine if it is prime. Display answer on page.


    • <h1>Prime Number?< /h1>
      <p>Enter any whole number and click 'Calculate' to find out if the number is prime.< /p>
      <form>
       < input type="text" name="number">
       < input type="submit" value="Calculate" name="">
      </form>
      <?php
      if ($_GET) {
       $i=2;
       $isPrime = true;
       while ($i < $_GET['number']) {
        if ($_GET['number'] % $i == 0) {
        //Number is not prime!
        $isPrime = false;
        }
        $i++;
       }
       if ($isPrime) {
        echo "< h2>" . $i . " is a prime number!";
       } else {
        echo "< p>" . $i . " is not a prime number.";
       }
      }
      ?>


    Create five variables and assign a value to each one

    • A variable called name, with a string value of your name.
    • A variable called age, with an integer value.
    • A variable called status, with a boolean value.
    • A variable called new_age, that contains the result of adding 10 to the contents of the age variable above.
    • A variable called sentence, that contains the contents of the name variable above, with the following string appended to the end: " knows PHP!". You can concatenate the strings together, or use variable interpolation.

    • $name = "Katie";
    • $age = 29;
    • $status = true;
    • $new_age = $age + 10;
    • $sentence = "$name knows PHP!";
    • → Katie
    • → 29
    • → true
    • → 39
    • → Katie knows PHP!


    Use a for loop to loop through an array and print each one on the page


    • $family = array("Rob", "Kirsten", "Tommy", "Ralphie");
    • for ($i = 0; $i < sizeof($family); $i++) {
    •  echo $family[$i]."< br>";
    • }
      • → Rob.
      • → Kirsten.
      • → Tommy.
      • → Ralphie.


    Loop through an associative array and output the key and value.


    • foreach($age as $x => $y) {
       echo "Key= {$x}, Value={$y}";
      }


    Use the correct array method to sort the $colors array alphabetically.

    $colors = array("red", "green", "blue", "yellow");


    • sort($colors);

    This will sort it, but will not output it. To see that it has been sorted, you can use print_r.

    • print_r($colors);
    • → Array ( [0] => blue [1] => green [2] => red [3] => yellow )


    Use the correct array method to sort the $age array according to the values.

    $age = ["Peter" => "35", "Ben" => "37", "Lucy" => "25"];


    • asort($age);

    This will sort it, but will not output it. To see that it has been sorted, you can use print_r.

    • print_r($age);
    • → Array ( [Lucy] => 25 [Peter] => 35 [Ben] => 37 )


    Arrays Problem

    Create a variable called array that contains an array with three simple values. These values can be whatever you like.

    Explicitly assign the string index of "third" to the third element.

    Write a foreach loop that contains the following statement to print out each element of the array, along with its index:

    echo "$indexPosition = $value.";


    • $array = ["red gummy", "blue gummy", "third" => "yellow gummy"];
    • foreach($array as $indexPosition => $eachGummy) {
    •  echo "$indexPosition = $eachGummy.";
    • }