The Essential Guide to Dreamweaver CS4 with CSS, Ajax, and PHP phần 9 ppsx

94 360 0
The Essential Guide to Dreamweaver CS4 with CSS, Ajax, and PHP phần 9 ppsx

Đ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

9. Remove the square brackets after operating_system in $_POST['operating_ system[]'] (line 41 in the preceding screenshot) so that it looks like this: GetSQLValueString($_POST['operating_system'], "text"), T his inserts the value of $ _POST['operating_system'] i nto the table as a string, but the values being sent from the checkbox group are an array. So, they need to be reformatted before they can be inserted into the database. 10. To convert the array in $_POST['operating system'] into a comma-separated string, add the following code block highlighted in bold immediately after the code shown on line 39 in the preceding screenshot: if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) { // convert the checkbox group subarray to a string if (isset($_POST['operating_system'])) { $_POST['operating_system'] = implode(',', $_POST['operating_system']); } else { $_POST['operating_system'] = 'none'; } $insertSQL = sprintf("INSERT INTO os_poll (operating_system) ➥ VALUES (%s)", The block is enclosed in the server behavior’s conditional statement that executes the code only if the form has been submitted. Because checkboxes and multiple- choice lists don’t appear in the $_POST array if nothing has been selected, the new code first checks whether any values have been selected for operating_system.If they have, they are converted to a comma-separated string with implode(). Otherwise, none is assigned as the value. This is needed to prevent the SQL query from throwing an error. The first argument to the implode() function is the string you want to act as a sep- arator between array elements. It’s vital to use a comma with no space on either side like this: $_POST['operating_system'] = implode(',', $_POST['operating_system']); If you add a space after the comma inside the first argument, only the first value is inserted in the SET column. This is because the space is treated as part of the string. The extra space after the first comma in the following line of code will result in incomplete data being inserted into the SET column: $_POST['operating_system'] = implode(', ', $_POST['operating_system']); 11. Save set_insert.php, and load it in a browser. Test the form by selecting at least two checkboxes and clicking Submit. 12. Check the results by clicking the Browse tab in phpMyAdmin. Confirm that you can see the selected values inserted in the table, as shown here: Check your code, if necessary, against set_insert_01.php in examples/ch17. HANDLING CHECKBOX GROUPS, SEARCHES, AND DATES 749 17 Retrieving data stored in a SET column The MySQL documentation (http://dev.mysql.com/doc/refman/5.0/en/set.html) clas- sifies the SET data type as a string, so that’s what it expects you to insert, and that’s what it returns when you retrieve data with a SELECT query. However, as I explained earlier, the values are stored numerically, rather than as text. This has the following important effects on the data that you get back from a SET column: Values are returned as a comma-separated list. Trailing spaces are automatically deleted. Even if the INSERT query contains duplicate values, each value is stored only once. This means you can’t adapt the form in set_insert.php to record how many com- puters of a different type a person owns. Values are returned in the same order as the original table specification. The results from a search of the os_poll table will always be in the order Windows, Mac, Linux. You can’t use a SET column to store items in order of preference. It’s purely a yes or no choice. The values stored for each record in a SET column can be accessed in the normal way through a recordset, as the following exercise shows. This exercise shows different ways of displaying values retrieved from a SET column. Continue working with set_insert.php and the os_poll table from the previous exercise. 1. With set_insert.php open in the Document window, open the Recordset dialog box in Simple mode, and use the following settings to create a recordset called getVote: Even though this uses only a SELECT query, I’m using the administrative user account because it makes more sense to use the same connection as the INSERT query on the same page. Displaying the user’s vote THE ESSENTIAL GUIDE TO DREAMWEAVER CS4 WITH CSS, AJAX, AND PHP 750 Setting Sort to vote_id Descending uses the primary key to sort the recordset in reverse order, so the most recent record will always be the first. 2. Underneath the insert form, add a paragraph with the text You selected:, and use the Bindings panel to insert a dynamic text placeholder for operating_system from the getVote recordset. The bottom of the page should look like this: 3. Save set_insert.php, and click the Live View button. Click Yes when asked about updating the copy on the testing server. The bottom of the page should look similar to this: Hang on a moment . . . You can’t submit the form in Live view, yet the dynamic text is displaying a result. It is, of course, the result from the previous vote. You want to display it only after the visitor has voted. So, the recordset code needs to go inside the conditional statement that controls the INSERT query, but it must come after the vote has been registered. 4. Open Code view, and locate the code shown in Figure 17-4. Study the code care- fully. In Chapter 15, I told you that Dreamweaver always puts the code for record- sets immediately above the DOCTYPE declaration. On this occasion, though, the getVote recordset code is on lines 34–38, more than 20 lines above the DOCTYPE declaration, with the Insert Record server behavior in between. HANDLING CHECKBOX GROUPS, SEARCHES, AND DATES 751 17 Figure 17-4. Because the Insert Record server behavior has been edited, the recordset has been inserted above it. This has happened because you edited the Insert Record behavior in the previous exercise, so Dreamweaver no longer recognizes it. However, it recognizes the GetSQLValueString() function declaration as part of its own code, so it puts the recordset with it. Because you’re moving the recordset code anyway, it doesn’t really matter where Dreamweaver put it. However, this illustrates the importance of understanding what each block of code does and where it’s located. PHP code is processed in the same order as it appears in the script. If you left the code in its current location and surrounded it with a conditional statement to run only after the form has been submitted, it would work, but it would always show the previous result rather than the current one because it’s executed before the INSERT query. 5. Cut the getVote recordset code (lines 34–38 in Figure 17-4) to your clipboard, and paste it in front of the closing curly brace shown on line 57 of Figure 17-4. This ensures that the recordset is created only when the form is submitted and that it gets the most recent result. 6. Also, you want to show the result only when the recordset has been created. You can do this by surrounding the paragraph that displays it with a conditional state- ment that checks whether the recordset has been created like this: <?php if (isset($getVote)) { ?> <p>You selected: <?php echo $row_getVote['operating_system']; ?></p> <?php } ?> The $getVote variable contains the recordset result, so it must exist if the record- set does. (See why it’s a good idea to give recordsets meaningful names?) 7. Since the recordset is created only when the form is submitted, you also need a conditional statement around the code that clears the recordset result at the end of the script like this: </html> <?php if (isset($getVote)) { mysql_free_result($getVote); } ?> 8. Save set_insert.php, and load it into a browser. When the page first loads, the form looks the same as before, but when you submit the form, it displays your choice immediately below as a comma-separated string, as shown in Figure 17-5. THE ESSENTIAL GUIDE TO DREAMWEAVER CS4 WITH CSS, AJAX, AND PHP 752 Figure 17-5. The values stored in a SET column are returned as a comma- separated string. If you select just one value, there is no comma, but when more than one value is returned, they are separated by commas with no space in between. 9. How you handle the comma-separated string depends on what you want to do with the results of a recordset that contains a SET column. If you simply want to add a space after each comma, you can use the str_replace() function like this: <?php echo str_replace(',', ', ', $row_getVote['operating_system']);?> The str_replace() function takes three arguments: the string you want to replace, what you want to replace it with, and the string you want to perform the replace- ment on. So, the first argument here is a comma on its own, the second argument is a comma followed by a space, and the final argument is the value from the recordset. 10. To format the comma-separated string in more complex ways, pass the value from the recordset to the explode() function, and store it in a variable like this: $selected = explode(',', $row_getVote['operating_system']); The explode() function converts a string into an array. It normally takes two argu- ments: a string containing the character(s) that mark(s) the boundary between each array element, and the string you want to split. The boundary characters are discarded, so this converts a comma-separated string into an array, which you can then manipulate however you like. For example, you could display the results as a bulleted list like this: <p>You selected: <?php $selected = explode(',', ➥ $row_getVote['operating_system']); ?></p> <ul> <?php foreach ($selected as $item) { echo "<li>$item</li>"; } ?> </ul> You can check your code against set_insert_02.php in examples/ch17. The purpose of this exercise is to demonstrate the use of SET columns, not to build a real- istic online poll. To prevent multiple submissions by the same person, an online poll also needs a column that records a value that can be used to identify someone who has already voted. One way of doing this is to create a session variable that contains a randomly gen- erated value like this: session_start(); if (!isset($_SESSION['random_id'])) { $_SESSION['random_id'] = md5(uniqid(rand(), true)); } This uses the PHP function uniqid() (http://docs.php.net/manual/en/function. uniqid.php) in combination with md5(), an encryption function, and rand(), which gener- ates a random value, to create a 32-character string. Store the session variable in a hidden HANDLING CHECKBOX GROUPS, SEARCHES, AND DATES 753 17 form field, and check that it doesn’t already exist in the database before inserting it with the poll data. I’ll come back later to showing you how to find records that contain specific values in a SET column. Getting the information you want from a database As you have probably realized by now, a recordset is the result of a database search. Controlling the search is a SQL query using the SELECT command. Dreamweaver builds the PHP code that passes the SQL query to the database and processes the result. It can also build the SQL query for very simple searches. For anything more sophisticated, it’s up to you to build the query yourself. Over the next few pages, I’ll show you how to tackle some common search problems. However, writing SELECT queries is a massive subject, about which whole books have been written (one of my favorite writers on MySQL is Paul DuBois). So, treat the following pages as an introduction to a fascinating and rewarding subject, rather than a definitive guide to search queries. Books and online forums can provide a lot of help in formulating the appropriate SELECT query to extract the information that you want from a database. But to use that informa- tion successfully with Dreamweaver, you need to understand how the Recordset dialog box builds a SELECT statement. Understanding how Dreamweaver builds a SQL query The file find_author_01.php in examples/ch17 contains a form with a single text field called first_name and a submit button. Beneath the form is a table with a single row in a repeat region, which displays the results of the search. Load the page into a browser, type William in the text field, and click Search. You should see a list of authors whose first name is William, as shown here: THE ESSENTIAL GUIDE TO DREAMWEAVER CS4 WITH CSS, AJAX, AND PHP 754 Try some other names, such as John, Dorothy, and Mae, and a list of matching records is displayed. By default, text searches in MySQL are case-insensitive, so it doesn’t matter what combination of uppercase and lowercase you use. We’ll get to case-sensitive and par- tial-word searches later, but let’s look at the code that Dreamweaver uses to submit the query to the database. I created the getAuthors recordset in find_author_01.php using the following settings in the Recordset dialog box in Simple mode: The same query looks like this in Advanced mode: The first thing to note is that Dreamweaver doesn’t add the table name in front of each column name when you use the Recordset dialog box in Simple mode. As explained in the previous chapter, adding the table name is necessary only when the same column name is used in more than one table (like author_id in the authors and quotations tables). Simple mode is capable of handling only single tables, so there’s never any danger of ambiguity. However, Dreamweaver automatically adds the table names to all columns HANDLING CHECKBOX GROUPS, SEARCHES, AND DATES 755 17 when you build a query in Advanced mode. It does so as a precautionary measure, even if there’s no likelihood of ambiguity. The other thing to note is that the Filter settings from Simple mode have been converted to this: WHERE first_name = colname Dreamweaver uses colname to represent the unknown value that will be passed to the SQL query through the text field in find_author_01.php. The properties of colname are defined in the Variables area below, with Type set to Text, Default value to -1, and Run-time Value to $_GET[‘first_name’]. It’s important to realize that colname is not part of SQL. Dreamweaver uses the concept of replacement when dealing with unknown values in SQL queries. When you close the Recordset dialog box, Dreamweaver replaces colname with PHP code that inserts the run- time value into the query. The choice of colname is purely arbitrary. It can be anything that doesn’t clash with the rest of the query. In the previous chapter, you used var1 and var2 as the names for runtime variables. The other important thing to know about Dreamweaver’s use of runtime variables is that the PHP code automatically encloses the value in quotes unless you specify Type as Integer or Floating point number. Because strings must be enclosed in quotes, the correct way to write this query in SQL is as follows (assuming that you’re searching for “William”): SELECT first_name, family_name FROM authors WHERE first_name = 'William' ORDER BY family_name ASC Because Dreamweaver handles the quotes automatically, you need to adapt SQL from other sources accordingly. Now, look at the PHP code generated by these settings (see Figure 17-6). Figure 17-6. The code Dreamweaver generates for a recordset that uses a variable passed through a query string You have seen the recordset code on many occasions, and I described the meaning of the variables in Chapter 15. What I would like you to focus on here is the way Dreamweaver THE ESSENTIAL GUIDE TO DREAMWEAVER CS4 WITH CSS, AJAX, AND PHP 756 handles colname and uses it to insert the runtime variable into the SQL query. The follow- ing sequence of events takes place: 1. The name of the variable defined in the Recordset dialog box (in this case, colname) is combined with the recordset name on line 34 to create a PHP variable ($colname_getAuthors), which is assigned a default value of -1. 2. The conditional statement on lines 35–37 replaces the default value with the sub- mitted value from the form. In this case, it uses $_GET['first_name']. So if a variable called first_name is passed through a query string at the end of the URL, $colname_getAuthors takes its value. Otherwise, $colname_getAuthors remains -1. 3. The code shown on line 39 of Figure 17-6 builds the SQL query using a PHP func- tion called sprintf(). The sprintf() function can be difficult to get your head around, but it takes a minimum of two arguments. The first of these is a string that contains one or more predefined place- holders; the number of remaining arguments matches the number of placeholders in the first argument. When the script runs, sprintf() replaces each placeholder with its corre- sponding argument. Why use such a convoluted way of inserting something into the SQL query? It’s a short- hand way of passing the runtime variables to another function without the need to assign the result to a variable. Dreamweaver passes all runtime variables to a custom-built func- tion called GetSQLValueString(), which is shown in Figure 15-1. As explained in Chapter 15, this function protects your database from malicious attacks known as SQL injection.If Dreamweaver didn’t use sprintf(), it would need to store the result of passing each run- time variable to GetSQLValueString() before building the query. It also avoids complex problems with escaping quotes with a lot of variables. The most commonly used predefined placeholder used with sprintf() is %s, which stands for “string.” So, the colname that you saw in the Recordset dialog box becomes %s, and when the script runs, it is replaced by the result of GetSQLValueString($colname_ getAuthors, "text"). When there’s more than one runtime variable in a SQL query, Dreamweaver replaces each one with %s and passes it to GetSQLValueString() when listing the variable as an argu- ment to sprintf(). Dreamweaver uses sprintf() to build all SQL queries, not just for recordsets. The impor- tant things to remember about editing SQL queries in Dreamweaver or adapting queries that you read about elsewhere are as follows: The number of arguments following the first one passed to sprintf() must be the same as the number of %s placeholders in the query. GetSQLValueString() automatically handles quotes around text values, so you should never add quotes around the %s placeholder in sprintf(). HANDLING CHECKBOX GROUPS, SEARCHES, AND DATES 757 17 Troubleshooting SQL queries At the end of line 40 in Figure 17-6 is this rather doom-laden command: or die(mysql_error()); This tells the script to stop running if there’s a problem with the SQL query and to display the error message returned by MySQL. Figure 17-7 shows what happens if you add single quotes around the %s placeholder in the SQL query in find_author_01.php. Figure 17-7. MySQL error messages look cryptic but are very useful. The error is reported as being on line 1, because the message comes from MySQL, not PHP. MySQL sees only the query, so the error is always on line 1. The important informa- tion is the reference to the error being “near” a particular part of the query. The error is always immediately preceding the segment quoted in the message, but the only way to diagnose the problem is to study the contents of the query. Don’t waste time trying to analyze the code. As I explained in Chapter 15, the SQL query is stored in a variable called $query_recordsetName. Dive into Code view, and use echo to display the query onscreen, as shown in the following illustration (use line breaks to sepa- rate the query from the error message): THE ESSENTIAL GUIDE TO DREAMWEAVER CS4 WITH CSS, AJAX, AND PHP 758 You can then load the page into a browser and see exactly what is being sent to the data- base. In the case of find_author_01.php, the query is displayed as soon as you load the page (see Figure 17-8). In some cases, you need to pass the necessary values to the query through the form or as part of a query string in the browser address bar. You might see a lot of error messages onscreen, but that’s not important. As long as you can see what the SQL query contains, you can get to the root of the problem. [...]... value The way to count all values with a single query involves using the MySQL IF() function The function works in a similar way to the PHP conditional (ternary) operator It takes three arguments: the condition you want to test, the value to assign if the test equates to true, and the value to assign if the test equates to false Unlike the PHP operator, the arguments are separated by commas, so the basic... Click the Test button, and you’ll see every quotation listed with its author’s name 3 To search for quotations containing a particular word or phrase, you need to add the quotation column to the WHERE clause In the Database items section at the bottom of the Recordset dialog box, expand Tables, and highlight quotation in the quotations tree menu Click the WHERE button to add it to the SQL query The query... variable Since Dreamweaver has options only for numbers and text, you need to do some elementary hand-coding 1 Copy find_author_02 .php from examples/ch17, and save it as find_author_ 03 .php in workfiles/ch17 2 Click inside the Author_id label to the left of the text field, select the tag in the Tag selector at the bottom of the Document window, and press the right arrow key once to position the insertion... (isset($_GET['operator']) && in_array($_GET['operator'], ➥ $permittedOperators)) { $operator = $_GET['operator']; } This sets $operator to a default value of an equal sign, defines an array of acceptable operators, and reassigns the value submitted from the form, if it exists and is one of the permitted operators Using the $permittedOperators array and in_array() like this performs a similar security check to the. .. along with the results, as shown in Figure 17 -9 Figure 17 -9 Using AND with a wildcard character search allows a field to be left blank Although nothing is entered in the second field, the wildcard character % is added to the end of the runtime variable This results in the second condition matching the family_name column with %—in other words, anything Now try it with find_author_14 .php, where the only... correctly between the label and text field 3 Select List/Menu from the Forms tab of the Insert bar (or use the Form submenu of the Insert menu) In the Input Tag Accessibility Attributes dialog box, enter operator in the ID field, leave Label blank, select No label tag, and click OK 4 Click the List Values button in the Property inspector, and enter the following operators in both the Item Label and Value fields:... = Although you don’t normally need to set the Value field if it’s the same as Item Label, you need to do it on this occasion, because Dreamweaver replaces the less-than and greaterthan operators with HTML entities 5 Select the equal sign as Initially Selected 6 Open Split view, and edit the value properties of the tags to change the HTML entities to the less-than and greater-than... use AND instead Finally, you add the ORDER BY clause Each part of the WHERE clause uses sprintf() and GetSQLValueString() to prepare the $_GET variables to be inserted safely into the query Because GetSQLValueString() is a Dreamweaver function, and not part of core PHP, you must remember to include its definition in your script The easiest way to do this is to build the first part of the query using the. .. blocks to avoid breaking Dreamweaver s Repeat Region server behavior code The increment operator (++) performs the current calculation and then adds 1 to the variable So, the first time through the loop $counter is 0 This leaves a remainder of 0 (false), so the hilite class isn’t inserted into the tag The next time, the calculation produces a remainder of 1 (true), and so on, until the loop comes to. .. you go through the various Filter options in Simple mode and examine the SQL in Advanced mode, you’ll quickly learn how the operators are used in a SQL query Dreamweaver uses as the “not equal to operator instead of != Either is perfectly acceptable At the bottom of the Filter drop-down menu are three options: begins with, ends with, and contains These perform wildcard searches, where the user enters . you to focus on here is the way Dreamweaver THE ESSENTIAL GUIDE TO DREAMWEAVER CS4 WITH CSS, AJAX, AND PHP 756 handles colname and uses it to insert the runtime variable into the SQL query. The. INSERT query on the same page. Displaying the user’s vote THE ESSENTIAL GUIDE TO DREAMWEAVER CS4 WITH CSS, AJAX, AND PHP 750 Setting Sort to vote_id Descending uses the primary key to sort the recordset. error messages either, Experimenting with the default value THE ESSENTIAL GUIDE TO DREAMWEAVER CS4 WITH CSS, AJAX, AND PHP 764 because a valid value is passed to the query. The problem is that

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

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

Tài liệu liên quan