Nothing Special   »   [go: up one dir, main page]

Web Programming: Handling Files and Exceptions

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 25

Web Programming

Handling files and exceptions


Files and their uses
 Storing text (including
error logs) / images /
HTML templates

XML
 Universal way to Application 1 Application 2
exchange structured JSON
data, e.g. JSON, XML

 Exchanging tabular
CSV Spreadsheet
data – CSV Database
File function examples
file_get_contents, Reading / writing files
file_put_contents, file,
fopen, fgets, fgetcsv,
feof, fwrite, fputcsv,
fclose

file_exists, filesize, Checking / asking for


is_readable, information
disk_free_space
Writing and reading a file ex

Application 1 writes
a file of employee employees
Application 2 reads
details and makes
the file
it available to
application 2
Writing data to a file
 We can use: fwrite
 You need to open the file with a mode that permits
writing
Open file in append writing mode
 Example
$fileHandle = fopen("employees.txt", "ab");
$employee = "Another person";
$dept = "MCE";
Add new
fwrite($fileHandle, "$employee|$dept".PHP_EOL);
line
fclose($fileHandle);

 We could of course write to a file using data dynamically


extracted from an external source like a database if required
Logging errors
 How could we make a function that stores
errors in a log file?

Function, error_log_file.log
e.g., log_error($e) Date/time of error|error details
Date/time of error|error details
Write error date/time Date/time of error|error details
and error details to Date/time of error|error details
a file …
fopen file modes
 The first argument to fopen is the name of
the file you want to access
 The second is the file mode. These include
Mode Action(s)
rb Reading from the beginning of a file
rb+ Reading and writing from the beginning of a file
wb Writing from the beginning of a file
wb+ Reading and writing from the beginning of a file
ab Writing from the end of a file
ab+ Reading and writing from the end of a file

Note that the “b” is for binary


compatibility
Reading a file line by line
 We can use: fopen, fgets, feof and fclose. Example
 Open file and return a connection handle
$fileHandle = fopen("employees.txt", "rb");

 While not the end of the file, read a line


while (!feof($fileHandle)) {
$line = fgets($fileHandle);
if($line) {
$line = trim($line);
$part = explode('|', $line);
echo "<li>$part[0], $part[1]</li>\n";
// or e.g., write data to a database record
}
}
fclose($fileHandle);
Dan Hogdson|CIS\n
Garry Elvin|CIS\n
employees.txt
Admin bod|HR\n
CSV files
 CSV files allow sharing of tabular data among programs
 We can use:
 fgetcsv – reads a line from a CSV file and returns it as an array
containing each field in the line
 fputcsv – takes an array of values and writes them as properly
formatted CSV to a file
 We could, for example:
 Retrieve data from a database and write it as CSV-formatted
data to a file using fputcsv
 Read data from a CSV-formatted file using fgetcsv and write it to
a database

 The workshop directed learning tasks will cover CSV


Errors and exception handling
 Things go wrong!
 Exceptions are used to anticipate and handle
problems gracefully using try{} catch{}
blocks
 They are thrown when an irreparable
situation is encountered and are then caught
 They can be used both offensively and
defensively
Throw exceptions
 Throw using the Exception object
 Exception sub-classes include, e.g.,
 Exception, ErrorException, InvalidArgumentException
 Example of bad practice
$num1 = 2;
$num2 = "Garry";
if (!is_numeric($num1) || !is_numeric($num2)) {
throw new Exception("num1 and num2 are not both
numeric");
}
$result = $num1 / $num2;
Catch exceptions
 Thrown exceptions need to be caught and
handled gracefully
 As uncaught exceptions terminate the
application with a fatal error and can expose
sensitive debugging details
 So, surround code that might lead to an
exception with a try / catch block
Example with catching
try {
$num1 = 2;
Snum2 = "Garry"; Not an number! So we get an exception
if (!is_numeric($num1) || !is_numeric($num2)) {
throw new Exception("num1 and num2 are not both numeric");
}
$result = $num1 / $num2;
} catch (Exception $e){
// In a system in test mode we can echo exceptions
echo "A Problem occurred: ".$e->getMessage();
/* In a production system we could write them to a log file
instead, e.g.,
log_error($e); */
}
getMessage() is a method of
Exception that accesses system
generated exception details
An example involving PDO
try {
require_once("functions.php");
$dbConn = getConnection(); An exception could
be thrown by the
/* Code to query a database etc. function or by the
could go here */ PDO code to query
etc.
} catch (Exception $e){
/* Take some appropriate action. */
}

Wherever an exception is thrown in the try block, the catch


block will handle it
Additional Exception sub-
classes
 The SPL provides additional sub-classes for
certain situations
LogicException RuntimeException
BadFunctionCall Exception OutOfBoundsException
•BadMethodCallException OverflowException
DomainException RangeException
InvalidArgumentException UnderflowException
LengthException UnexpectedValueException
OutOfRangeException
Sub-class example
function divide ($num1, $num2) {
if (!is_numeric($num1) || !is_numeric($num2)) {
throw new InvalidArgumentException("Function
only accepts numbers");
}
return $num1 / $num2;
}

 Example adapted from php.net

Sub-class example in a function (note that you can throw


using Exception in a function as well if you need to)
Catching multiple exceptions
 You can intercept more than one type of
exception with multiple catch blocks. Example
try {
echo divide("A", 2);
} catch (InvalidArgumentException $e){
// Take some appropriate action
} catch (Exception $e){
/* Handle any other exceptions by taking some
appropriate action */
}

Note that only one catch is triggered per exception


More than one sub-class
function divide ($num1, $num2) {
if (!is_numeric($num1) || !is_numeric($num2)) {
throw new InvalidArgumentException("Function
only accepts numbers");
}
if ($num2 == 0) {
throw new RangeException("Divisor cannot be
zero");
}
return $num1 / $num2;
}

Example adapted from php.net


Catching multiple exceptions
 Adding another catch block
try {
echo divide(4, 0);
} catch (InvalidArgumentException $e){
// Take some appropriate action
} catch (RangeException $e){
// Take some appropriate action
} catch (Exception $e){
// Handle any other exceptions
}
finally block
 You can add a finally block that will always run if there where any
exceptions or not. Example

try {
echo divide(4, 0);
} catch (InvalidArgumentException $e){
// Take some appropriate action
} catch (RangeException $e){
// Take some appropriate action
} catch (Exception $e){
// Handle any other exceptions
} finally {
// Put code here that will always run
}
Handling uncaught exceptions
 We should always include try/catch around any code that may throw an
exception. However, its hard to do perfectly
 So, set a global exception handler as a safety net
 To do that you can create a custom exception handler function, e.g.,

function exceptionHandler ($e) {


/* Code to handle uncaught exceptions by taking some
appropriate action */
}

 and register it, e.g.,


set_exception_handler('exceptionHandler');
ErrorException
 PHP errors can occur for a number of reasons, including generation by
older functions (like fopen) that still trigger errors rather than exceptions,
etc.
 We can bring errors within exception handling by using ErrorException
objects. Example

/* Check if the file exists before trying to open it. If


it doesn’t, throw an ErrorException */

if(!file_exists("employees.txt")) {
throw new ErrorException("Couldn't open file");
}
$fileHandle = fopen("employees.txt", "rb");

/* The code to use the open file connection would go here */


ErrorException – global handler
 We should set a global error handler function as a safety net for PHP
errors to help ensure that all errors are brought within exception
handling by converting them into ErrorException objects
 To do that you can create a custom error handler function, e.g.,

function errorHandler ($errno, $errstr, $errfile, $errline) {


if(!(error_reporting() & $errno)) { // check error isn’t excluded by server settings
return;
}
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler('errorHandler');
Development and production
 Development
 During development it is essential to display
detailed exception messages to the browser
 Production (when a system is live)
 Display only user friendly messages like
“Something went wrong. Please try again”
 Log detailed exception information to a file for
later inspection
Development and production
Define a constant that indicates development status in a script, e.g.,
setEnv.php
define("DEVELOPMENT", true);

Script that needs to know the development status


require_once("setEnv.php");

if (defined("DEVELOPMENT") && DEVELOPMENT===true) {
/* Code to display detailed exception message,
including, e.g., $e->getMessage(), $e->getFile(),
and $e->getLine() */
} else {
// Code to display a user friendly message
// Code to log detailed exception info to a file
}

You might also like