MySQL /PHP Database Applications Second Edition phần 5 pot

81 444 0
MySQL /PHP Database Applications Second Edition phần 5 pot

Đ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

{ if ($arg === NULL || (is_array($arg) && count($arg) == 0)) { // do nothing } elseif (is_object($arg)) { $result = array_merge($result, get_object_vars($arg)); } elseif (is_assoc($arg)) { $result = array_merge($result, $arg); } else { if ($i < $sc) { $key = $simple[$i++]; if (!empty($arg) || !isset($result[$key])) { $result[$key] = $arg; } } else { if ($key === NULL) { user_error(“Argument ‘$arg’ was passed with no available target - aborting \n”, E_USER_ERROR); } if (isset($result[$key])) { if (!is_array($result[$key])) { $result[$key] = array($result[$key]); } $result[$key][] = $arg; } else { $result[$key] = $arg; } } } } Chapter 9: Survey 279 Two things are worth pointing out here. If a simple argument is encountered after we’ve run out of parameter names from $_simple, it’s added into an array by means of the last simple name. This is how a function like paragraph() works. It has just one simple argument name, ‘values’, so a list of simple arguments passed in to the function ends up as elements in the $values array: paragraph(‘One line’,’Another line’,$variable,’Yet another line’); becomes ‘values’ => array(‘One line’, ‘Another line’, $variable, ‘Yet another line’); If there are no names passed in, however, we won’t have anywhere to put any arguments that aren’t associative arrays. In this case we use PHP’s user_error() function to raise an error. This prints out our error message and stops the script, just like a normal PHP error. (The user_error() function is one you’ll be seeing more of in later examples.) Finally, to clean up, we take any changes to our list of default and simple argu- ments and pass them back to the calling function. Because the two arrays are passed in by reference, changes made to them here will update the original variables. And because they’re declared as static, those changes will still be there the next time the function is called. $defaults = array_merge($defaults, $result[‘_defaults’]); $simple = $result[‘_simple’]; return $result; } Changes to $_defaults are merged into the original list, while a new value for $_simple will replace the old one. After calling parse_arguments() in the image_src() function, like this, $p = parse_arguments($p, $_simple, $_defaults); we have an array, $p, containing all the attribute values and other parameters from the original call. For example, from this line in the Web page — image_src(‘/images/monkey.jpg’); — we would end up with the following values in $p: $p = array(‘src’=>’/image/monkey.jpg’, ‘alt’=>’’, ‘border’=>0); 280 Part III: Simple Applications For the <IMG> tag specifically, if the ‘alt’ attribute is empty, we’ll use the name of the image file (from the ‘src’ attribute) as a default: if (empty($p[‘alt’])) $p[‘alt’] = $p[‘src’]; The next step is to turn the reference to the image file into an HTML tag. So we pass the array to the get_attlist() function. This takes key/value pairs from an associative array and reformats them as a single string of HTML-style attributes. The previous example would come back as the following: src=”/images/monkey.jpg” alt=”/images/monkey.jpg” border=”0” Therefore, we only need add the name of the tag itself and the opening and clos- ing angle brackets to get this, which image_tag() returns as its result: <image src=”/images/monkey.jpg” alt=”/images/monkey.jpg” border=”0”> A special constant, STANDALONE, defined in /functions/basic.php, is useful for attributes like ‘selected’ in an <option> tag. So array(‘value’=>’CA’,’selected’=>STANDALONE) becomes value=”CA” selected Using this function may seem like a lot of work just to get a simple <img> tag. Well, it is. The payoff is flexibility, the cost is an increase in complexity. In a high- performance environment you would probably end up discarding parts of this code. For instance, you could decree that all function calls will be of the following form: my_function(array(‘param1’=>’value1’, ‘param2’=>’value2’, ) This would enable you to eliminate the call to parse_arguments() and simply merge the passed-in array with $_defaults. Or you could use functions like these in your production/development environment to produce less clever, and thus faster, files that will then get pushed out to your servers. FUNCTIONS FROM /BOOK/FUNCTIONS/HTML/ These functions make it easier to create common HTML tags. Most of the functions in this file are very similar. Chapter 9: Survey 281 ANCHOR_TAG() This function creates an anchor tag. function anchor_tag() { static $_defaults = array( ‘href’=>’’ , ‘text’ => ‘’ , ‘value’ => ‘’ , ‘allowed’ => array(‘Common’,’accesskey’,’charset’,’href’ ,’hreflang’,’rel’,’rev’,’tabindex’,’type’,’name’,’target’ ) ); static $_simple = array(‘href’,’value’); $p = func_get_args(); $p = parse_arguments($p, $_simple, $_defaults); if (empty($p[‘text’])) { $p[‘text’] = $p[‘href’]; } if (empty($p[‘value’])) { $p[‘value’] = $p[‘text’]; } $attlist = get_attlist($p); $output = “<a $attlist>{$p[‘value’]}</a>”; return $output; } You can expect only two things every time with an anchor tag: an href attribute and some text to go between the opening and closing <a> tags. However, it is pos- sible that a name attribute would be more descriptive, and more useful in client-side scripting. But more often than not, the call to this function will look something like this: anchor_tag(‘myurl.com/index.html’, ‘this is a great link’); PARAGRAPH() This function will either print out opening and closing <p> tags and everything between them, or just the opening <p> tag, depending on how it’s called. 282 Part III: Simple Applications function paragraph () { static $_defaults = array( ‘values’ => array() , ‘allowed’ => array(‘Common’,’align’) , ‘start’ => NULL ); static $_simple = array(‘values’); $p = func_get_args(); $p = parse_arguments($p, $_simple, $_defaults); $attlist = get_attlist($p); $output = “\n<p $attlist>\n”; if ($p[‘start’] !== NULL) { return $output; } $output .= implode(“\n”,(array)$p[‘values’]) .end_paragraph($p) ; return $output; } The first thing to understand about this function is that by default it will print not only the opening <p> tag along with its attributes, but also the closing </p> tag and everything that could occur between the two. This could include anchor tags, image tags, or just about anything else. The following function call would work just fine, and in fact is used within the survey application: print paragraph(anchor_tag(‘block_domain.php’,’Return to Domain List’)); One argument exists in this function call, and that’s another function call with two arguments. In effect, when one function call is nested inside another, PHP exe- cutes the internal one first. So first the anchor_tag() function is called, creating a string like ‘<a href=”admin_block.php”>’. Then the outer function is executed, so the call to the paragraph function will actually look something like this: print paragraph(‘<a href=”admin_block.php”>Return to Domain List</a>’); Note how flexible this becomes. By looping through the number of arguments you can send any number of additional function calls to the paragraph function. And you can happily mix text and function calls together, because by the time Chapter 9: Survey 283 paragraph() sees it, it’s all text. So the following is a perfectly fine call to the paragraph function: print paragraph( “<b>Blocked by:</b> $block_by <br>” , “<b>Date Blocked:</b> $block_dt <br>” , “<b>Date Released:</b> $release_dt <br>” , “<b>Last Modified:</b> $modify_dt <br>” ); START_PARAGRAPH() You might have noticed that the paragraph() function checked to see if it had been passed an argument named ‘start’, and if it had, returned only the opening <p> tag. Sometimes you need to use the function that way because what goes inside the paragraph is too complicated to be included in a list of values. In such a case you can just call paragraph() with a ‘start’=>TRUE attribute, or you can use the start_paragraph() function, as follows: function start_paragraph () { $p = func_get_args(); $p[] = array(‘start’=>’yes’); return call_user_func_array(‘paragraph’, $p); } The start_paragraph() function takes the arguments passed into it and adds a ‘start’ argument. Then comes the interesting part. The PHP function call_user_func_array () takes a function name and an array of arguments and uses them to make a call to the named function. The elements in the array of argu- ments are passed in exactly as they would be in a normal function call. So call_user_func_array(‘myfunc’,array(1,2,3); works just like myfunc(1,2,3); The call_user_func_array() strategy lets start_paragraph() work as a kind of front end to the paragraph() function. A call to start_paragraph() like this one: start_paragraph(array(‘align’=>’center’)); is equivalent to paragraph(array(‘align’=>’center’, ‘start’=>’yes’)); 284 Part III: Simple Applications Both calls produce the same HTML output: <p align=”center”> END_PARAGRAPH() This function just prints out an end paragraph tag (</p>), as follows: function end_paragraph () { $output = “\n</p>\n”; return $output; } Its main reason for existing, besides making a lovely matched set with start_paragraph(), is to let you close any opening tags you might want to hard- code into the opening of a paragraph — a <font> tag, for example. UL_LIST() With this function you can create a bulleted list. Most frequently, an array will be passed to the function, each element prepended with an <li> tag. The function also deals with occasions in which a string is sent as the only argument. function ul_list () { static $_defaults = array( ‘values’ => array() , ‘contents’ => NULL , ‘allowed’ => array(‘Common’,’compact’,’type’) ); static $_simple = array(‘values’); $p = func_get_args(); $p = parse_arguments($p, $_simple, $_defaults); $attlist = get_attlist($p); $output = “<ul $attlist>\n”; if (!empty($p[‘values’]) && !is_array($p[‘values’]) && !is_object($p[‘values’]) ) { $output .= $p[‘values’]; } else { array_key_remove($p,array(‘_defaults’,’_simple’,’allowed’)); Chapter 9: Survey 285 foreach ((array)$p[‘values’] as $p[‘text’]) { $output .= li_tag($p); } } $output .= $p[‘contents’]; $output .= “</ul>\n”; return $output; } START_TABLE() Every HTML table begins with more or less the same code, so we have a function to generate it for us. function start_table () { static $_defaults = array( ‘cellspacing’ => 0 , ‘cellpadding’ => 1 , ‘allowed’ => array(‘Common’,’border’,’cellpadding’,’cellspacing’ ,’datapagesize’,’frame’,’rules’,’summary’,’width’,’align’,’bgcolor’ ) ); static $_simple = array(‘width’); $p = func_get_args(); $p = parse_arguments($p, $_simple, $_defaults); $attlist = get_attlist($p); $output = “\n<table $attlist>\n”; return $output; } END_TABLE() The same goes for the end of the table — it’s boilerplate, and boiler- plate should be generated programmatically. Here’s a function that does just that. function end_table () { $output = “\n</table>\n”; return $output; } TABLE() Here, unlike with the similar paragraph functions, start_table() is the function that knows how to generate the opening <table> tag, and it is the overall table() function that calls it. This is because we’d like to be able to pass in the 286 Part III: Simple Applications width as an argument when we are only opening a table. However, when we’re cre- ating a whole table, any unlabeled arguments are going to be rows in the resulting table. Because the two situations need two different values for $_simple, start_table() can’t be just a front end to table(). function table () { static $_defaults = array( ‘rows’ => array() ); static $_simple = array(‘rows’); $p = func_get_args(); $p = parse_arguments($p, $_simple, $_defaults); $output = start_table($p); foreach ((array)$p[‘rows’] as $row) { $output .= table_row($row); } $output .= end_table($p); return $output; } TABLE_ROW() This function does not only print out the opening <tr> tag and its attributes; it also prints the table cells that will be nested within the <tr> tags. function table_row () { static $_defaults = array( ‘cells’ => array() , ‘allowed’ => array(‘Common’,’align’,’valign’,’char’,’charoff’ ,’bgcolor’ ) ); static $_simple = array(‘cells’); $p = func_get_args(); $p = parse_arguments($p, $_simple, $_defaults); $attlist = get_attlist($p); $output = “\n <tr $attlist>\n”; Chapter 9: Survey 287 foreach ((array)$p[‘cells’] as $cell) { if (!preg_match(‘/<t[dh]/i’, $cell)) { $output .= table_cell($cell); } else { $output .= $cell; } } $output .= “\n </tr>\n”; return $output; } The following table_row() call has two arguments, one of which is itself another function call. The table_cell() function (described later) is executed first, and the results are passed in to table_row(). print table_row( ‘<b>A simple cell</b>’ , table_cell(array(‘value’=>’A not-so-simple cell’, ‘align’=>’right’)) ); So when table_row() goes through the values in its $cells argument, it finds one plain string (‘<b>A simple cell</b>’), which it runs through table_cell() itself, and one already-formatted cell (the output of the table_cell() call in our initial code), which it just tacks onto its output string as is. TABLE_CELL() Not too much is new here. It might be worth pointing out the way the $value attribute is handled: You check to see if it’s an array or an object, because PHP lets you cast an object as an array — you get back an associative array of the properties of the object. function table_cell () { static $_defaults = array( ‘align’ => ‘left’ , ‘valign’ => ‘top’ , ‘value’ => ‘’ , ‘allowed’ => array(‘Common’,’abbr’,’align’,’axis’,’char’,’charoff’ ,’colspan’,’headers’,’rowspan’,’scope’,’valign’,’width’,’height’ 288 Part III: Simple Applications [...]... is_blocked from blocked_domains where release_dt is null and ($where) “; $result = my_query($query); list($is_blocked) = mysql_ fetch_row($result); mysql_ free_result($result); if ($is_blocked == 1) { // Be noncomittal print subtitle(‘Page unavailable.’); exit; } } } 2 95 296 Part III: Simple Applications In order to understand this code, look more closely at the query, particularly the like predicates When... and very difficult to guess 303 304 Part III: Simple Applications mt_srand ((double) microtime() * 1000000); $claim_code = substr(md5(uniqid(rand())),0,8); The preceding code uses the uniqueid() and md5() functions to create a string that is very random There’s little for a hacker to latch onto in trying to figure out how the string is constructed md5() will create a string that is 32 characters long,... URL that includes a claim code that matches one in the database: http://mydomain.com/book/survey/claim php?claim_code =54 fa3399 If the user is interested, he or she will go to this page claim.php If the winner comes to claim.php, we first need to check that the claim code exists in the database The query in the following code grabs queries from the database to see if the claim code exists; if it does,... state_results.php, and country_results.php) for a look at how MySQL aggregate functions can come in handy This application contains much more complexity than the guestbook In it is a real database schema complete with related tables In the course of the application we need to make use of queries that contain MySQL functions (See Appendix J for more information on MySQL functions.) Another notable item seen in this... associative array function fetch_question ($question_id=0) { $result = my_query( ‘select * from questions where question_id=’.(int)$question_id ); $output = mysql_ fetch_assoc($result); mysql_ free_result($result); return $output; } This will return from the database all the information regarding a particular question, based on the question_id fetch_user() This function grabs the contents of a row in the users... returns them as an associative array function fetch_user ($user_id=’’) { $result = my_query( ‘select * from users where user_id=’.(int)$user_id ); $output = mysql_ fetch_assoc($result); mysql_ free_result($result); return $output; } 297 298 Part III: Simple Applications This function returns the result set based on a user_id get_answers() This function returns an array of answers associated with a question,... notification to $admin_email EOQ; } 3 05 306 Part III: Simple Applications The comparison $user_email != $winner_email will work because the query that ran at the top of the page retrieved the correct winner’s email, and we get $user_email from the form submitted by the user If that comparison fails, an error message prints If it does not fail, the following code updates the winners database, recording the time... qualified winner at random from the database First we use the weekstart() function (discussed earlier in this chapter in the section “Functions from /book/survey/functions”) to get the date on which the current week begins: $weekdate = (string)array_key_value($_REQUEST,’weekdate’,’’); $result = my_query(‘select ‘.weekstart($weekdate)); list($thisweek) = mysql_ fetch_row($result); mysql_ free_result($result);... code will run after handling the update of the database record for the question itself There will always be 10 elements to be looped through, so a for loop works nicely $answer_texts = (array)array_key_value($_POST,’answer_text’,array()); $answer_ids = (array)array_key_value($_POST,’answer_id’,array()); for ($i = 1; $i . my_query($query); list($is_blocked) = mysql_ fetch_row($result); mysql_ free_result($result); if ($is_blocked == 1) { // Be noncomittal. print subtitle(‘Page unavailable.’); exit; } } } Chapter 9: Survey 2 95 In order to. where question_id=’.(int)$question_id ); $output = mysql_ fetch_assoc($result); mysql_ free_result($result); return $output; } This will return from the database all the information regarding a particular question,. variables and comparing them against a database. In the real world it would be about as hacker-proof as a wet tissue. weekstart() This function generates SQL, MySQL style, to figure out the day of

Ngày đăng: 12/08/2014, 21:20

Từ khóa liên quan

Mục lục

  • Part III Simple Applications

    • 9 Survey

      • Code Breakdown

        • The survey application

        • Interesting Code Flow

          • admin/ questions. php

          • admin/ get_ winner. php

          • admin/ winners. php

          • claim. php

          • Summary

          • Part IV Not So Simple Applications

            • 10 Threaded Discussion

              • Determining the Scope and Goals of the Application

                • What do you need?

                • What do you need to prevent?

                • The Data

                • Code Overview

                • Code Breakdown

                  • Reusable functions

                  • Functions from / book/ discussion/ functions

                  • Error- handling and debugging functions

                  • Summary

                  • 11 Content-Management System

                    • Determining the Scope and Goals of the Application

                      • Necessary pages

                      • What do we need to prevent?

                      • Designing the Database

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

Tài liệu liên quan