CSCB20S Databases and Web Programming PHP Hypertext Preprocessor (PHP) PHP CSCB20 Databases and Web Apps 1 Web Programming So far, we’ve seen how HTML and CSS work together to create a Web page (HTML) with styling details applied (CSS) When you type a URL for an HTML document into a browser window, e.g. https://mathlab.utsc.utoronto.ca/…/test.html, the browser sends a request to the server (mathlab in this case), the server locates the requested file (test.html), and sends that file back to the browser to be rendered Rather than providing the name of a file in a URL, it is possible to give the name of a program, in which case, the server executes the program and sends its output back to the browser to be rendered, e.g.: PHP https://mathlab.utsc.utoronto.ca/…/hello.php CSCB20 Databases and Web Apps 2 What is PHP? PHP PHP == ‘PHP Hypertext Preprocessor’. Free and open-source, server-side scripting language designed specifically for the Web Used to generate dynamic web-pages Supported by most Web servers PHP scripts are bracketed by reserved PHP tags supports embedding of PHP scripts within HTML pages easy to learn operational behavior and common patterns for working with Web pages CSCB20 Databases and Web Apps 3 PHP Overview (cont’d) Interpreted language, scripts are parsed at run-time rather than compiled beforehand Executed on the server-side Source-code not visible to client ‘View Source’ in browsers does not display PHP code, only output produced by PHP code Various built-in functions allow for fast development Compatible with many popular databases PHP CSCB20 Databases and Web Apps 4 PHP Overview LAMP (Linux, Apache, MySQL, PHP) is a common Web application platform – all components are free, opensource Syntax Perl- and C-like syntax. Relatively easy to learn Large function library Embedded directly into HTML Interpreted, no need to compile Loosely typed, like Python and JavaScript PHP CSCB20 Databases and Web Apps 5 Why PHP? PHP is but one of many server-side languages for developing dynamic Web app’s, other options include: PHP Java Servlets with JSP, Ruby on Rails, ASP .Net Why choose PHP? easy deployment – no complex infrastructure to set up compatible: supported by most popular Web servers simple: lots of built-in functionality; familiar syntax free and open source: anyone can run a PHP-enabled server free of charge available: installed on most commercial Web hosts, and on UTSC servers, including mathlab CSCB20 Databases and Web Apps 6 PHP Web Page Request Lifecycle PHP CSCB20 Databases and Web Apps browser requests .html file (static content); server sends file content browser requests .php file (dynamic content); server reads file, executes any embedded script content, sends output of script back to browser. 7 What does PHP code look like? Structurally similar to C/C++, Java Supports procedural and object-oriented paradigms All PHP statements end with a semi-colon Each PHP script must be enclosed in the reserved PHP tag, denoted by <?php … ?> PHP PHP code block may contain statements, function definitions, variable-value references CSCB20 Databases and Web Apps 8 Hello World in PHP <!-– hello.php --> <html><body> <strong>Hello World!</strong><br /> <?php print "<h2>Hello, World</h2>"; ?> </body></html> Output generated by PHP “print” and “echo” statements is inserted into the HTML returned to the browser How do you view the output of a PHP script from a browser? Place hello.php in your cscb20w13_space directory, then view in a browser with URL: https://mathlab.utsc.utoronto.ca/cscb20w13/UTORid/hello.php PHP CSCB20 Databases and Web Apps 9 Variables in PHP PHP variables begin with a “$” sign, both for declaration and value reference Case-sensitive ($Foo != $foo != $fOo) Global and locally-scoped variables Certain variable names reserved by PHP PHP global variables can be used anywhere local variables restricted to a function or class Form variables ($_POST, $_GET) Server variables ($_SERVER) Etc. CSCB20 Databases and Web Apps 10 Variable Usage and Comments <?php $foo = 25; $bar = “Hello”; // Numerical variable // String variable $foo = ($foo * 7); $bar = ($bar * 7); ?> single-line comments are written as one of: PHP // Multiplies foo by 7 // Invalid expression // single-line comment # single-line comment multi-line comments bracketed by /* multi-line comment ... */ CSCB20 Databases and Web Apps 11 Data Types PHP is a loosely-typed language, like Python PHP basic types are: Conversion between types is automatic in many cases, e.g.: int, float, boolean, string, array, object, NULL functions is_type() test whether a variable has a certain type, e.g. is_string($myvar) string to int for “+” int to float for “/” types can be “cast” to another type using: PHP $int_val = (int) “33”; CSCB20 Databases and Web Apps 12 Strings $myvar = "hello"; print $myvar[1]; # prints “e” square bracket notation for 0-based indexing catenation using “.” operator (not “+”) print $myvar . "world"; # prints hello world strings quoted with double quotes are “interpreted”, meaning that embedded variables have their values inserted strings quoted with single quotes are not interpreted print "$myvar world"; # prints hello world print '$myvar world'; # prints $myvar world PHP CSCB20 Databases and Web Apps 13 for loop for (initialization; condition; update) { statements } uses same syntax as Java for ($i = 10; $i >= 0; $i--) { print "$i cubed is " . $i * $i * $i . ".\n"; } PHP CSCB20 Databases and Web Apps 14 for loop for (initialization; condition; update) { statements } uses same syntax as Java $name = "preprocessor"; for ($i = 0; $i < strlen($name); $i++) { print "The next letter is".{$name[$i]}\n"; } PHP CSCB20 Databases and Web Apps 15 if/else statement if (condition) { statements; } elseif (condition) { statements; } else { statements; } PHP <?php if ($user==“John”) { print “Hello John.”; } else { print “You aren’t John.”; } ?> elseif clause and else clause are both optional multiple elseif clauses may be used CSCB20 Databases and Web Apps 16 while same syntax as Java while (condition) { statements; } Loops or do { statements; } while (condition) <?php $count=0; while($count<3) { print “hello PHP. ”; $count += 1; // or // $count = $count + 1; // or // $count++; } ?> hello PHP. hello PHP. hello PHP. PHP CSCB20 Databases and Web Apps 17 Arrays $myvar = array(); # create new array $myvar = array(val0, val1, ..., valN); $myvar[index]; # element at position index $myvar[index] = val0; # assign element at index $myvar[] = valN; # append valN $a1 = $a[2] $a2 = $a2[] PHP array(); # empty, length-0 array = 12; # store 12 in 3rd position of array array("a", "sequence", "of", "strings"); = "the end"; # new last element of $a2 CSCB20 Databases and Web Apps 18 foreach loop foreach ($array as $element) { ... } Similar to Python’s: for element in array: Simpler than regular “for” loop when using arrays $a = array("a", "sequence", "of", "strings"); for ($i = 0; i < count($a); $i++) { print "the next word is {$a[$i]}\n"; } foreach ($a as $element) { print "the next word is $element\n"; } PHP CSCB20 Databases and Web Apps 19 Embedded PHP We could use PHP print and/or echo statements to generate HTML output, e.g. <?php print "<html>\n<head>\n"; print "<title>PHP Squares</title>\n"; ... for ($i = 0; i <= 10; $i++) { print "<p>$i squared is $i*$i</p>\n"; } ?> What’s wrong with this approach? Suppose you want to change the page HTML … PHP CSCB20 Databases and Web Apps 20 Embedding PHP in HTML Rather than using PHP print/echo statements to generate HTML, write HTML literally, and when scripting is needed to compute a value, embed PHP code. General format of a PHP script written within HTML file: HTML elements ... <!-- output as HTML --> <?php PHP code ... # output embedded within HTML ?> HTML elements ... <?php PHP code ... ?> HTML elements ... PHP CSCB20 Databases and Web Apps 21 Embedding PHP in HTML General format of a PHP script written within HTML file: HTML elements ... <!-- output as HTML --> <?php PHP code ... # output embedded within HTML ?> HTML elements ... The PHP code in an embedded block may consist of statements, declarations, or expression values Here’s a sample expression block: <?= $myvar ?> which is equivalent to <?php print $myvar; ?> PHP CSCB20 Databases and Web Apps 22 Embedding PHP in HTML Here’s our earlier “squares” calculator, now without print statements: <html><head> <title>PHP Squares</title> ... <?php for ($i = 0; $i <= 10; $i++) { ?> <p><?= $i ?> squared is <?= $i*$i ?> </p> <?php } ?> ... </html> PHP CSCB20 Databases and Web Apps 23 Functions Functions must be defined before then can be called Function headers are of the format function functionName($arg_1, $arg_2, …, $arg_n) note that no return type is specified function quadratic($a, $b, $c) { return -$b + sqrt($b*$b - 4*$a*$c) / (2*$a); } $x = -2; $y = 3; $root = quadratic(1, $x, $y-2); Unlike variables, function names are not case sensitive foo(…) == Foo(…) == FoO(…) PHP CSCB20 Databases and Web Apps 24 Query Strings and Parameters We refer to Web pages using URL’s (Uniform Resource Locators), of the form http://domain_name/path_value We can specify parameters to PHP scripts by appending a value to the end of the URL: http://www.google.com/search?q=android https://mathlab…./cscb20w13/utorid/rancid.php?film=vampire Parameter name=value pairs follow the “?” at the end of the URL path_value, in 2nd example param name is film, value is vampire Provides a mechanism by which a user can control/customize the behavior of a server-side PHP script PHP CSCB20 Databases and Web Apps 25 Query Strings and Parameters PHP can retrieve parameter values using the $_REQUEST array $_REQUEST["parameter_name"] returns the parameter’s value as a string Can check to see if a specific parameter is set using isset() $country_name = $_REQUEST["country"]; $population = (int) $_REQUEST["population"]; if (isset($_REQUEST["code"])) { $code = (int) $_REQUEST["code"]; } else { $code = -1; } PHP CSCB20 Databases and Web Apps 26 Reading Files Two ways to read the contents of a text file: 1. file(“my_file.txt”); returns array of lines in my_file.txt 2. file_get_contents(“my_file.txt”); returns a single string containing all lines in my_file.txt <?php # display lines from file as a bulleted list $cities = file("cities.txt"); foreach ($cities as $city) { ?> <li> <?= $city ?> </li> <?php } ?> PHP CSCB20 Databases and Web Apps 27 Unpacking Arrays, Splitting Strings Sometimes it is useful to be able to refer to the elements of an array by individual variable names, rather than using indices $movie_info = file("info.txt"); list($title,$year) = $movie_info; # now can use $title rather than $movie_info[0] A string consisting of delimited values can be split (same idea as in Python) $title = "Databases and Web Programming"; $words = explode(" ", $title); PHP CSCB20 Databases and Web Apps 28 Reading Directories If your application needs to read from a set of files in a directory, how can your code automatically detect and read the specific files present? glob enables you to use pattern matching to select files $notes = glob("note_*.txt"); foreach ($notes as $note) { print $note; } * is just one of several “regular expression” patternmatching forms (others include matching on character ranges, matching digits, optional characters) PHP CSCB20 Databases and Web Apps 29 Web Services In Assignment 2 we used PHP embedded within an HTML document to implement dynamic HTML content However, HTML is only one of several kinds of data a server could produce for use by a client A Web service refers to use of the Web’s HTTP protocol to invoke programs and retrieve their results The general idea is that we should be able to call programs using URL references, just as we do to refer to Web pages Like traditional functions, Web-service programs can take parameters and produce results, which may be written as HTML, but also as XML, JSON, plain text, or other formats PHP CSCB20 Databases and Web Apps 30 Web Services and PHP The type of output produced by a Web service must be explicitly specified, since it can take different forms – essentially, the client needs to know how to interpret the byte values returned by the server HTTP, the Internet protocol used for Web URL requests and responses, provides a “Content-type” header for this purpose In PHP, the “type” of the result value(s) defaults to HTML (“text/html”), but can be explicitly specified using: header("Content-type: type/subtype"); The header() function must be called before a PHP script generates any output (since the client who called the script needs the header information to interpret that output) PHP CSCB20 Databases and Web Apps 31 MIME Content-Types MIME types are used to communicate the type of data sent by a server to a client (e.g. a jpeg image, or an html file), and vice versa (e.g. a file upload from a client) MIME types are specified in two parts: “type/subtype”, e.g.: MIME type text/plain text/html text/css application/json image/png image/jpg text/javascript PHP related file extension .txt .html, .htm, ... .css .png .jpeg, .jpg, .jpe .js CSCB20 Databases and Web Apps 32 A PHP Web service Let’s examine a simple example of a PHP Web service that take “base” and “exp” parameters, and returns the base raised to the exp (exponent) power. A URL to invoke this service might look like this: https://mathlab…/cscb20w13/utorid/power.php?base=5&exp=3 PHP How would we implement this service in PHP? <?php header("Content-type: text/plain"); $base = (int) $_GET["base"]; $exp = (int) $_GET["exp"]; $result = pow($base, $exp); print $result; ?> CSCB20 Databases and Web Apps 33 Web Service Errors When implementing a Web service, we must make provision for errors, such as omission of a required parameter or an invalid parameter value. E.g. https://mathlab…/utorid/power.php?base=5&exp=w https://mathlab…/utorid/power.php?base=5 How should such an error be reported? We could return an HTML error message, but what if the client (caller) takes the result and displays it in a result <div> on their Web page, now they display an opaque error message where the user expects a number We need a mechanism that will enable the caller to detect that the result is an error, as opposed to a result value. PHP CSCB20 Databases and Web Apps 34 HTTP Status Codes The Web’s HTTP protocol provides a mechanism for signaling the outcome of a request, that can be used for both ordinary Web pages (e.g. 404 Not Found), and for Web services (e.g. 400 illegal request) HTTP code 200 301-303 400 401 403 404 410 500 PHP Meaning OK page has moved (temporarily or permanently) illegal request authentication required you are forbidden to access this page page not found gone; missing data or resource internal server error CSCB20 Databases and Web Apps 35 A Web Service with Error Handling We could rewrite the power() Web service to detect missing or invalid parameters as follows: <?php $base = $_GET["base"]; $exp = $_GET["exp"]; if (is_numeric($base) and is_numeric($exp)) { header("Content-type: text/plain"); ... as before for valid input ... } else { header("HTTP/1.1 400 Invalid Request"); die("invalid request; required parameters"); } ?> PHP CSCB20 Databases and Web Apps 36 Web Service Output Types So far, our Web service examples have output values expressed as MIME type text/plain. More commonly, a Web service invoked from a Web page will return an HTML fragment, XML data, or JSON data. Why an HTML fragment? Because normally the result returned by a Web service will be inserted into an existing HTML document, e.g. as the content of a <div> PHP CSCB20 Databases and Web Apps 37 Web Service Output Types Suppose we want to generate an HTML list of factorial values, up to a user-supplied value of “n”: <?php header("Content-type: text/html"); $limit = (int) $_GET["n"]; $fact = 1; for ($i = 1; $i < $limit; $i++) { ?> <li>Factorial of <?= $i ?> is <?= $fact ?> </li> <?php $fact = $fact * $i; } ?> PHP Later we’ll look at how an HTML fragment, like the one generated by this script could be inserted into a Web page CSCB20 Databases and Web Apps 38 JSON Data JSON, JavaScript Object Notation, is a string-based representation of JavaScript array and dictionary objects, that is a popular way to communicate structured data to (input) and from (output) Web services A JSON dictionary is written: { A JSON array is written: [ value1, value2, … ] "field0": "value0", "field1": "value1", ... } PHP Values can be primitive types such as numbers and strings, and can also be arrays and dictionaries nested arbitrarily CSCB20 Databases and Web Apps 39 JSON Data For example: { "id": "cd1", "title": "Sgt. Pepper", "band": "The Beatles", "price": 22.00 } Note that JSON is strict about the presence of quotes around keys and values that are strings. A malformed JSON string will not be interpreted by JavaScript and will fail silently We will use the JSONLint tool to detect such errors PHP CSCB20 Databases and Web Apps 40 Outputting JSON Data When outputting JSON from PHP, you could use print statements; e.g. for the above JSON example: <?php header("Content-type: application/json"); print "{\n"; print " \"id\": \"cd1\",\n"; print " \"title\": \"Sgt. Pepper\",\n"; print " \"band\": \"The Beatles\",\n"; print " \"price\": 22.00,\n"; print "}\n"; ?> PHP As was the case with manually outputting PHP, this approach is discouraged: hard to read and maintain code CSCB20 Databases and Web Apps 41 Outputting JSON Data PHP provides global functions for converting JSON string representation to/from a PHP (associative) array object: json_decode(string) json_encode(object) # returns PHP object # returns JSON string value For example: <?php $json = array( "id" => "cd1", "title" => "Sgt. Pepper", "band" => "The Beatles", "price" => 22.00); header("Content-type: application/json"); print json_encode($json); ?> PHP CSCB20 Databases and Web Apps 42 Working with Databases In B20, we are using the MySQL database part of the widely deployed LAMP (Linux, Apache, MySQL, PHP) open-source suite for implementing Web sites Wikipedia, for example, runs on MySQL and PHP PHP’s PDO (PHP Database Object) database library is an abstraction layer that improves code reuse by enabling the same PHP code to work with different database engines, such as MySQL, Oracle, PostgreSQL $db = new PDO("db:dbname=db;host=server",user,pwd); $db -> query("SQL query string"); PHP CSCB20 Databases and Web Apps 43 PDO Object Methods Name query Description performs an SQL SELECT query on the database exec performs an SQL query that modifies the database (INSERT, DELETE, UPDATE, etc.) getAttribute, get/set various DB connection properties setAttribute quote encodes a value for use within a query PHP CSCB20 Databases and Web Apps 44 PDOStatement Methods A PDO query() result is not actually an array, but rather a PDOStatement object. Methods that apply to this type: Name columnCount( ) Description number of columns in the results fetch( ) return the next row from the results fetchAll( ) return an array containing all result rows fetchColumn(number) return the next column from the results rowCount( ) number of rows returned by the query if ($pdo -> rowCount() > 0) { $first_row = $pdo -> fetch(); } PHP CSCB20 Databases and Web Apps 45 Example: DB Results as HTML PDO example – render Cities table query as HTML list items: <?php $pdo = new PDO("mysql:host=$dbhost; dbname=$dbname", $dbuser, $dbpass); $cities = $pdo -> query(“SELECT * FROM Cities WHERE population > 9000000;"); foreach ($cities as $city) { ?> <li>City: <?= $city["name"] ?>, Population: <?= $city["population"] ?> </li> <li>City: Sao Paulo, Population: 9968485 </li> <?php } # foreach ?> PHP <li>City: Jakarta, Population: 9604900 </li> <li>City: Mumbai (Bombay), Population: 10500000 </li> … CSCB20 Databases and Web Apps 46 Example: DB Results as JSON Using a database query to produce JSON results: <?php $pdo = new PDO("mysql:host=$dbhost; dbname=$dbname", $dbuser, $dbpass); $stmt = $pdo -> query("SELECT * FROM Cities WHERE population > 9000000;"); $cities = $stmt->fetchAll(PDO::FETCH_ASSOC); $json = json_encode($cities); print $json; ?> [ {"id":"206","name":Sao Paulo, "country_code":"BRA", "district":null,"population":"9968485"}, {"id":"939","name":"Jakarta","country_code":"IDN","district ":"Jakarta Raya", "population":"9604900"}, … ] PHP CSCB20 Databases and Web Apps 47 User-Supplied Input in Queries A common requirement is that the user of an app be able to control the DB query by providing an input value that will be included in the query: <?php $film = $_GET["film"]; # user-supplied film name $stmt = $pdo -> query("SELECT * FROM movies WHERE name = '$film'"); ?> PHP There’s a problem here, can you spot it? Suppose user types an invalid parameter value, e.g. film=' User can include illegal characters, or change meaning of SQL statement! This is the basis for “SQL Injection attacks”. CSCB20 Databases and Web Apps 48 User-Supplied Input in Queries PDO’s quote() method should be called on any values quote() “escapes” illegal characters, surrounding them with quote characters (') Prevents user input from changing the meaning of query strings – the basis for SQL-injection attacks <?php $film = $_GET["film"]; # user-supplied film name $film = $pdo -> quote($film); $stmt = $pdo -> query("SELECT * FROM movies WHERE name = $film"); ?> PHP CSCB20 Databases and Web Apps 49 Dealing with Failure PDO commands fail for a variety of reasons, e.g. an invalid query, DB connection fails, DB does not respond to query) PDO commands return FALSE or NULL on failure, but have to remember to check for these special result markers; better alternative is to tell PDO to throw an exception on failure: $film = $_GET["film"]; # user-supplied film name $film = $pdo -> quote($film); # Tell PDO to throw PDOException if error occurs. $db -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo -> query("SELECT * FROM movies WHERE name = $film"); PHP CSCB20 Databases and Web Apps 50 Dealing with Failure When a PDO throws a PDOException, it will appear as an error message on the PHP output Usually preferable to catch exceptions, to enable clean handling of the failure, rather than showing the user an unintelligible error message try { ... $stmt = $pdo -> query("SELECT * FROM movies WHERE name = $film"); } catch (PDOException $e) { ?> <p>Sorry, a database error occurred ...</p> <p>(details: <?= $e -> getMessage() ?>)</p> ... PHP CSCB20 Databases and Web Apps 51