1. Trang chủ
  2. » Công Nghệ Thông Tin

Secure PHP Development- P16 pptx

5 224 0

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 5
Dung lượng 79,09 KB

Nội dung

echo “Address 2 = $addr2\n”; echo “City = $city\n”; echo “State = $state\n”; echo “ZIP = $zip\n”; } // First call myFunction($name, $email, $age, $addr1, $addr2, $city, $state, $zipcode ); // Second call myFunction($name, $email, $age, $addr2, $addr1, $city, $state, $zipcode ); In this example, the function myFunction() expects a list of arguments. The code segment also shows two calls to this function. Notice that the second call has $addr1 and $addr2 misplaced. This type of argument misplacement is very com- mon and is the cause of many bugs that take a great deal of time to fix. When you have a function that requires a large number of parameters to be passed, use an associative array, as shown in the following code segment: $params = array( ‘NAME’ => $name, ‘EMAIL’ => $email, ‘AGE’ => $age, ‘ADDR1’ => $addr1, ‘ADDR2’ => $addr2, ‘CITY’ => $city, ‘STATE’ => $state, ‘ZIP’ => $zipcode ) 46 Part I: Designing PHP Applications 05 549669 ch03.qxd 4/4/03 9:24 AM Page 46 myFunction($params); function myFunction($params = null) { echo “Name = $params[‘NAME’]\n”; echo “Email = $params[‘EMAIL’]\n”; echo “Age = $params[‘AGE’]\n”; echo “Address 1 = $params[‘ADDR1’]\n”; echo “Address 2 = $params[‘ADDR2’]\n”; echo “City = $params[‘CITY’]\n”; echo “State = $params[‘STATE’]\n”; echo “ZIP = $params[‘ZIP’]\n”; } $params is an associative array, which is set up using key=value pairs. The function is called with only one argument. The order of the key=value does not mat- ter as long as the right key is used with the right value. This position-independent way of passing values to the function is much less likely to cause parameter bugs in your code. Best Practices for Database Most applications require database connectivity and, therefore, you need to know about some best practices that will help you make your code more efficient and bug-free. Here, I discuss the techniques that relate to relational database access. I assume that you’re using the DBI class (class.DBI.php), which is part of our appli- cation framework discussed in Chapter 4. The DBI class is really a database abstrac- tion layer that allows applications to access a set of database methods used to perform operations such as connect, query, etc. Since this class hides the database behind the scene, it provides a very easy way to change database backends from MySQL to Postgres or vise versa when needed. By changing the DBI class code to connect to a new database, an application can be easily ported from one database to another. Writing good SELECT statements SELECT is the most commonly used SQL statement that applications use to get data from databases. Unfortunately, a large number of SELECT statements that you will find in many applications use it in a way that can cause serious problems. For example, look at the following code segment: // Bad SELECT statement $statement = “SELECT * FROM myTable”; Chapter 3: PHP Best Practices 47 05 549669 ch03.qxd 4/4/03 9:24 AM Page 47 $result = $dbi->query($statement); $result->fetchRow(); This SELECT statement gets all the columns (field values) from the named table (myTable). If the table is changed to have new fields, the SELECT statement will also get values for the new fields. This is a side effect that can be good or bad. It is a good side effect only if your code is smart enough to handle the new data. Most codes are not written to do so. The bad effect could be that your code can become slower due to additional memory requirements to hold the new data, which is never used. For example, say that myTable has two fields, ID and NAME. The example code segment works just fine until the DBA adds a new field called COMMENTS (large text field) in the table to allow another application to work with comments. Our example code is adversely affected by this database change because it now wastes memory loading COMMENTS when there’s no use for this data in our application. Using named fields in the SELECT statement is the solution. // Good SELECT statement $statement = “SELECT ID, NAME FROM myTable”; $result = $dbi->query($statement); $result->fetchRow(); Dealing with missing data When accessing data via SELECT statements, be prepared to handle situations resulting from no data or missing data. For example: // Bad // no data or missing data $statement = “SELECT myField1 FROM myTable”; $result = $dbi->query($statement); $result->fetchRow(); If myTable doesn’t have any data when this code executes, the fetchRow() method causes PHP to throw an exception. This can be easily avoided by ensuring that the $result object is not null before calling the fetchRow() method of the $result object, as the following code shows: // Good $statement = “SELECT myField1 FROM myTable”; $result = $dbi->query($statement); if ($result != null) { $result->fetchRow(); } 48 Part I: Designing PHP Applications 05 549669 ch03.qxd 4/4/03 9:24 AM Page 48 Handling SQL action statements There are several best practices that make using SQL action statements such as INSERT, UPDATE, and DELETE most effective. Here I will explain those practices. Quoting and protecting against slashes Quote database fields that are char or varchar types, and escape for slashes. Quoting character or varchar fields is important because these data types can have keywords or punctuation marks that can be interpreted as part of an SQL statement and thus producing wrong results. Escaping slashes in these data types is also very important since data stored in these data types can be easily misinterpreted by the SQL engine. Often I see code segments that are as shown here: $params[‘FNAME’] = ‘Jennifer’; $params[‘LNAME’] = ‘Gunchy’; $params[‘SCHOOL’] = ‘CSUS, Sacramento’; $params[‘YEAR’] = 4; $this->myFunction($params); // BAD function myFunction($params = null) { $values = “‘“ . $params[‘FNAME’] . “‘,”; $values .= “‘“ . $params[‘LNAME’] . “‘,”; $values .= “‘“ . $params[‘SCHOOL’] . “‘,”; $values .= $params[‘YEAR’]; $stmt = “INSERT INTO myTable VALUES($values)”; $result = $this->dbi->query($stmt); return ($result == DB_OK) ? TRUE : FALSE; } In this example, the myFunction() method is called with $params argument. Some of the data fields stored in the $params variable are char or varchar fields and, therefore, hard-coded quotations are used as they are stored in $values. This type of hard-coded quotation can easily break if the data value include the quotation character. Here’s a better approach: Chapter 3: PHP Best Practices 49 05 549669 ch03.qxd 4/4/03 9:24 AM Page 49 // GOOD function myFunction($params = null) { $fields = array(‘FNAME’ => ‘text’, ‘LNAME’ => ‘text’, ‘SCHOOL’ => ‘text’, ‘YEAR’ => ‘number’ ); $fieldList = implode(‘,’, array_keys($fields)); while(list($fieldName, $fieldType) = each($fields)) { if (strcmp($fieldType, ‘text’)) { $valueList[] = $this->dbi->quote(addslashes($params[$fieldName])); } else { $valueList[] = $params[$fieldName]; } } $values = implode(‘,’, $valueList); $stmt = “INSERT INTO myTable ($fieldList) VALUES($values)”; $result = $this->dbi->query($stmt); return ($result == DB_OK) ? TRUE : FALSE; } In this example, an associative array called $fields is used to store field and field type information. A comma-separated value list called $fieldList is created using the keys from the $fields array. A while loop is used to loop through each of the fields in the $fields array and fields of type ‘text’ are quoted using the quote() method in our DBI class. Before quoting the field value the char/varchar value is escaped for slashes using the addslashes() function. The quoted, slash-escaped char/varchar values are stored in $valueList array. Similarly, non-quoted numeric values are stored in $valueList. The comma-separated values are stored in $values by imploding the $valueList. The INSERT statement is then composed of $fieldList and $values, which is very clean and free from quote and slash issues. 50 Part I: Designing PHP Applications 05 549669 ch03.qxd 4/4/03 9:24 AM Page 50 . => $addr2, ‘CITY’ => $city, ‘STATE’ => $state, ‘ZIP’ => $zipcode ) 46 Part I: Designing PHP Applications 05 549669 ch03.qxd 4/4/03 9:24 AM Page 46 myFunction($params); function myFunction($params. that relate to relational database access. I assume that you’re using the DBI class (class.DBI .php) , which is part of our appli- cation framework discussed in Chapter 4. The DBI class is really. following code segment: // Bad SELECT statement $statement = “SELECT * FROM myTable”; Chapter 3: PHP Best Practices 47 05 549669 ch03.qxd 4/4/03 9:24 AM Page 47 $result = $dbi->query($statement); $result->fetchRow(); This

Ngày đăng: 07/07/2014, 07:20