MySQL Enterprise Solutions phần 5 ppt

42 233 0
MySQL Enterprise Solutions phần 5 ppt

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

the C API, you do not have to worry about buffer size. PHP again comes to the rescue, and, depending on your viewpoint, you can say that it either frees pro- grammers from thinking about annoying low-level implementation details and allows them to focus on the core of the problem, or, as some would say, allows lazy and sloppy programmers to produce working code without correcting their evil ways—and thus reinforcing the bad habits. Sample Code For the sample application, I have chosen to write the Web version of our com- mand-line inventory program from Chapter 8. Due to the Web nature of the code, a good portion of it is dedicated to HTML generation and user form input processing. Although this may distract you from the database-manipulation techniques, which is our primary goal, I believe that since most uses of PHP are Web related—and database programming is tightly coupled with the Web inter- face—it is only natural to study HTML integration along with the database programming. To see the application in action, copy sample.php from the Web site into a Web- accessible directory on your Web server, make sure MySQL is installed and run- ning on the same system, and then type http://webserver-hostname/path/to/sample.php replacing the placeholder tokens with the actual values; for example, http://localhost/learn-mysql/sample.php. You will see a menu of options. The first thing you need to do is select Initialize Database. Afterward, you may add, view, delete, and update records, as well as view the totals. Listing 9.1 contains the sample code with my comments. It is my hope that the comments inside the code will help you understand the code, but see the section that follows for a further discussion. PHP Client Basics 148 <? // auxiliary variable for proper HTML generation $html_started = 0; // The line below tells PHP not to automatically escape user input values with quotes, since we will be escaping them ourselves in the // code. ini_set("magic_quotes_gpc","0"); // Enable error tracking. We need this to have MySQL error in // $php_errormsg in case mysql_connect() fails. ini_set("track_errors","1"); Listing 9.1 Source code of sample.php. (continues) Sample Code 149 // database connection parameters $mysql_user = "root"; $mysql_host = "localhost"; $mysql_pass = ""; $mysql_db = "test"; // This class is used for the drop-down list during HTML form // generation. No rocket science involved, but very convenient. class form_option { // Class members var $text, $val; // A very boring constructor function form_option($val_arg,$text_arg) { $this->text = $text_arg; $this->val = $val_arg; } // The name of this method should be self-explanatory function print_html($selected_val) { // Note that this method allows us to preselect items of our // choice by default. if ($this->val == $selected_val) $selected = "selected"; echo("<option value=\"$this->val\" $selected>$this->text</option>"); } } // Helper function to generate the HTML for a submit button function submit_button($name, $text) { echo("<input type=submit name=$name value=\"$text\">"); } // Helper function to generate HTML for a drop-down list // Note that we assume that $opts is an array of form_option objects. function select_input($name, $prompt,$opts) { global $action; echo("<table><tr><td>$prompt</td><td><select name=$name>"); $len = count($opts); for ($i = 0; $i < $len; $i++) { Listing 9.1 Source code of sample.php. (continues) PHP Client Basics 150 $opts[$i]->print_html($action); } echo("</select></td><td>"); submit_button("${name}_submit","Go!"); echo("</td></tr></table>"); } // Function to generate a form with a drop-down menu prompting the // user to select an action function menu_form() { echo("<form method=post>"); // After we have written some rather tedious auxiliary HTML code, // now we can generate a drop-down HTML input with appropriate // default preselection of items quite easily. The dirty work is // finally paying off. select_input("action","Select Action:", array(new form_option("init","Initialize Database"), new form_option("add", "Add Record"), new form_option("delete","Delete Record"), new form_option("select","Select Record"), new form_option("update", "Update Record"), new form_option("show_totals","Show Totals") )); echo("</form>"); } // Helper function to generate customized HTML at the top. function html_start($title) { // Do not generate it if we have already done it earlier. if ($html_started) return; echo("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); echo("<html><head><title>Sample Inventory Application - $title</title> </head>"); echo("<body><h1>$title</h1>"); // Ensure that this function will be called only once by setting a // special flag. As you can see, we check this flag in the first // statement. $html_started = 1; Listing 9.1 Source code of sample.php. (continues) Sample Code 151 } // Helper function to generate the standard bottom HTML function html_end() { echo("</body></html>"); } // Function for gracious abort with a properly written message. function error_exit($msg) { if (!$html_started) html_start("Error"); echo("Fatal error: $msg"); exit(); } // Function to connect to the database, and select the default one for // this application, checking for errors and if any discovered, abort // with an error message. We assume that the caller is always pleased // with our error handling and does not want us to return if we are // not successful. function safe_connect() { global $mysql,$mysql_host,$mysql_user,$mysql_pass,$mysql_db, $php_errormsg; // Note the @ in front of MySQL API calls. This prevents PHP // from automatically spitting out the error message in the HTML // output if the call fails. $mysql = @mysql_connect($mysql_host,$mysql_user,$mysql_pass); if (!$mysql) error_exit("Could not connect to MySQL: $php_errormsg"); if (!@mysql_select_db($mysql_db,$mysql)) error_exit("Could not select database $mysql_db:".mysql_error($mysql)) ; } // Safety wrapper function for mysql_query(). We take care of the // error handling here. The assumption is that the caller expects this // function to succeed and is satisfied with just aborting on error. function safe_query($query) { global $mysql; // Again, note @ before mysql_query() to prevent an error message // "spill" to the user. We want to control how the message is // printed in case of error. if (!($res=@mysql_query($query,$mysql))) error_exit("Failed running query '$query': ".mysql_error($mysql)); Listing 9.1 Source code of sample.php. (continues) PHP Client Basics 152 return $res; } //Another convenience wrapper function for error messages. As the name //suggests, signals to the user that there was an error in the entered // data. function input_error($msg) { echo("<font color=red>Input error:</font>$msg<br>"); } //Helper function to prompt the user to select a record by entering //the record id. function pick_record_form() { global $action; // If the record is being picked for update or delete, we do not // want to give the user the options of picking all records. // However, this is an option if the user just wants to view the // record(s). if ($action == "select") $empty_for_all = "(empty for all)"; // Note the use of hidden inputs to pass messages about the current // state of the application. echo("<form method=post><input type=hidden name=record_selected value=1> <input type=hidden name=action value=\"$action\"> <table><tr><td>Record id $empty_for_all:</td> <td><input name=record_id type=text size=5></td> <td><input type=submit name=submit value=\"Submit\"></td> </table></form>"); } // Helper function for generating form HTML. Generates a table row // consisting of a prompt with the input name, followed by the text // input itself. function table_input($prompt, $name,$size) { echo("<tr><td>$prompt</td><td><input type=text name=$name size=$size value=\"".$GLOBALS[$name]."\"></td></tr>"); } // Another HTML generating helper. Writes out the HTML for the entire // record form, pre-populating the fields if the record has been // retrieved from the database already, or if the user has partially // entered the data but made some errors or omissions. Again, note the // use of hidden fields for state tracking. Also note the use of // table_input() and submit_button() helpers, which make the code much Listing 9.1 Source code of sample.php. (continues) Sample Code 153 // less cumbersome, easier to read, and easier to modify. function record_form() { global $record_id,$action; echo("<form method=post><input type=hidden name=action value=\"$action\"> <input type=hidden name=record_id value=\"$record_id\"> <input type=hidden name=record_entered value=1> <table>"); table_input("Name","name", 15); table_input("Quantity","quantity", 5); table_input("Price", "price", 6); echo("<tr><td>"); submit_button("submit","Submit"); echo("</td></tr>"); echo("</table></form>"); } // Helper function to generate HTML for buttons in the record view // provided by "Select Record" to prompt the user to update or delete // the displayed record. function td_form($record_id,$text,$action) { echo("<td><form method=POST><input type=hidden name=record_id value=$record_id><input type=hidden name=action value=\"$action\"> <input type=submit name=submit value=\"$text\"> </form></td>"); } // Now the validation functions. Each of them returns TRUE if the // respective input element was valid. Otherwise, it prints the // appropriate error message about the input error and returns FALSE. // // Note the use of trim() to remove the heading and trailing space, // and the intended side effect of setting the corresponding global // value in all three of the functions, which we need to do manually, // since we do not want to assume that register_globals is set to ON. function validate_name() { global $name; if (!strlen(($name=trim($_POST["name"])))) { input_error("Empty name"); return FALSE; } return TRUE; Listing 9.1 Source code of sample.php. (continues) PHP Client Basics 154 } function validate_price() { global $price; $price = trim($_POST["price"]); if (!strlen($price)) { input_error("Empty price"); return FALSE; } if (!preg_match("/^\d+(\.\d{1,2}){0,1}/",$price)) { input_error("Invalid price"); return FALSE; } return TRUE; } function validate_quantity() { global $quantity; $quantity = trim($_POST["quantity"]); if (!strlen($quantity)) { input_error("Empty quantity"); return FALSE; } if (!is_numeric($quantity)) { input_error("Invalid quantity"); return FALSE; } return TRUE; } // Convenience wrapper to combine all three functions into one call function validate_input() { return validate_name() && validate_quantity() && validate_price(); } // Helper function to fetch the record specified by global setting of // $record_id from the database and set the corresponding global // variables in accordance with the values of the fields. Note that we // assume that the caller has already set the record_id to a numeric // value, which is accomplished by get_record_id(). If the record is Listing 9.1 Source code of sample.php. (continues) Sample Code 155 // found in the database, we return TRUE, otherwise FASLE, expecting // the caller to take measures. function fetch_record() { global $record_id,$name,$quantity,$price; $res = safe_query("SELECT name,quantity,price/100 as dollar_price FROM inventory WHERE id = $record_id"); if (!mysql_num_rows($res)) return FALSE; $r=mysql_fetch_object($res); $name = $r->name; $quantity = $r->quantity; $price = $r->dollar_price; return TRUE; } // Helper function to ensure that the record id is set to a numeric // value. After it returns, global $record_id will be set to a numeric // value either entered by the user or passed through a hidden input, // and TRUE will be returned. Otherwise, the user is prompted with a // record id entry form, and FALSE is returned. function get_record_id() { global $record_id; $record_id = $_POST["record_id"]; if (!isset($record_id)) { pick_record_form(); return FALSE; } if (!is_numeric($record_id)) { input_error("Record id must be a number"); pick_record_form(); return FALSE; } return TRUE; } // Now we get to the meat of the application. The next functions are // actually calling the shots. They are action handlers. Each of them // is called from main after executing some common preamble. // Drop the old table if it exists and re-create an empty one. // Note that we use mediumint for price because we store the money in // cents to save space. This function is called every time the user // selects "Initialize database". There is no other user input to Listing 9.1 Source code of sample.php. (continues) PHP Client Basics 156 // process, so we get straight down to business. function init_db() { safe_query("DROP TABLE IF EXISTS inventory"); safe_query("CREATE TABLE inventory ( id smallint unsigned NOT NULL auto_increment, name varchar(30) NOT NULL, price mediumint unsigned NOT NULL, quantity smallint unsigned NOT NULL, PRIMARY KEY (id) )"); // Having finished the database work, give the menu and report // success. menu_form(); echo("Database initialized<br>"); } // Handler for "Add Record" action. We collect the data, validate user // input, and then process it. Note how the function is able to handle // being called from different states, and how it determines the state // by checking the record_entered variable. function add_record() { global $name,$quantity,$price; if (!isset($_POST["record_entered"]) || !validate_input()) { record_form(); return; } else { // Note the use of mysql_escape_string() to escape potentially // problematic characters. Also note the dollars->cents conversion // to accommodate for the use of mediumint for price storage safe_query("INSERT INTO inventory (name,quantity,price) VALUES ('". mysql_escape_string($name)."',$quantity,$price*100)"); // After we've done the database work, make users happy by giving // them a menu and telling them the work was successful. menu_form(); echo("Record added<br>"); } } // Handler for "Show Totals" action. No additional user input is // required. Note how we handle NULL values in the fields by using // isset() on the field member in the row object. Also note how we do Listing 9.1 Source code of sample.php. (continues) Sample Code 157 // not use the while loop, but instead call mysql_fetch_object() only // once because the query will always return only one row. function show_totals() { // Since the price is stored in cents, and we want the output in // dollars, we divide the price by 100. $res = safe_query("SELECT SUM(quantity) as total_quantity, SUM(price*quantity)/100 as total_price FROM inventory"); $r = mysql_fetch_object($res); // Give menu at the top before we print the results of the // computation. menu_form(); // If we have no records, the query will return NULL in both // columns, not 0. if (!isset($r->total_quantity)) { echo("The database has no records<br>"); } else { echo("<table border=1><tr><td>Total Items</td><td>Total Value</td></tr> <tr><td>$r->total_quantity</td><td>$r->total_price</td></tr></table>"); } // Although PHP cleans up for us at the end, we will be good and // clean up here to make the code cleaner and read easier. mysql_free_result($res); } // Handler for "Delete Record" action. We first need to get $record_id // from the user. function delete_record() { global $record_id,$mysql; if (!get_record_id()) return; safe_query("DELETE FROM inventory WHERE id = $record_id"); // Again, make users happy with a menu and a report of the results. // Note that in some cases the record may not exist. menu_form(); if (mysql_affected_rows($mysql)) echo("Record deleted<br>"); else echo("No such record, nothing deleted<br>"); } // Handler for "Update Record". We require $record_id, as well as the // entire record form filled out. If something is missing we ask for Listing 9.1 Source code of sample.php. (continues) [...]... # course, made up add_customer_with_deposit("Tim", "Jones", "11123 456 7", "1400 Maple", "Los Angeles", "CA", "900 15" , 1000.00); add_customer_with_deposit("Chris", "Barker", "11123 456 7", "11 45 State", "Springville", "UT", "84664", 2000.00); add_customer_with_deposit("Jim", "Marble", "678 456 788", "230 N Pioneer", "Mesa", "AZ", " 852 03", 150 0.00); # Commit the transaction $dbh->commit(); print("Database... the MySQL DBD module, you will get a message “Can’t locate DBD /mysql. pm.” Go to www .mysql. com/api-dbi.html and download the file called Msql-mysqlmodules-version.tar.gz, unpack the archive, and then proceed with the standard Perl module installation mantra: perl Makefile.PL make make install Note that it is important to install DBI before you install the MySQL module, and you should also have the MySQL. .. front of MySQL API calls, while checking for errors in your code Ti p s a n d Tr i c k s 163 ■ ■ To get the error if mysql_ connect() or mysql_ pconnect() fails, you need to have the track_errors setting enabled and read it from $php_errormsg Unlike other MySQL API functions, where you would use mysql_ error(), the connection handle will not be initialized if the connection is not successful, and mysql_ error()... is to install MySQL Connector/J, so go to www .mysql. com/downloads/api-jdbc-stable.html and download the distribution Unpack the archive in the directory where you would like to have it installed, and set your CLASSPATH variable to point at that directory For example: mkdir /usr/lib/java cd /usr/lib/java gtar zxvf /tmp /mysql- connector-java-2.0.14.tar.gz ln -s mysql- connector-java-2.0.14 mysql- connector... the stored procedures, which are not supported by the MySQL server JDBC Classes and Methods Java applications connect to MySQL through the JDBC interface Native MySQL API does not exist—everything happens on the JDBC level Our discussion of the MySQL API for Java, therefore, is essentially reduced to the discussion of JDBC with the exception of MySQL- specific driver parameters Let’s begin with a listing... more detailed information by visiting http:// search.cpan.org/author/TIMB/DBI-1.30/DBI.pm To learn more about the DBD: :mysql module, which works underneath the DBI module to provide support for MySQL connectivity, visit http://search.cpan.org/author/JWIED/ DBD -mysql- 2.1018/lib/DBD /mysql. pod The methods and attributes listed as follows can be divided into three categories: methods and attributes global... surrogate unique id To demonstrate the use of transactions and to remind you that MySQL does support transactions Listing 10.1 Perl MySQL sample code (continues) 174 Perl AP I Basics # nowadays, we make both tables transactional - TYPE=INNODB # # Note the partial key on only the first 5 letters of # the first name and only the first 5 letters of the last name This # is a heuristical decision - the reasoning... null, street varchar(30) not null, city varchar(30) not null, state char(2) not null, zip char (5) not null, key(lname (5) ,fname (5) ), key(ssn) ) TYPE=INNODB }; safe_do($query); $query = q{CREATE TABLE account ( id int unsigned not null auto_increment primary key, customer_id int unsigned not null, Listing 10.1 Perl MySQL sample code (continues) Sample Code interest_rate smallint unsigned not null, amount... main # First make sure that the MySQL DBD driver is sufficiently recent # This is needed because we are using transactions # # Note that there is a discrepancy between the version number in the # variable# and the official version of the driver, but luckily, they # correlate and we can do version checks ($drh = DBI->install_driver( "mysql" )) || dbi_die("Failed to load MySQL driver"); if ($drh->{"Version"}... CHAPTER 11 Java Client Basics he first public version of Java was released in 19 95 The language came about as a result of a group of Sun developers who were not quite satisfied with C++ Since then, it has been gaining in popularity in the corporate world and has become a major player in the enterprise T Nevertheless, MySQL developers have looked at Java with an eye of skepticism for a long time, and . fails. $mysql = @mysql_ connect( $mysql_ host, $mysql_ user, $mysql_ pass); if (! $mysql) error_exit("Could not connect to MySQL: $php_errormsg"); if (! @mysql_ select_db( $mysql_ db, $mysql) ) error_exit("Could. not successful. function safe_connect() { global $mysql, $mysql_ host, $mysql_ user, $mysql_ pass, $mysql_ db, $php_errormsg; // Note the @ in front of MySQL API calls. This prevents PHP // from automatically. (continues) Sample Code 149 // database connection parameters $mysql_ user = "root"; $mysql_ host = "localhost"; $mysql_ pass = ""; $mysql_ db = "test"; // This class is used

Ngày đăng: 13/08/2014, 22:21

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan