===== 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)