=====
CS 328 - recorded for Week 9 Lecture 2 - recorded for 2024-03-20
=====

=====
TODAY WE WILL
=====
*   announcements
*   more PHP basics,
    including variable interpolation,
    some basic control structures,
    and hopefully our first PHP that responds to a form!

=====
*   Should be working on Homework 7,
    first attempts must be submitted by 11:59 pm on Sunday, March 24

*   Remember that there will be a lab exercise for Friday, March 22,
    that you can do individually or as a pair, due by 11:59 pm on
    Friday, March 22
    *   I will send out a class e-mail when it is available.

=====
Variable Interpolation in PHP
=====
*   we said you can write a string literal in PHP using either
    single or double quotes:

    'moo'   "moo"

    *   but that there is an interesting difference between
        using single and double quotes

*   here's that difference!

    Consider: what if you wanted to build a string and include
    a variable's value?

    *   you could concatenate the desired string and the desired
        variable

        BUT PHP uses Perl's concatenation operator, which is a period

        $a_variable = "something";
        $my_variable = 'abc'.$a_variable."def";

        // $my_variable would now be "abcsomethingdef"

   *   BUT -- when a variable appears within a double-quoted
       string, you get something called variable interpolation,
       where the variable is replaced by its value in that string

       $another_var = "abc $a_variable def";

       // $another_var would now be "abc something def"

   *   in a single-quoted string, the variable is not seen as
       a variable, but just a $ character and other characters

       $yet_another = 'abc $a_variable def';

       // $yet_another would now be 'abc $a_variable def'

=====
a few words on PHP errors and debugging them
=====
*   what if your PHP has some kind of problem or error?

*   On the server -- on the application tier -- there is a file
    named php.ini that has configuration settings for PHP on that system

    *   on nrs-projects, this file is world-readable, and it is in
        the /etc directory:

        more /etc/php.ini

*   the kind of error reporting you get is determined here --
    during development, you want all of the error messages,
    and to get those, you set display_errors to On

    in production, though, you tend to not want those gory details
    displayed -- you set display_errors to Off

    *   as of 2024-03-19, nrs-projects's /etc/php.ini has this set to
        Off

*   Happily, nrs-projects DOES support the ability for a single
    PHP document to request that error reporting be turned on
    (for that one document) even if php.ini has display_errors
    set to Off:

    in the first PHP tag in the document, put:
    <?php
        ini_set('display_errors', 1);
        error_reporting(E_ALL);
    ?>

    ...and you can add this during development, and remove it
    when the page is production-ready;

*   the zyBooks Chapter 5 (coming soon, honest!!) mentions FOUR
    types of PHP error messages:
    *   parse error - syntax error when the page is compiled by the
        PHP preprocessor (e.g., a missing semicolon)

    *   fatal error - runtime error that halts execution of the
        script

    *   warning - runtime error that does not halt execution of the
        script

    *   notice - runtime message of a possible logic error

*   (we demo'd examples of some of these "live" --
    see the posted recording!)

=====
some PHP DEBUGGING tips!
=====
*   if you get a previously-displayed page now giving a message
    about the page not being working,

    try running it command-line style, using the php command,
    to get a parse error's error message:

    php my-sad-page.php

*   try to run small iterative chunks of your PHP documents frequently
    (run early and often, makes errors easier to find!)

*   use tested-and-known-working helper functions as often as possible

*   in a page that is not running,
    where running it on the command line is not giving a useful error message,

    carefully use multi-line comments /* */ to comment large swaths of
    PHP until the page displays something again,
    then gradually uncomment bits until it stops working
    so you can at least locate which statements are causing a problem

*   if you have a PHP tutorial that allows you to enter PHP fragments,
    you can try pasting in your problem code, and *sometimes* helps!

*   and remember: YOU CANNOT RUN PHP FROM THE CLIENT TIER...

=====
PHP if statement
=====

if (bool_expr)
{
    desired_statements;
    ...
}
elseif (bool_expr)
{
    ...
}
...
else
{
    ...
}

*   INTERESTING mind-blowing PART:
    YOU CAN JUMP IN and OUT of php in the course of an if statement
    or any other PHP control structure --

    (to include swaths of boilerplate, for example)

    if ($this == $that)
    {
    ?>
        <p> Hey looky! </p>
    <?php
    }
    else
    {
    ?>
        <ul>
            <li> O really? </li>
            <li> Yeah! </li>
        </ul>
    <?php
    }

=====
several PHP loops!
=====
*   while loop

    while (bool_expr)
    {
        desired_stmts;
    }

*   for loop

    for (init_part; bool_expr; update_part)
    {
        desired_stmts;
    }

    for ($i = 1; $i < 5; $i++)
    {
         ....
    }

*   at least two kinds of foreach loops

    =====
    fun fact: you can write an array using square brackets

    [10, 20, 30]    // initialize an indexed array

    ["a" => 1, "b" => 2, "c" => 3] // initialize an associative array
    =====

    =====
    for an indexed array: iterate over it using:
    =====
    foreach ($indexedArray as $value)
    {
        ... $value ...
    }

    =====
    for an associative array: iterative over it using:
    ====
    foreach ($assocArray as $key => $value)
    {
        ... $key ... $value ...
    }

=====
PHP - interacting with forms, postback style!
=====
*   ONE PHP document can generate multiple different pages --
    for example, it can generate a form, and then later the response
    to that form;

    zyBooks: "A postback is a form that posts back to the same
             URL as the form."

    *   instead of, say, having an .html page with a form
        whose action is the PHP responding to that form...

*   also want to know: PHP has some special associative arrays
    called superglobal associative arrays
    *   why associative? have strings as their keys
    *   why superglobal? they are visible in all of the PHP code

    *   they are all named in all-uppercase starting with an underscore

    *   here are three classic examples:

        $_GET will be filled with the name=value pairs submitted
        by a form whose method="get"
        *   name will be the array key
        *   value will be the array value

        $_POST will be filled with the name=value pairs submitted
        by a form whose method="post"
        *   name will be the array key
        *   value will be the array value

        $_SERVER has useful server-related information in it
        *   for example:
            key "REQUEST_METHOD" has the value "GET" or "POST"
            $_SERVER["REQUEST_METHOD"] has the value "GET" or "POST"

            *   fun fact: a first request of a document has a default
                $_SERVER["REQUEST_METHOD"] of "GET"

        *   key "PHP_SELF" has the URL of the requesting page
            $_SERVER["PHP_SELF"] has this URL!

=====
CROSS-SITE SCRIPTING
=====
*   (simplest version)
    user enters scripting into a form and it is used in the result

*   ONE of the approaches to handling cross-site scripting
    is to NEVER trust user-supplied code --

    NEVER DISPLAY UNMODIFIED EXTERNAL INPUT.
    (and don't let it into your database, either...!)

    validate it! (check it to see if is reasonable)
    and/or
    sanitize it! (try to remove or render unexecutable any bad bits)

*   PHP provides some tools to help with this:

    strip_tags - function that expects a string argument,
        removes anything that looks like an HTML tag from that argument
        and returns the resulting string

    htmlspecialchars - function that expects a string argument,
        converts HTML special characters from that to display-only
        versions of those characters
        (e.g., < is converted to < ) and returns the resulting string

    htmlentities - goes even further, converts several more possibly-dangerous
        characters to display-only versions; has a second argument that
        is a bitmask of a set of flags specifying how to handle quotes
        and more (see https://www.php.net/manual/en/function.htmlentities.php);

        e.g., ENT_QUOTES specifies to convert both single and double quotes

        *   interestingly, $_SERVER["PHP_SELF"] can be hacked,
            and so it is considered good practice to use htmlentities
            with the flaf ENT_QUOTES to sanitize that:

        action="<?= htmlentities($_SERVER["PHP_SELF"], ENT_QUOTES) ?>">

*   CS 328 CLASS STYLE:
    always validate and/or sanitize external user-provided input!
    (and we'll use htmlentities as shown above for postbacks that use
    $_SERVER["PHP_SELF"] for form actions)