setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $db; } catch (PDOException $ex) { # An error may occur here if the db connection is down (it happens), the connection variables # are incorrect for the machine this PHP file is being ran on, etc. Note that don't usually want to # output specific information from the $ex variable, since the client should really know # about information in our database, so we make a generic message. handle_db_error(); } } /** * Prints out a JSON 400 error message with a key of "error" and a value as the given $msg. * Remember that 400 indicate an invalid request from a client, but that should be separate from * any PDO-related (database) errors. Use handle_db_error for anything related * to the database. * @param $msg {string} - message to output details of invalid request. */ function handle_request_error($msg) { process_error("HTTP/1.1 400 Invalid Request", $msg); } /** * Prints out a JSON 503 error message with a key of "error". * If given a second (optional) argument as an PDOException, prints details about the cause * of the exception. See process_error note about responding with PDO errors to a client. * @param $ex {PDOException} - (optional) Exception object with additional exception details */ function handle_db_error($ex=NULL) { # we can do default parameters in PHP! NULL is default if not given a second parameter. $msg = "Can not connect to the database. Please try again later."; process_error("HTTP/1.1 503 Service Unavailable", $msg, $ex); } /** * Terminates the program after printing out a JSON error message given $msg after * sending the given header error code (handy to factor out error-handling between * 400 request errors and 503 db errors). * If given an (optional) third argument as an Exception, prints details about * the cause of the exception. * * @param $type {string} - The HTTP error header string. * @param $msg {string} - Message to output. */ function process_error($type, $msg, $ex=NULL) { header($type); # e.g. "HTTP/1.1 400 Invalid Request" header("Content-type: application/json"); if ($ex) { # Note that in practice, you probably don't want to print details about your # database errors in a response to a client. But for testing your code, this can # help pinpoint bugs in your PDO functions/database connections. echo ("Internal error details: $ex \n"); } $error_json = json_encode(array("error" => $msg)); die($error_json); # die will print the argument and terminate the program. } /** * Outputs a message in the format: { "success" : } * @param {string} $msg - string message that will be value of "success" key in response. */ function output_success($msg) { $result = array("success" => $msg); header("Content-type: application/json"); echo json_encode($result); } /** * Checks whether the given $money value is valid (non-negative), terminating with a 400 * error and JSON message if not. * @param {number} $money - value to check/handle non-negative money value errors. */ function check_negative($money) { if ($money < 0) { handle_request_error("Price and cost should be non-negative."); } } /** * * Returns true if an item with the given name is in the menu table, otherwise false. * Note that we pass $db as a parameter here because we don't want to construct another * one unecessarily (e.g. if this function is used before an INSERT query). * @param {PDO} $db - PDO object connected to cafedb * @param {string} $name - name of item to check in menu (case-insensitive in MySQL!) * @return {array|boolean} array with name, price, cost key/value pairs if item was found, * otherwise false. */ function find_item($db, $name) { $qry = "SELECT name, price, cost FROM menu WHERE name = :name"; $stmt = $db->prepare($qry); $stmt->execute(array("name" => $name)); return $stmt->fetch(); # returns false if no result, otherwise an associative array with name, price, cost } ?>