Learn PHP in One Video

PHP TutorialI devoted 30 hours to make the most complete PHP tutorial that I could make in this video. I cover the core language, set up a database in PHPMyAdmin, show how to validate data, create a complete system for manipulating and displaying database data and so much more. This is basically a 700 page PHP & MySQL book crammed into one 2 hour video. All of the code used can be found below and it is heavily commented. I refer to these videos : Install for Windows, Install for Mac & my MySQL Learn in One Tutorial.

Get my Ultimate Python Series on Udemy for $9.99 until December 13th. I cover the Core Language, GUI Development, Working with Multiple Databases. Up next I’ll cover Django, Data Structures & Algorithms, The Math of Machine Learning, Data Analytics and Machine Learning.

Code From the Video

tut1.php

<?php
// You embed PHP code by surrounding it with <?php and
// the closing tag
// Put PHP code you want to run before the HTML before it
// You can also embed PHP code within the HTML with
// the same tags

/*
Variables begin with a $, start with a letter and
can contain letters, numbers or underscores
A variables data type is defined by the value
assigned and the data type can change
*/

// Here are the different data types
$f_name = "Derek"; // String
$l_name = 'Banas'; // You can use single quotes
$age = 44; // Integer
$height = 1.87; // Float
$can_vote = true; // Boolean
// Array
$address = array('street'=> '123 Main St', 'city'=> 'Pittsburgh');
// I'll cover objects later

// NULL signifies that something doesn't have a value
$state = NULL;

// You can define constants
define('PI', 3.1415);

 ?>

<!-- Tells the browser to render using HTML5 spec -->
<!DOCTYPE HTML>
<!-- Define we are using English -->
<html lang="en">
  <!-- Contains data for defining the doc -->
  <head>
    <!-- Defines the character set -->
    <meta charset="UTF-8">
    <title>PHP Tutorial</title>
  </head>
  <body>
    <!-- Display inline using PHP tags and echo. Combine strings with . -->
    <p>Name : <?php echo $f_name . ' ' . $l_name; ?></p>

    <!-- You can pass data to a PHP script using forms
    Get passes the values through the URL in an array
    Get should be used when you are reading data from the
    server. Using Get allows the user to bookmark the page
    Use Post when you resend data to the server
    because if the user tries to send the same data to the
    server multiple times they will be warned
    -->
    <form action="tut1.php" method="get">
      <label>Your State : </label>
      <input type="text" name="state"/><br>
      <label>Number 1 : </label>
      <input type="text" name="num-1"/><br>
      <label>Number 2 : </label>
      <input type="text" name="num-2"/><br>
      <input type="submit" value="Submit"/>
    </form>
    <?php
    # Check if anything was passed to the web page and if the state key exists
    # I'll show a better way to validate user input later, but I want to cover
    # these functions as well
      if(isset($_GET) && array_key_exists('state', $_GET)){
        # Assign the value passed
        $state = $_GET['state'];
        # Verify that the value isn't NULL and isn't empty
        if (isset($state) && !empty($state)){
          echo 'You live in ' . $state . '<br>';
          # Use double quotes to insert a variable in a string
          echo "$f_name lives in $state<br>";
        }
        # Check how many values are in array with count
        # If executes statements between {} if the condition is true
        if(count($_GET) >= 3){
          # Math operators
          $num_1 = $_GET['num-1'];
          $num_2 = $_GET['num-2'];
          echo "$num_1 + $num_2 = " . ($num_1 + $num_2) . "<br>";
          echo "$num_1 - $num_2 = " . ($num_1 - $num_2) . "<br>";
          echo "$num_1 * $num_2 = " . ($num_1 * $num_2) . "<br>";
          echo "$num_1 / $num_2 = " . ($num_1 / $num_2) . "<br>";
          echo "$num_1 % $num_2 = " . ($num_1 % $num_2) . "<br>";

          # Integer Division
          echo "$num_1 / $num_2 = " . (intdiv($num_1, $num_2)) . "<br>";

          # Shortcut ways of incrementing and decrementing
          echo "Increment $num_1 = " . ($num_1++) . "<br>";
          echo "Decrement $num_1 = " . ($num_1--) . "<br>";

          # The following use the format of turning i = i + 1 into
          # i += 1
          $num_1 += 1;
          $num_1 -= 1;
          $num_1 *= 1;
          $num_1 /= 1;
          $num_1 %= 1;

          # Built in math functions
          echo "abs(-5) = " . abs(-5) . "<br>";
          echo "ceil(4.45) = " . ceil(4.45) . "<br>";
          echo "floor(4.45) = " . floor(4.45) . "<br>";
          echo "round(4.45) = " . round(4.45) . "<br>";
          echo "max(4,5) = " . max(4,5) . "<br>";
          echo "min(4,5) = " . min(4,5) . "<br>";
          echo "pow(4,2) = " . pow(4,2) . "<br>"; # 4 raised to the power of 2
          echo "sqrt(16) = " . sqrt(16) . "<br>"; # Square Root
          echo "exp(1) = " . exp(1) . "<br>"; # Exponent of e
          echo "log(e) = " . log(exp(1)) . "<br>"; # Logarithm
          echo "log10(10) = " . log10(exp(10)) . "<br>"; # Base 10 Logarithm
          echo "PI = " . pi() . "<br>"; # PI
          echo "hypot(10,10) = " . hypot(10,10) . "<br>"; # Hypotenuse
          echo "deg2rad(90) = " . deg2rad(90) . "<br>"; # Degrees to radians
          echo "rad2deg(1.57) = " . rad2deg(1.57) . "<br>";
          echo "mt_rand(1,50) = " . mt_rand(1,50) . "<br>"; # Fast random num
          echo "rand(1,50) = " . rand(1,50) . "<br>"; # Original random num
          echo "Max Random = " . mt_getrandmax() . "<br>"; # Max random num
          echo "is_finite(10) = " . is_finite(10) . "<br>";
          echo "is_infinite(log(0)) = " . is_infinite(log(0)) . "<br>";
          echo "is_numeric(\"10\") = " . is_numeric("10") . "<br>";

          # Trig functions
          # sin, cos, tan, asin, acos, atan, asinh, acosh, atanh, atan2
          echo "sin(0) = " . sin(0) . "<br>";

          # Format with decimals and defined decimal places
          echo number_format(12345.6789, 2) . "<br>";

          # If, elseif and else are used to execute different blocks
          # of code depending on multiple conditions. We do this with
          # Conditional Operators : == != < > <= >= and with
          # Logical Operators : && || !
          # Calculate discounts based on amount purchased
          $num_oranges = 4;
          $num_bananas = 36;
          if(($num_oranges > 25) && ($num_bananas > 30)){
            echo "25% Discount<br>";
          } elseif(($num_oranges > 30) || ($num_bananas > 35)){
            echo "15% Discount<br>";
          } elseif(!(($num_oranges < 5)) || (!($num_bananas < 5))){
            echo "5% Discount<br>";
          } else {
            echo "No Discount<br>";
          }

          # Switch provides output for a limited number of options
          $request = "Coke";
          switch($request){
            case "Coke":
              echo "Here is your Coke<br>";
              break;
            case "Pepsi":
              echo "Here is your Pepsi<br>";
              break;
            default:
              echo "Here is your Water<br>";
              break;
          }

          # You can also use conditons with Switch if you match the
          # value checked as true with a condition that also is true
          $age = 12;
          switch(true){
            case ($age < 5):
              echo "Stay Home<br>";
              break;
            case ($age == 5):
              echo "Go to Kindergarten<br>";
              break;
            # Range creates an array with values from 6 to 17
            # in_array returns true if the value of age is in the array
            case in_array($age, range(6, 17)):
              $grade = $age - 5;
              echo "Go to Grade $grade<br>";
              break;
            default:
              echo "Go to College<br>";
          }

          # The Ternary operator assigns one or another value based
          # on a condition
          $can_vote = ($age >= 18) ? "Can Vote" : "Can't Vote";
          echo "Vote? : $can_vote<br>";

          # The identical operator returns true only if the value
          # and the data type are the same
          if ("10" === 10){
            echo "They are Equal<br>";
          } else {
            echo "They aren't Equal<br>";
          }

          # ---------- PRINTF ----------
          # printf provides another way to format output
          # The variable value is placed where the type specifier
          # is located in the string
          # %c : Character
          # %d : Integer
          # %f : Float with decimal length requested
          # %s : String
          printf("%c %d %.2f %s<br>", 65, 65, 1.234, "string");

          # ---------- STRINGS ----------
          # Strings store a series of characters
          $rand_str = "     Random String      ";
          # Get number of characters in the string
          printf("Length : %d<br>", strlen($rand_str));
          # Trim left white space
          printf("Length : %d<br>", strlen(ltrim($rand_str)));
          # Trim right white space
          printf("Length : %d<br>", strlen(rtrim($rand_str)));
          # Trim all white space
          $rand_str = trim($rand_str);
          printf("Length : %d<br>", strlen($rand_str));
          # Display in all uppercase
          printf("Upper : %s<br>", strtoupper($rand_str));
          # Display in all lowercase
          printf("Lower : %s<br>", strtolower($rand_str));
          # 1st letter in uppercase
          printf("Upper : %s<br>", ucfirst($rand_str));
          # Get characters from 0 to 6
          printf("1st 6 : %s<br>", substr($rand_str, 0, 6));
          # Get location of a string
          printf("Index : %d<br>", strpos($rand_str, "String"));
          echo "rand_str : " . $rand_str . "<br>";
          # Replace a string with another
          $rand_str = str_replace("String", "Characters", $rand_str);
          printf("Replace : %s<br>", $rand_str);
          # Compare strings
          # 0 if equal
          # Positive if str1 > str2
          # Negative if str1 < str2
          # strcasecmp() isn't case sensitive
          printf("A == B : %d<br>", strcmp("A", "B"));

          # ---------- ARRAYS ----------
          # Arrays store multiple values
          $friends = array('Joy', 'Willow', 'Ivy');
          # Access by index
          echo 'Wife : ' . $friends[0] . '<br>';
          # Add an item
          $friends[3] = 'Steve';
          # Cycle through an array
          foreach($friends as $f){
            printf("Friend : %s<br>", $f);
          }
          # Create key value pairs
          $me_info = array('Name'=>'Derek', 'Street'=>'123 Main');
          # Output keys and values
          foreach($me_info as $k => $v){
            printf("%s : %s<br>", $k, $v);
          }
          # Combine arrays
          $friends2 = array('Doug');
          $friends = $friends + $friends2;
          # Sort is ascending order
          sort($friends);
          # Sort in descending order
          rsort($friends);
          # Sort a key value (associative array) by value
          asort($me_info);
          # Sort associative array by key
          ksort($me_info);
          # Use arsort and krsort for descending
          # Multidimensional arrays
          $customers = array(array('Derek', '123 Main'),
                            array('Sally', '122 Main'));
          for($row = 0; $row < 2; $row++){
            for($col = 0; $col < 2; $col++){
              echo $customers[$row][$col] . ', ';
            }
            echo '<br>';
          }
          # Turn a string into an array
          $let_str = "A B C D";
          $let_arr = explode(' ', $let_str);
          foreach($let_arr as $l){
            printf("Letter : %s<br>", $l);
          }
          # Turn an array into a string
          $let_str_2 = implode(' ', $let_arr);
          echo "String : $let_str_2<br>";
          # Check if key exists
          printf("Key Exists : %d<br>", array_key_exists('Name', $me_info));
          # Get key for matching value
          printf("Key : %s<br>", array_search('Derek', $me_info));
          # Is value in array
          printf("In Array : %d<br>", in_array('Joy', $friends));

          # ---------- LOOPS ----------
          # While loops execute as long as a condition is true
          $i = 0;
          while($i < 10){
            echo ++$i . ', ';
          }
          echo '<br>';

          # For loops compacts what is spread out with while
          for($i = 0; $i < 10; $i++){
            # continue jumps to top of loop to only print odds
            if(($i % 2) == 0){
              continue;
            }
            # Break jumps to the code that follows the loop
            if($i == 7) break;
            echo $i . ', ';
          }
          echo '<br>';

          # foreach can be used to easily cycle through arrays
          # as shown above

          # do while will execute at least once
          $i = 0;
          do {
            echo "Do While : $i<br>";
          } while ($i > 0);

          # ---------- FUNCTIONS ----------
          # Functions allow you to reuse code
          # They must begin with a letter, but can contain
          # numbers and underscores
          # You can pass values to a function and set default values
          # You can define parameter types like this
          # function addNumbers(int $num_1=0, int $num_2=0)
          function addNumbers($num_1=0, $num_2=0){
            # return returns data from where the function
            # was called
            return $num_1 + $num_2;
          }

          printf("5 + 4 = %d<br>", addNumbers(5,4));

          # Functions are pass by value by default so you can't
          # effect values out of the function
          function changeMe($change){
            $change = 10;
          }

          $change = 5;
          changeMe($change);
          echo "Change : $change<br>";

          # You can pass by reference though
          function changeMe2(&$change){
            $change = 10;
          }

          $change = 5;
          changeMe2($change);
          echo "Change : $change<br>";

          # Receive a variable number of parameters
          function getSum(...$nums){
            $sum = 0;
            foreach($nums as $num){
              $sum += $num;
            }
            return $sum;
          }
          printf("Sum = %d<br>", getSum(1,2,3,4));

          # Return multiple values
          function doMath($x, $y){
            return array(
              $x + $y,
              $x - $y
            );
          }
          list($sum, $difference) = doMath(5,4);
          echo "Sum = $sum<br>";
          echo "Difference = $difference<br>";

          # ---------- MAP ----------
          # Apply a function to values in a list
          function double($x){
            return $x * $x;
          }
          $list = [1,2,3,4];
          $dbl_list = array_map('double', $list);
          # Print human readable version of list
          print_r($dbl_list);
          echo '<br>';

          # ---------- REDUCE ----------
          # Reduce values in an array to a single value
          # Multiply each value times the others
          function mult($x, $y){
            $x *= $y;
            return $x;
          }
          $prod = array_reduce($list, 'mult', 1);
          print_r($prod);
          echo '<br>';

          # ---------- FILTER ----------
          # Filter an array with a function
          # Get only even values
          function isEven($x){
            return ($x % 2) == 0;
          }
          $even_list = array_filter($list, 'isEven');
          print_r($even_list);
          echo '<br>';

          # ---------- DATES ----------
          # Set the time zone php.net/manual/en/timezones.php
          date_default_timezone_set('America/New_York');

          # Format date info for now
          # php.net/manual/en/function.date.php
          echo "Date : " . date('l F m-d-Y g:i:s A') . "<br>";

          # Create a date hour, minute, second, month, day, year
          $import_date = mktime(0, 0, 0, 12, 21, 1974);
          echo "Important Date : " . date('l F m-d-Y g:i:s A', $import_date) . "<br>";

          # ---------- INCLUDING OTHER FILES ----------
          # You can insert code from another script with include
          include 'sayhello.php';

        }
      }

      # ---------- EXCEPTION HANDLING ----------
      # Use to avoid a crashed program
      function badDivide($num){
        if($num == 0){
          throw new Exception("You can't divide by zero");
        }
        return $calc = 100 / $num;
      }
      try{
        badDivide(0);
      } catch(Exception $e){
        echo "Exception : " . $e->getMessage();
      }

     ?>

  </body>
</html>

sayhello.php

<?php
echo "Hello<br>";
 ?>

tut2.php

<!DOCTYPE HTML>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>PHP Tutorial</title>
  </head>
  <body>
    <form action="tut2.php" method="post">
      <label>Email : </label>
      <input type="text" name="email"/><br>
      <label>Number 1 : </label>
      <!-- Protect by setting the correct types
      w3schools.com/html/html_form_input_types.asp -->
      <input type="text" name="num1"/><br>
      <label>Number 2 : </label>
      <input type="text" name="num2"/><br>
      <label>Website : </label>
      <input type="text" name="website"/><br>
      <input type="submit" value="Submit"/>
    </form>
    <?php
    # Check for valid email
    if(isset($_POST["email"])){
      # filter_input gets the value from either INPUT_GET, INPUT_POST,
      # INPUT_COOKIE, INPUT_SERVER, or INPUT_ENV
      # Specify the variable name and any filter to run
      if(!filter_input(INPUT_POST, "email", FILTER_VALIDATE_EMAIL)){
        echo "Email isn't Valid<br>";
      } else {
        echo "Email is Valid<br>";
      }
    }
    # Verify that the values are numbers with is_numeric
    if(!empty($_POST["num1"]) && !empty($_POST["num2"])){
      # Will delete anything that isn't a float
      $num1 = filter_input(INPUT_POST, 'num1', FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
      $num2 = filter_input(INPUT_POST, 'num2', FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
      # sprintf returns a formatted string
      $output = sprintf("%.1f + %.1f = %.1f", $num1, $num2, ($num1 + $num2));
      # htmlspecialchars escapes output to avoid XSS attacks
      echo htmlspecialchars($output) . '<br>';
    }
    # Validate URL
    if(isset($_POST["website"])){
      $website = filter_input(INPUT_POST, 'website', FILTER_VALIDATE_URL);
      echo 'Website : ' . htmlspecialchars($website) . '<br>';
    }
    # Other Validations : php.net/manual/en/filter.filters.validate.php
    # Sanitization Filters : php.net/manual/en/filter.filters.sanitize.php

    # Converting HTML special characters
    # Convert special characters into HTML entities
    $con_html = '<a href="#">Sample</a>';
    echo $con_html . "<br>";
    # Convert special characters to HTML so it can be displayed
    echo htmlspecialchars($con_html) . "<br>";
    # Strip tags except for a
    echo strip_tags($con_html, '<a>') . "<br>";
    # Eliminate all tags
    $con_html = strip_tags($con_html) . "<br>";
    echo $con_html . "<br>";
     ?>
  </body>
</html>

Setup PHPMyAdmin

CREATE TABLE student(
first_name VARCHAR(30) NOT NULL,
last_name VARCHAR(30) NOT NULL,
email VARCHAR(60) NULL,
street VARCHAR(50) NOT NULL,
city VARCHAR(40) NOT NULL,
state VARCHAR(2) NOT NULL DEFAULT "PA",
zip MEDIUMINT UNSIGNED NOT NULL,
phone VARCHAR(20) NOT NULL,
birth_date DATE NOT NULL,
sex ENUM('M', 'F') NOT NULL,
date_entered TIMESTAMP,
lunch_cost FLOAT NULL,
student_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
);

INSERT INTO student VALUES('Dale', 'Cooper', 'dcooper@aol.com', 
	'123 Main St', 'Yakima', 'WA', 98901, '792-223-8901', "1959-2-22",
	'M', NOW(), 3.50, NULL);

INSERT INTO student VALUES
('Harry', 'Truman', 'htruman@aol.com', '202 South St', 'Vancouver', 'WA', 98660, '792-223-9810', "1946-1-24",
'M', NOW(), 3.50, NULL),
('Shelly', 'Johnson', 'sjohnson@aol.com', '9 Pond Rd', 'Sparks', 'NV', 89431, '792-223-6734', "1970-12-12",'F', NOW(), 3.50, NULL),
('Bobby', 'Briggs', 'bbriggs@aol.com', '14 12th St', 'San Diego', 'CA', 92101, '792-223-6178', "1967-5-24",'M', NOW(), 3.50, NULL),
('Donna', 'Hayward', 'dhayward@aol.com', '120 16th St', 'Davenport', 'IA', 52801, '792-223-2001', "1970-3-24",'F', NOW(), 3.50, NULL),
('Audrey', 'Horne', 'ahorne@aol.com', '342 19th St', 'Detroit', 'MI', 48222, '792-223-2001', "1965-2-1",'F', NOW(), 3.50, NULL),
('James', 'Hurley', 'jhurley@aol.com', '2578 Cliff St', 'Queens', 'NY', 11427, '792-223-1890', "1967-1-2",'M', NOW(), 3.50, NULL),
('Lucy', 'Moran', 'lmoran@aol.com', '178 Dover St', 'Hollywood', 'CA', 90078, '792-223-9678', "1954-11-27",'F', NOW(), 3.50, NULL),
('Tommy', 'Hill', 'thill@aol.com', '672 High Plains', 'Tucson', 'AZ', 85701, '792-223-1115', "1951-12-21",'M', NOW(), 3.50, NULL),
('Andy', 'Brennan', 'abrennan@aol.com', '281 4th St', 'Jacksonville', 'NC', 28540, '792-223-8902', "1960-12-27",'M', NOW(), 3.50, NULL);

CREATE TABLE class(
name VARCHAR(30) NOT NULL,
class_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);

INSERT INTO class VALUES
('English', NULL), ('Speech', NULL), ('Literature', NULL),
('Algebra', NULL), ('Geometry', NULL), ('Trigonometry', NULL),
('Calculus', NULL), ('Earth Science', NULL), ('Biology', NULL),
('Chemistry', NULL), ('Physics', NULL), ('History', NULL),
('Art', NULL), ('Gym', NULL);


CREATE TABLE test(
date DATE NOT NULL,
type ENUM('T', 'Q') NOT NULL,
class_id INT UNSIGNED NOT NULL,
test_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);

CREATE TABLE score(
student_id INT UNSIGNED NOT NULL,
event_id INT UNSIGNED NOT NULL,
score INT NOT NULL,
PRIMARY KEY(event_id, student_id));

CREATE TABLE absence(
student_id INT UNSIGNED NOT NULL,
date DATE NOT NULL,
PRIMARY KEY(student_id, date));

ALTER TABLE test ADD maxscore INT NOT NULL AFTER type;

INSERT INTO test VALUES
('2014-8-25', 'Q', 15, 1, NULL),
('2014-8-27', 'Q', 15, 1, NULL),
('2014-8-29', 'T', 30, 1, NULL),
('2014-8-29', 'T', 30, 2, NULL),
('2014-8-27', 'Q', 15, 4, NULL),
('2014-8-29', 'T', 30, 4, NULL);

ALTER TABLE score CHANGE event_id test_id 
	INT UNSIGNED NOT NULL;

INSERT INTO score VALUES
(1, 1, 15),(1, 2, 14),(1, 3, 28),(1, 4, 29),(1, 5, 15),(1, 6, 27),(2, 1, 15),(2, 2, 14),(2, 3, 26),(2, 4, 28),(2, 5, 14),(2, 6, 26),(3, 1, 14),(3, 2, 14),(3, 3, 26),(3, 4, 26),(3, 5, 13),(3, 6, 26),(4, 1, 15),(4, 2, 14),(4, 3, 27),(4, 4, 27),(4, 5, 15),(4, 6, 27),(5, 1, 14),(5, 2, 13),(5, 3, 26),(5, 4, 27),(5, 5, 13),(5, 6, 27),(6, 1, 13),(6, 2, 13),(6, 4, 26),(6, 5, 13),(6, 6, 26),(7, 1, 13),(7, 2, 13),(7, 3, 25),(7, 4, 27),(7, 5, 13),(8, 1, 14),(8, 3, 26),(8, 4, 23),(8, 5, 12),(8, 6, 24),(9, 1, 15),(9, 2, 13),(9, 3, 28),(9, 4, 27),(9, 5, 14),(9, 6, 27),(10, 1, 15),(10, 2, 13),(10, 3, 26),(10, 4, 27),(10, 5, 12),(10, 6, 22);

INSERT INTO absence VALUES
	(6, '2014-08-29'),
	(7, '2014-08-29'),
	(8, '2014-08-27');

RENAME TABLE 
	absence to absences,
	class to classes,
	score to scores,
	student to students,
	test to tests;

tut3.php

<?php
# Connect to the database
require('db_connect.php');

# Get student names
# Define the query to send to the database
$query_students = 'SELECT * FROM students ORDER BY student_id';
# We use a prepared statement to execute the query
# This creates a PDOStatement object
$student_statement = $db->prepare($query_students);
# Execute the query
$student_statement->execute();
# Return an array containing the query results
$students = $student_statement->fetchAll();
# Allows new SQL statements to execute
$student_statement->closeCursor();
 ?>
<!DOCTYPE HTML>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>PHP Tutorial</title>
    <link rel="stylesheet" type="text/css" href="main.css" />
  </head>
  <body>
    <h3>Student List</h3>
    <table>
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Email</th>
        <th>Street</th>
        <th>City</th>
        <th>State</th>
        <th>Zip</th>
        <th>Phone</th>
        <th>BD</th>
        <th>Sex</th>
        <th>Entered</th>
        <th>Lunch</th>
      </tr>
      <!-- Get an array from the DB query and cycle
      through each row of data -->
      <?php foreach($students as $student) : ?>
        <tr>
          <!-- Print out individual column data -->
          <td><?php echo $student['student_id']; ?></td>
          <td><?php echo $student['first_name'] . ' ' . $student['last_name']; ?></td>
          <td><?php echo $student['email']; ?></td>
          <td><?php echo $student['street']; ?></td>
          <td><?php echo $student['city']; ?></td>
          <td><?php echo $student['state']; ?></td>
          <td><?php echo $student['zip']; ?></td>
          <td><?php echo $student['phone']; ?></td>
          <td><?php echo $student['birth_date']; ?></td>
          <td><?php echo $student['sex']; ?></td>
          <td><?php echo $student['date_entered']; ?></td>
          <td><?php echo $student['lunch_cost']; ?></td>
        </tr>
      <!-- Mark the end of the foreach loop -->
      <?php endforeach; ?>
    </table>
    <h3>Insert Student</h3>
    <form action="add_student.php" method="post"
      id="add_student_form">
      <label>First Name : </label>
      <input type="text" name="first_name"><br>
      <label>Last Name : </label>
      <input type="text" name="last_name"><br>
      <label>Email : </label>
      <input type="text" name="email"><br>
      <label>Street : </label>
      <input type="text" name="street"><br>
      <label>City : </label>
      <input type="text" name="city"><br>
      <label>State : </label>
      <input type="text" name="state"><br>
      <label>Zip Code : </label>
      <input type="text" name="zip"><br>
      <label>Phone : </label>
      <input type="text" name="phone"><br>
      <label>Birth Date : </label>
      <input type="text" name="birthdate"><br>
      <label>Sex : </label>
      <input type="text" name="sex"><br>
      <label>Lunch Cost : </label>
      <input type="text" name="lunch"><br>
      <input type="submit" value="Add Student"><br>
    </form>
  </body>
</html>

db_connect.php

<?php
# I create a PHP Data Object to work with our DB
# Using a PDO allows the same PHP code to work with
# multiple types of DBs.
# Make the userid and password constants
DEFINE ('DB_USER', 'studentweb');
DEFINE ('DB_PASSWORD', 'TurtleDove');

# Defines the data source name which is MySQL, local
# and the DB to use
$dsn = 'mysql:host=localhost;dbname=students';

# Try to connect and if we get an error display it
# and call for an error page to load
try{
  $db = new PDO($dsn, DB_USER, DB_PASSWORD);
} catch (PDOException $e){
  $err_msg = $e->getMessage();
  include('db_error.php');
  exit();
}
 ?>

main.css

table {
  border-collapse: collapse;
  width: 90%;
}

table, th, td {
  border: 1px solid black;
  text-align: left;
}

add_student.php

<?php
# Get data to input
$first_name = filter_input(INPUT_POST, "first_name");
$last_name = filter_input(INPUT_POST, "last_name");
$email = filter_input(INPUT_POST, "email");
$street = filter_input(INPUT_POST, "street");
$city = filter_input(INPUT_POST, "city");
$state = filter_input(INPUT_POST, "state");
$zip = filter_input(INPUT_POST, "zip");
$phone = filter_input(INPUT_POST, "phone");
$birth_date = filter_input(INPUT_POST, "birthdate");
$sex = filter_input(INPUT_POST, "sex");
$lunch_cost = filter_input(INPUT_POST, "lunch", FILTER_VALIDATE_FLOAT);
# Create a timestamp for now
$date_entered = date('Y-m-d H:i:s');

# Verify that eveything has been entered
if($first_name == null || $last_name == null || $email == null ||
$street == null || $city == null || $state == null ||
$zip == null || $phone == null || $birth_date == null ||
$sex == null || $lunch_cost == false){
  # Print an error if values aren't entered
  $err_msg = "All Values Not Entered<br>";
  include('db_error.php');

  # Validate Data with Regular Expressions
  # Regular Expressions are codes used to match patterns
  # Check if first name contains only characters with a max of 30
} elseif(!preg_match("/[a-zA-Z]{3,30}$/", $first_name)){
  $err_msg = "First Name Not Valid<br>";
  include('db_error.php');
} elseif(!preg_match("/[a-zA-Z]{3,30}$/", $last_name)){
  $err_msg = "Last Name Not Valid<br>";
  include('db_error.php');
} elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)){
  $err_msg = "Email Not Valid<br>";
  include('db_error.php');
} elseif(!preg_match("/^[A-Za-z0-9 ,#'\/.]{3,50}$/", $street)){
  $err_msg = "Street Not Valid<br>";
  include('db_error.php');
} elseif(!preg_match("/[a-zA-Z\- ]{2,58}$/", $city)){
  $err_msg = "City Not Valid<br>";
  include('db_error.php');
} elseif(!preg_match("/^(?:A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])*$/", $state)){
  $err_msg = "State Not Valid<br>";
  include('db_error.php');
} elseif(!preg_match("/[0-9]{5}$/", $zip)){
  $err_msg = "Zip Not Valid<br>";
  include('db_error.php');
} elseif(!preg_match("/(([0-9]{1})*[- .(]*([0-9]{3})[- .)]*[0-9]{3}[- .]*[0-9]{4})+$/", $phone)){
  $err_msg = "Phone Not Valid<br>";
  include('db_error.php');
} elseif(!preg_match("/[0-9- ]{8,12}$/", $birth_date)){
  $err_msg = "Birth Date Not Valid<br>";
  include('db_error.php');
} elseif(!preg_match("/[MF]{1}$/", $sex)){
  $err_msg = "Sex Not Valid<br>";
  include('db_error.php');
} else {
  require_once('db_connect.php');
  # Create your query using : to add parameters to the statement
  $query = 'INSERT INTO students (first_name, last_name, email,
    street, city, state, zip, phone, birth_date, sex, date_entered,
    lunch_cost, student_id) VALUES
    (:first_name, :last_name, :email, :street, :city, :state, :zip, :phone, :birth_date, :sex, :date_entered, :lunch_cost, :student_id)';

  # Create a PDOStatement object
  $stm = $db->prepare($query);
  # Bind values to parameters in the prepared statement
  $stm->bindValue(':first_name', $first_name);
  $stm->bindValue(':last_name', $last_name);
  $stm->bindValue(':email', $email);
  $stm->bindValue(':street', $street);
  $stm->bindValue(':city', $city);
  $stm->bindValue(':state', $state);
  $stm->bindValue(':zip', $zip);
  $stm->bindValue(':phone', $phone);
  $stm->bindValue(':birth_date', $birth_date);
  $stm->bindValue(':sex', $sex);
  $stm->bindValue(':date_entered', $date_entered);
  $stm->bindValue(':lunch_cost', $lunch_cost);
  $stm->bindValue(':student_id', null, PDO::PARAM_INT);
  # Execute the query and store true or false based on success
  $execute_success = $stm->execute();
  $stm->closeCursor();

  # If an error occurred print the error
  if(!$execute_success){
    print_r($stm->errorInfo()[2]);
  }
}

require_once('db_connect.php');
$query_students = 'SELECT * FROM students ORDER BY student_id';
$student_statement = $db->prepare($query_students);
$student_statement->execute();
$students = $student_statement->fetchAll();
$student_statement->closeCursor();
 ?>
 <!DOCTYPE HTML>
 <html lang="en">
   <head>
     <meta charset="UTF-8">
     <title>PHP Tutorial</title>
     <link rel="stylesheet" type="text/css" href="main.css" />
   </head>
   <body>
     <h3>Student List</h3>
     <table>
       <tr>
         <th>ID</th>
         <th>Name</th>
         <th>Email</th>
         <th>Street</th>
         <th>City</th>
         <th>State</th>
         <th>Zip</th>
         <th>Phone</th>
         <th>BD</th>
         <th>Sex</th>
         <th>Entered</th>
         <th>Lunch</th>
       </tr>
       <!-- Get an array from the DB query and cycle
       through each row of data -->
       <?php foreach($students as $student) : ?>
         <tr>
           <!-- Print out individual column data -->
           <td><?php echo $student['student_id']; ?></td>
           <td><?php echo $student['first_name'] . ' ' . $student['last_name']; ?></td>
           <td><?php echo $student['email']; ?></td>
           <td><?php echo $student['street']; ?></td>
           <td><?php echo $student['city']; ?></td>
           <td><?php echo $student['state']; ?></td>
           <td><?php echo $student['zip']; ?></td>
           <td><?php echo $student['phone']; ?></td>
           <td><?php echo $student['birth_date']; ?></td>
           <td><?php echo $student['sex']; ?></td>
           <td><?php echo $student['date_entered']; ?></td>
           <td><?php echo $student['lunch_cost']; ?></td>
         </tr>
       <!-- Mark the end of the foreach loop -->
       <?php endforeach; ?>
     </table>
     <h3>Update Student</h3>
     <form action="update_student.php" method="post"
       id="update_student_form">
       <label>Student ID : </label>
       <input type="text" name="student_id"><br>
       <label>First Name : </label>
       <input type="text" name="first_name"><br>
       <label>Last Name : </label>
       <input type="text" name="last_name"><br>
       <label>Email : </label>
       <input type="text" name="email"><br>
       <label>Street : </label>
       <input type="text" name="street"><br>
       <label>City : </label>
       <input type="text" name="city"><br>
       <label>State : </label>
       <input type="text" name="state"><br>
       <label>Zip Code : </label>
       <input type="text" name="zip"><br>
       <label>Phone : </label>
       <input type="text" name="phone"><br>
       <label>Birth Date : </label>
       <input type="text" name="birthdate"><br>
       <label>Sex : </label>
       <input type="text" name="sex"><br>
       <label>Lunch Cost : </label>
       <input type="text" name="lunch"><br>
       <input type="submit" value="Update Student"><br>
     </form>
   </body>
 </html>

db_error.php

<!DOCTYPE HTML>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>PHP Tutorial</title>
  </head>
  <body>
    <h1>Database Error</h1>
    <p><?php echo $err_msg; ?></p>
  </body>
</html>

update_student.php

<?php
# Get data to input
# NEW add student_id input
$first_name = filter_input(INPUT_POST, "first_name");
$last_name = filter_input(INPUT_POST, "last_name");
$email = filter_input(INPUT_POST, "email");
$street = filter_input(INPUT_POST, "street");
$city = filter_input(INPUT_POST, "city");
$state = filter_input(INPUT_POST, "state");
$zip = filter_input(INPUT_POST, "zip");
$phone = filter_input(INPUT_POST, "phone");
$birth_date = filter_input(INPUT_POST, "birthdate");
$sex = filter_input(INPUT_POST, "sex");
$lunch_cost = filter_input(INPUT_POST, "lunch", FILTER_VALIDATE_FLOAT);
# Create a timestamp for now
$date_entered = date('Y-m-d H:i:s');
$student_id = filter_input(INPUT_POST, "student_id", FILTER_VALIDATE_INT);

# Verify that eveything has been entered
if($first_name == null || $last_name == null || $email == null ||
$street == null || $city == null || $state == null ||
$zip == null || $phone == null || $birth_date == null ||
$sex == null || $lunch_cost == false || $student_id == null){
  # Print an error if values aren't entered
  $err_msg = "All Values Not Entered";
  include('db_error.php');
} else {
  require_once('db_connect.php');
  # Create your query using : to add parameters to the statement
  $query = 'UPDATE students
            SET first_name = :first_name,
            last_name = :last_name,
            email = :email,
            street = :street,
            city = :city,
            state = :state,
            zip = :zip,
            phone = :phone,
            birth_date = :birth_date,
            sex = :sex,
            lunch_cost = :lunch_cost
            WHERE student_id = :student_id';

  # Create a PDOStatement object
  $stm = $db->prepare($query);
  # Bind values to parameters in the prepared statement
  $stm->bindValue(':first_name', $first_name);
  $stm->bindValue(':last_name', $last_name);
  $stm->bindValue(':email', $email);
  $stm->bindValue(':street', $street);
  $stm->bindValue(':city', $city);
  $stm->bindValue(':state', $state);
  $stm->bindValue(':zip', $zip);
  $stm->bindValue(':phone', $phone);
  $stm->bindValue(':birth_date', $birth_date);
  $stm->bindValue(':sex', $sex);
  $stm->bindValue(':lunch_cost', $lunch_cost);
  $stm->bindValue(':student_id', $student_id);
  # Execute the query and store true or false based on success
  $execute_success = $stm->execute();
  $stm->closeCursor();

  # If an error occurred print the error
  if(!$execute_success){
    print_r($stm->errorInfo()[2]);
  }
}

require_once('db_connect.php');
$query_students = 'SELECT * FROM students ORDER BY student_id';
$student_statement = $db->prepare($query_students);
$student_statement->execute();
$students = $student_statement->fetchAll();
$student_statement->closeCursor();
 ?>
 <!DOCTYPE HTML>
 <html lang="en">
   <head>
     <meta charset="UTF-8">
     <title>PHP Tutorial</title>
     <link rel="stylesheet" type="text/css" href="main.css" />
   </head>
   <body>
     <h3>Student List</h3>
     <table>
       <tr>
         <th>ID</th>
         <th>Name</th>
         <th>Email</th>
         <th>Street</th>
         <th>City</th>
         <th>State</th>
         <th>Zip</th>
         <th>Phone</th>
         <th>BD</th>
         <th>Sex</th>
         <th>Entered</th>
         <th>Lunch</th>
       </tr>
       <!-- Get an array from the DB query and cycle
       through each row of data -->
       <?php foreach($students as $student) : ?>
         <tr>
           <!-- Print out individual column data -->
           <td><?php echo $student['student_id']; ?></td>
           <td><?php echo $student['first_name'] . ' ' . $student['last_name']; ?></td>
           <td><?php echo $student['email']; ?></td>
           <td><?php echo $student['street']; ?></td>
           <td><?php echo $student['city']; ?></td>
           <td><?php echo $student['state']; ?></td>
           <td><?php echo $student['zip']; ?></td>
           <td><?php echo $student['phone']; ?></td>
           <td><?php echo $student['birth_date']; ?></td>
           <td><?php echo $student['sex']; ?></td>
           <td><?php echo $student['date_entered']; ?></td>
           <td><?php echo $student['lunch_cost']; ?></td>
         </tr>
       <!-- Mark the end of the foreach loop -->
       <?php endforeach; ?>
     </table>
     <h3>Delete Student</h3>
     <form action="delete_student.php" method="post"
       id="delete_student_form">
       <label>Student ID : </label>
       <input type="text" name="student_id"><br>
       <input type="submit" value="Delete Student"><br>
     </form>
   </body>
 </html>

delete_student.php

<?php
# Get data to input
$student_id = filter_input(INPUT_POST, "student_id", FILTER_VALIDATE_INT);

# Verify that eveything has been entered
if($student_id == null){
  # Print an error if values aren't entered
  $err_msg = "All Values Not Entered";
  include('db_error.php');
} else {
  require_once('db_connect.php');
  # Create your query using : to add parameters to the statement
  $query = 'DELETE FROM students
            WHERE student_id = :student_id';

  # Create a PDOStatement object
  $stm = $db->prepare($query);
  # Bind values to parameters in the prepared statement
  $stm->bindValue(':student_id', $student_id);
  # Execute the query and store true or false based on success
  $execute_success = $stm->execute();
  $stm->closeCursor();

  # If an error occurred print the error
  if(!$execute_success){
    print_r($stm->errorInfo()[2]);
  }
}

require_once('db_connect.php');
$query_students = 'SELECT * FROM students ORDER BY student_id';
$student_statement = $db->prepare($query_students);
$student_statement->execute();
$students = $student_statement->fetchAll();
$student_statement->closeCursor();
 ?>
 <!DOCTYPE HTML>
 <html lang="en">
   <head>
     <meta charset="UTF-8">
     <title>PHP Tutorial</title>
     <link rel="stylesheet" type="text/css" href="main.css" />
   </head>
   <body>
     <h3>Student List</h3>
     <table>
       <tr>
         <th>ID</th>
         <th>Name</th>
         <th>Email</th>
         <th>Street</th>
         <th>City</th>
         <th>State</th>
         <th>Zip</th>
         <th>Phone</th>
         <th>BD</th>
         <th>Sex</th>
         <th>Entered</th>
         <th>Lunch</th>
       </tr>
       <!-- Get an array from the DB query and cycle
       through each row of data -->
       <?php foreach($students as $student) : ?>
         <tr>
           <!-- Print out individual column data -->
           <td><?php echo $student['student_id']; ?></td>
           <td><?php echo $student['first_name'] . ' ' . $student['last_name']; ?></td>
           <td><?php echo $student['email']; ?></td>
           <td><?php echo $student['street']; ?></td>
           <td><?php echo $student['city']; ?></td>
           <td><?php echo $student['state']; ?></td>
           <td><?php echo $student['zip']; ?></td>
           <td><?php echo $student['phone']; ?></td>
           <td><?php echo $student['birth_date']; ?></td>
           <td><?php echo $student['sex']; ?></td>
           <td><?php echo $student['date_entered']; ?></td>
           <td><?php echo $student['lunch_cost']; ?></td>
         </tr>
       <!-- Mark the end of the foreach loop -->
       <?php endforeach; ?>
     </table>
     <h3>Delete Student</h3>
     <form action="delete_student.php" method="post"
       id="delete_student_form">
       <label>Student ID : </label>
       <input type="text" name="student_id"><br>
       <input type="submit" value="Delete Student"><br>
     </form>
   </body>
 </html>

cookie_test.php

<?php
# Cookies can store values in the users browser
# You can't expect that users will have cookies enabled
# Create a cookie with name, value, expiration date (1 day)
# and make available to your entire site
# You modify cookie vales by running setcookie again
# Delete a cookie by setting the expiration in the past
# setcookie("my_cookie", "", time() - 86400, "/");
setcookie("my_cookie", "sample value", time() + 86400, "/");
 ?>
 <!DOCTYPE HTML>
 <html lang="en">
 <body>
   <?php
   # Check if cookie is set
    if(!isset($_COOKIE["my_cookie"])){
      echo "Cookie Not Set<br>";
    } else {
      # Output cookie value
      echo "Cookie Value : " . $_COOKIE["my_cookie"] . "<br>";
    }
    ?>
  </body>
  </html>

oopphp.php

<html>
<head>
	<title><?php echo "PHP Object Oriented Programming";?></title>
</head>
<body>
<?php
/*
	Object Oriented Programming allows you to model real
	world objects. Every object has attributes and things 
	it can do (Operations / Functions / Methods) You define those 
	things in a class which is a blueprint for creating
	objects.
*/
class Animal implements Singable{

	/* 
		You define attributes like this. The private means
		that only methods in the class can access this data
		public would mean that any code could directly access
		and change the values for these attributes. 
		
		Attributes that are private won't be inherited as you'll see
		but those that are public or protected are
		
		By making sure our data can only be changed by the class 
		operations we are inencapsulating or protecting it.
	*/
	
	protected $name;
	protected $favorite_food;
	protected $sound;
	protected $id;
	
	// A static attribute is shared by every object. If its
	// value changes for one it changes for all
	
	public static $number_of_animals = 0;
	
	// A constant is also shared
	
	const PI = "3.14159";
	
	// You define methods just like you define functions in a class
	
	function getName(){
	
		// To refer to data stored in an object you proceed the name
		// of the attribute with $this->yourAttribute
	
		return $this->name;
	
	}
	
	// A Construtor is used to initialize objects when they are 
	// created or instantiated
	
	function __construct(){
	
		// Generate a random id between 1 and 1000000
		
		$this->id = rand(100, 1000000);
		
		echo $this->id . " has been assigned<br />";
		
		// You access static attributes with Class::$static_att
		
		Animal::$number_of_animals++;
	
	}
	
	// A Destructor is called when all references to the object have 
	// been unset. It cannot receive attributes
	
	public function __destruct(){
	
		echo $this->name . " is being destroyed :(";
	
	}
	
	// You can also use magic setters and getters which are called
	// when an attribute is set, or if its value is asked for
	
	function __get($name){
		
		echo "Asked for " . $name . "<br />";
	
		return $this->$name;
		
	}
	
	
	// If you want to check for a valid attribute you could use switch
	
	function __set($name, $value){
	
		switch($name){
		
			case "name":
				$this->name = $value;
				break;
				
			case "favorite_food":
				$this->favorite_food = $value;
				break;
				
			case "sound":
				$this->sound = $value;
				break;
				
			default : 
				echo $name . "Not Found";
		
		}
		
		echo "Set " . $name . " to " . $value . "<br />";
	
	}
	
	// 2. We will override this method in the subclass
	function run(){
		
		
		echo $this->name . " runs<br />";
		
	}
	
	// 3. To keep a method from being overridden use final
	// You can use final on a class to keep classes from
	// being overridden as well
	
	final function what_is_good(){
		
		echo "Running is Good<br />";
		
	}
	
	// 4. You can use __toString to define what prints when
	// the object is called to print
	
	function __toString(){
		
		return $this->name . " says " . $this->sound .
		" give me some ". $this->favorite_food . " my id is " .
		$this->id . " total animals = " . Animal::$number_of_animals .
		"<br /><br />";
		
	}
	
	// 5. You must define any function defined in an interface
	
	public function sing(){
		
		echo $this->name . " sings 'Grrrr grr grrr grrrrrrrrr'<br />";
		
	}
	
	// 7. static methods can be called without the need for instantiation
	
	static function add_these($num1, $num2){
		
		return ($num1 + $num2) . "<br />";
		
	}
	
}

// Inheritance occurs when you create a new class by extending another
// You will inherit all of the Attributes and Methods defined in the first
// You don't have to do anything in the class and it will still work

class Dog extends Animal implements Singable{
	
	// 2. You can override functions defined in the superclass
	function run(){
		
		
		echo $this->name . " runs like crazy<br />";
		
	}
	
	// 5. You must define any function defined in an interface
	
	public function sing(){
		
		echo $this->name . " sings 'Bow wow, woooow, woooooooooow'<br />";
		
	}
	
	
}

// 5. PHP doesn't allow muliple inheritance
// You need to use interfaces to get similar results
// Interfaces allow you to define functions that must be implemented

interface Singable{
	
	public function sing();
	
}


$animal_one = new Animal();

// These call __set

$animal_one->name = "Spot";
$animal_one->favorite_food = "Meat";
$animal_one->sound = "Ruff";

// The statements $animal_one->att_name call __get
// We call static attributes like this Class::$static_var 

echo $animal_one->name . " says " . $animal_one->sound .
	" give me some ". $animal_one->favorite_food . " my id is " .
	$animal_one->id . " total animals = " . Animal::$number_of_animals .
	"<br /><br />";
	
// If we defined a constant in the class we would get its
// value like this Class::CONTANT 
	
echo "Favorite Number " . Animal::PI . "<br />";
	
$animal_two = new Dog();

$animal_two->name = "Grover";
$animal_two->favorite_food = "Mushrooms";
$animal_two->sound = "Grrrrrrr";

// Even though we are referring to the Dog $number_of_animals it
// still increases even with subclasses

echo $animal_two->name . " says " . $animal_two->sound .
	" give me some ". $animal_two->favorite_food . " my id is " .
	$animal_two->id . " total animals = " . Dog::$number_of_animals .
	"<br /><br />";
	
// 2. Because of method overriding we get different results	
$animal_one->run();
$animal_two->run();

// 3. final methods can't be overriden
$animal_one->what_is_good();

// 4. Example using __toString()

echo $animal_two;

// 5. You call a method defined in an interface like all others

$animal_two->sing();

// 6. You can also define functions that will except classes
// extending a secific class or interface

function make_them_sing(Singable $singing_animal){
	
	$singing_animal->sing();
	
}

// 6. Polymorphism states that different classes can have different
// behaviors for the same function. The compiler is smart enough to
// just figure out which function to execute

make_them_sing($animal_one);
make_them_sing($animal_two);

echo "<br />";

function sing_animal(Animal $singing_animal){
	
	$singing_animal->sing();
	
}

sing_animal($animal_one);
sing_animal($animal_two);

// 7. Calling a static method

echo "3+5= " . Animal::add_these(3,5);

// 8. You can check the class type with instanceof

$is_it_an_animal = ($animal_two instanceof Animal) ? "True" : "False";

echo "It is " . $is_it_an_animal . ' that $animal_one is an Animal<br />';
?>
</body>
</html>

Leave a Reply

Your email address will not be published. Required fields are marked *