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

Giải pháp thiết kế web động với PHP - p 36 doc

10 279 0
Tài liệu đã được kiểm tra trùng lặp

Đ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 10
Dung lượng 736,27 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

However, instead of calling the errorInfo method on the connection object, use it on the PDO statement like this: $error = $stmt->errorInfo; if isset$error[2] { echo $error[2]; } To bin

Trang 1

331

In both cases, the result of the query is stored in $stmt

Error messages can be accessed in the same way as with a PDO connection However, instead of calling the errorInfo() method on the connection object, use it on the PDO statement like this:

$error = $stmt->errorInfo();

if (isset($error[2])) {

echo $error[2];

}

To bind the results of a SELECT query to variables, each column needs to bound separately using the bindColumn() method before calling execute() The bindColumn() method takes two arguments The first argument can be either the name of the column or its number counting from 1 The number comes from its position in the SELECT query, not the order it appears in the database table So, to bind the result from the filename column to $filename, either of the following is acceptable:

$stmt->bindColumn('filename', $filename);

$stmt->bindColumn(2, $filename);

PHP Solution 11-9: Using a PDO prepared statement in a search

This PHP solution shows how to embed the user-submitted value from a search form into a SELECT query with a PDO prepared statement It uses the same search form as the MySQLi versions in PHP Solutions 11-7 and 11-8

1 Copy pdo_prepared_01.php from the ch11 folder, and save it in the mysql folder as

pdo_prepared.php

2 Add the following code in a PHP block above the DOCTYPE declaration:

if (isset($_GET['go'])) {

require_once(' /includes/connection.inc.php');

$conn = dbConnect('read', 'pdo');

$sql = 'SELECT image_id, filename, caption FROM images

WHERE caption LIKE :search';

$searchterm = '%' $_GET['search'] '%';

$stmt = $conn->prepare($sql);

$stmt->bindParam(':search', $searchterm, PDO::PARAM_STR);

$stmt->bindColumn('image_id', $image_id);

$stmt->bindColumn('filename', $filename);

$stmt->bindColumn(3, $caption);

$stmt->execute();

$numRows = $stmt->rowCount();

}

When the form is submitted, this includes the connection file and creates a PDO connection to MySQL The prepared statement uses :search as a named parameter in place of the user-submitted value Like MySQLi prepared statements, you need to add the % wildcard characters

to the search term before binding it to the prepared statement with bindParam() The results are bound to $image_id, $filename, and $caption The first two use the column names, but the caption column is referred to by its position in the SELECT query

Trang 2

CHAPTER 11

332

3 The code that displays the results is identical to step 6 in PHP Solution 11-8 The finished file

is in pdo_prepared_02.php in the ch11 folder

PHP Solution 11-10: Changing column options through user input

This PHP solution shows how to change the name of SQL keywords in a SELECT query through user input SQL keywords cannot be wrapped in quotes, so using prepared statements or the MySQLi real_escape_string() method wont work Instead, you need to ensure that the user input matches an array of expected values If no match is found, use a default value instead The technique is identical for MySQLi and PDO

1. Copy either mysqli_order_01.php or pdo_order_01.php from the ch11 folder, and save it in the mysql folder Both versions select all records from the images table and display the results in table The pages also contain a form that allows the user to select the name of a column to sort the results in either ascending or descending order In their initial state, the form is inactive The pages display the details sorted by image_id in ascending order like this:

2 Amend the code in the PHP block above the DOCTYPE declaration like this (the following listing

shows the MySQLi version, but the changes highlighted in bold type are the same for PDO): require_once(' /includes/connection.inc.php');

// connect to MySQL

$conn = dbConnect('read');

// set default values

$col = 'image_id';

$dir = 'ASC';

// create arrays of permitted values

$columns = array('image_id', 'filename', 'caption');

$direction = array('ASC', 'DESC');

// if the form has been submitted, use only expected values

if (isset($_GET['column']) && in_array($_GET['column'], $columns)) {

$col = $_GET['column'];

Trang 3

333

}

if (isset($_GET['direction']) && in_array($_GET['direction'], $direction)) { $dir = $_GET['direction'];

}

// prepare the SQL query using sanitized variables

$sql = "SELECT * FROM images

ORDER BY $col $dir";

// submit the query and capture the result

$result = $conn->query($sql) or die(mysqli_error());

The new code defines two variables, $col and $dir, that are embedded directly in the SELECT query Because they have been assigned default values, the query displays the results

sorted by the image_id column in ascending order when the page first loads

Two arrays, $columns and $direction, then define permitted values: the column names, and the ASC and DESC keywords These arrays are used by the conditional statements that check the $_GET array for column and direction The submitted values are reassigned to $col and

$dir only if they match a value in the $columns and $direction arrays respectively This prevents any attempt to inject illegal values into the SQL query

3 Edit the <option> tags in the drop-down menus so they display the selected values for $col

and $dir like this:

<select name="column" id="column">

<option <?php if ($col == 'image_id') echo 'selected'; ?>>image_id</option> <option <?php if ($col == 'filename') echo 'selected'; ?>>filename</option> <option <?php if ($col == 'caption') echo 'selected'; ?>>caption</option>

</select>

<select name="direction" id="direction">

<option value="ASC" <?php if ($dir == 'ASC') echo 'selected'; ?>> 

Ascending</option>

<option value="DESC" <?php if ($dir == 'DESC') echo 'selected'; ?>>  Descending</option>

</select>

4 Save the page, and test it in a browser You can change the sort order of the display by

selecting the values in the drop-down menus and clicking Change However, if you try to inject

an illegal value through the query string, the page uses the default values of $col and $dir to display the results sorted by image_id in ascending order

You can check your code against mysqli_order_02.php and pdo_order_02.php in the ch11 folder

Trang 4

CHAPTER 11

334

Chapter review

PHP provides three methods of communicating with MySQL:

used for new projects If you need to maintain an existing site, you can easily recognize whether it uses the original MySQL extension, because all functions begin with mysql_ For help using it, consult the first edition of this book or use the online documentation at http://docs.php.net/manual/en/book.mysql.php

projects It requires PHP 5.0 and MySQL 4.1 or higher Its more efficient, and has the added safety of prepared statements

choose this option if your projects are likely to need to be adapted to use other databases Although PHP communicates with the database and stores the results, queries need to be written in SQL, the standard language used to query a relational database This chapter showed how to retrieve information stored in a database table using a SELECT statement, refining the search with a WHERE clause, and changing the sort order with ORDER BY You also learned several techniques to protect queries from SQL injection, including prepared statements, which use placeholders instead of embedding variables directly in a query

In the next chapter, youll put this knowledge to practical use creating an online photo gallery

Trang 5

335

Creating a Dynamic Online Gallery

The previous chapter concentrated mainly on extracting the contents of the images table as text This chapter builds on those techniques to develop the mini photo gallery shown in Figure 12-1

Figure 12-1 The mini photo gallery is driven by pulling information from a database

The gallery also demonstrates some cool features that youll want to incorporate into text-driven pages, too For instance, the grid of thumbnail images on the left displays two images per row Just by changing two numbers, you can make the grid as many columns wide and as many rows deep as you like Clicking one of the thumbnails replaces the main image and caption Its the same page that reloads, but exactly

Trang 6

CHAPTER 12

336

the same technique is used to create online catalogs that take you to another page with more details

about a product The Next link at the foot of the thumbnails grid shows you the next set of photographs,

using exactly the same technique as you use to page through a long set of search results This gallery isnt just a pretty face or two

What this chapter covers:

• Why storing images in a database is a bad idea, and what you should do instead

• Planning the layout of a dynamic gallery

• Displaying a fixed number of results in a table row

• Limiting the number of records retrieved at a time

• Paging through a long set of results

Why not store images in a database?

The images table contains only filenames and captions, but not the images themselves Even though I said in the previous chapter that you can always add new columns or tables to a database when new requirements arise, I dont intend to store the images in the database for the simple reason that its usually more trouble than its worth The main problems are as follows:

• Images cant be indexed or searched without storing textual information separately

• Images are usually large, bloating the size of tables If theres a limit on the amount of storage

in your database, you risk running out of space

• Table fragmentation affects performance if images are deleted frequently

• Retrieving images from a database involves passing the image to a separate script, slowing down display in a web page

Storing images in a database is messy Its more efficient to store images in an ordinary folder on your website and use the database for information about the images You need just two pieces of information in the database—the filename and a caption that can also be used as alt text Some developers store the full path to the image in the database, but I think storing only the filename gives you greater flexibility The path to the images folder will be embedded in the HTML You could also store the images height and width, but its not absolutely necessary As you saw in Chapter 4, you can generate that information dynamically

Planning the gallery

Unless youre good at visualizing how a page will look simply by reading its source code, I find that the best way to design a database-driven site is to start with a static page and fill it with placeholder text and images I then create my CSS style rules to get the page looking the way I want, and finally replace each placeholder element with PHP code Each time I replace something, I check the page in a browser to make sure everything is still holding together

Figure 12-2 shows the static mockup I made of the gallery and points out the elements that need to be converted to dynamic code The images are the same as those used for the random image generator in Chapter 4 and are all different sizes I experimented by scaling the images to create the thumbnails but decided that the result looked too untidy, so I made the thumbnails a standard size (80  54 pixels) Also,

Trang 7

337

to make life easy, I gave each thumbnail the same name as the larger version and stored them in a separate subfolder of the images folder called thumbs

As you saw in the previous chapter, displaying the contents of the entire images table was easy You created a single table row, with the contents of each field in a separate table cell By looping through the result set, each record displayed on a row of its own, simulating the column structure of the database table This time, the two-column structure of the thumbnail grid no longer matches the database structure This means that you need to count how many thumbnails have been inserted in each row before triggering the creation of the next row

Figure 12-2 Working out what needs to be done to convert a static gallery to a dynamic one

Figure 12-3 shows the framework I created to hold the gallery together The table of thumbnails and the main_image <div> are floated left and right respectively in a fixed-width wrapper <div> called gallery I dont intend to go into the details of the CSS, but you may study that at your leisure

Trang 8

CHAPTER 12

338

Figure 12-3 The underlying structure of the image gallery

Once I had worked out what needed to be done, I stripped out the code for thumbnails 2 to 6, and for the navigation link (which is nested in the final row of the thumbs table) The following listing shows what was left in the maincontent <div> of gallery.php, with the elements that need to be converted to PHP code highlighted in bold (you can find the code in gallery_01.php in the ch12 folder):

<div id="maincontent">

<h2>Images of Japan</h2>

<p id="picCount">Displaying 1 to 6 of 8</p>

<div id="gallery">

<table id="thumbs">

<tr>

<! This row needs to be repeated >

<td><a href="gallery.php"><img src="images/thumbs/basin.jpg" alt="" 

width="80" height="54"></a></td>

</tr>

<! Navigation link needs to go here >

</table>

<div id="main_image">

<p><img src="images/basin.jpg" alt="" width="350" height="237"></p>

<p>Water basin at Ryoanji temple, Kyoto</p>

</div>

</div>

</div>

Trang 9

339

Converting the gallery elements to PHP

Before you can display the contents of the gallery, you need to connect to the phpsols database and retrieve all the records stored in the images table The procedure for doing so is the same as in the previous chapter, using the following simple SQL query:

SELECT filename, caption FROM images

You can then use the first record to display the first image and its associated caption and thumbnail You dont need image_id

PHP Solution 12-1: Displaying the first image

If you set up the Japan Journey website in Chapter 4, you can work directly with the original gallery.php Alternatively, copy gallery_01.php from the ch12 folder, and save it in the phpsols site root as gallery.php You also need to copy title.inc.php, menu.inc.php, and footer.inc.php to the includes folder of the phpsols site If your editing program asks if you want to update the links in the files, choose the option not to update

1 Load gallery.php into a browser to make sure that it displays correctly The maincontent

part of the page should look like Figure 12-4, with one thumbnail image and a larger version of the same image

Figure 12-4 The stripped-down version of the static gallery ready for conversion

2 The gallery depends on a connection to the database, so include connection.inc.php,

create a read-only connection to MySQL, and define the SQL query Add the following code just before the closing PHP tag above the DOCTYPE declaration in gallery.php (new code is highlighted in bold):

include('./includes/title.inc.php');

require_once('./includes/connection.inc.php');

Trang 10

CHAPTER 12

340

$conn = dbConnect('read');

$sql = 'SELECT filename, caption FROM images';

If you are using PDO, add 'pdo' as the second argument to dbConnect()

3 The code for submitting the query and extracting the first record from the result depends on

which method of connection you are using

For MySQLi, use this:

// submit the query

$result = $conn->query($sql) or die(mysqli_error());

// extract the first record as an array

$row = $result->fetch_assoc();

For PDO, use this:

// submit the query

$result = $conn->query($sql);

// get any error messages

$error = $conn->errorInfo();

if (isset($error[2])) die($error[2]);

// extract the first record as an array

$row = $result->fetch();

To display the first image when the page loads, you need to get the first result on its own The code for both MySQLi and PDO submits the query, extracts the first record, and stores it in

$row

4 You now have the details of the first record image stored as $row['filename'] and

$row['caption'] In addition to the filename and caption, you need the dimensions of the large version so that you can display it in the main body of the page Add the following code immediately after the code in the preceding step:

// get the name and caption for the main image

$mainImage = $row['filename'];

$caption = $row['caption'];

// get the dimensions of the main image

$imageSize = getimagesize('images/'.$mainImage);

The getimagesize() function was described in Chapters 4 and 8

5 You can now use this information to display the thumbnail, main image, and caption

dynamically The main image and thumbnail have the same name, but you eventually want to display all thumbnails by looping through the full result set, so the dynamic code that goes in the table cell needs to refer to the current record—in other words, $row['filename'] and

$row['caption'], rather than to $mainImage and $caption Youll see later why Ive assigned the values from the first record to separate variables Amend the code in the table like this:

<td><a href="gallery.php"> ➥

<img src="images/thumbs/<?php echo $row['filename']; ?>" ➥

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

TỪ KHÓA LIÊN QUAN