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

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

10 351 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 465,6 KB

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

Nội dung

To give you just a taste of PHP image manipulation, Im going to show you how to generate a smaller copy of an uploaded image.. In this chapter, youll create two classes: one to generate

Trang 1

USING PHP TO MANAGE FILES

211

2 Remove any default code created by your script editor, and insert the following code:

<?php

// define error page

$error = 'http://localhost/phpsols/error.php';

// define the path to the download folder

$filepath = 'C:/xampp/htdocs/phpsols/images/';

$getfile = NULL;

// block any attempt to explore the filesystem

if (isset($_GET['file']) && basename($_GET['file']) == $_GET['file']) { $getfile = $_GET['file'];

} else {

header("Location: $error");

exit;

}

if ($getfile) {

$path = $filepath $getfile;

// check that it exists and is readable

if (file_exists($path) && is_readable($path)) {

// get the file's size and send the appropriate headers

$size = filesize($path);

header('Content-Type: application/octet-stream');

header('Content-Length: ' $size);

header('Content-Disposition: attachment; filename=' $getfile);

header('Content-Transfer-Encoding: binary');

// open the file in read-only mode

// suppress error messages if the file can't be opened

$file = @fopen($path, 'r');

if ($file) {

// stream the file and exit the script when complete

fpassthru($file);

exit;

} else {

header("Location: $error");

}

} else {

header("Location: $error");

}

The only two lines that you need to change in this script are highlighted in bold type The first defines $error, a variable that contains the URL of your error page The second line that

needs to be changed defines the path to the folder where the download file is stored

The script works by taking the name of the file to be downloaded from a query string appended

to the URL and saving it as $getfile Because query strings can be easily tampered with,

Trang 2

CHAPTER 7

212

$getfile is initially set to NULL This is an important security measure If you fail to do this, you could give a malicious user access to any file on your server

The opening conditional statement uses basename() to make sure that an attacker cannot request a file, such as one that stores passwords, from another part of your file structure As explained in Chapter 4, basename() extracts the filename component of a path, so if

basename($_GET['file']) is different from $_GET['file'], you know theres an attempt to probe your server, and you can stop the script from going any further by using the header() function to redirect the user to the error page

After checking that the requested file exists and is readable, the script gets the files size, sends the appropriate HTTP headers, and opens the file in read-only mode using fopen() Finally, fpassthru() dumps the file to the output buffer But if the file cant be opened or doesnt exist, the user is redirected to the error page

3. Test the script by creating another page and add a couple of links to download.php Add a query string at the end of each link with file= followed by the name a file to be downloaded Youll find a page called getdownloads.php in the ch07 folder, which contains the following two links:

<p><a href="download.php?file=maiko.jpg">Download image 1</a></p>

<p><a href="download.php?file=basin.jpg">Download image 2</a></p>

4 Click one of the links, and the browser should present you with a dialog box prompting you to

download the file or choose a program to open it, as shown in Figure 7-6

Figure 7-6 The browser prompts the user to download the image, rather than opening it directly

Trang 3

USING PHP TO MANAGE FILES

213

5 Select Save File, and click OK, and the file should be saved rather than displayed Click

Cancel to abandon the download Whichever button you click, the original page remains in the

browser window The only time download.php should load into the browser is if the file cannot

be opened Thats why its important to send the user to an error page if theres a problem Ive demonstrated download.php with image files, but it can be used for any type of file because the headers send the file as a binary stream

This script relies on header() to send the appropriate HTTP headers to the browser It is vital to ensure that there are no new lines or whitespace ahead of the opening PHP tag If you have removed all whitespace and still get an error message saying “headers already sent,” your editor may have inserted invisible control characters at the beginning of the file Some editing programs insert the byte order mark (BOM), which is known to cause problems with the ability to use the header() function Check your program preferences to make sure the option to insert the BOM is deselected

Chapter review

The file system functions arent particularly difficult to use, but there are many subtleties that can turn a seemingly simple task into a complicated one Its important to check that you have the right permissions Even when handling files in your own website, PHP needs permission to access any folder where you want

to read files or write to them

The SPL DirectoryIterator and RecursiveDirectoryIterator classes make it easy to examine the contents of folders Used in combination with the SplFileInfo methods and the RegexIterator, you can quickly find files of a specific type within a folder or folder hierarchy

When dealing with remote data sources, you need to check that allow_url_fopen hasnt been disabled One of the most common uses of remote data sources is extracting information from RSS news feeds or XML documents, a task that takes only a few lines of code thanks to SimpleXML

In the next two chapters, well put some of the PHP solutions from this chapter to further practical use when working with images and building a simple user authentication system

Trang 4

CHAPTER 7

214

Trang 5

215

Chapter 8

Generating Thumbnail Images

PHP has an extensive range of functions designed to work with images Youve already met one of them, getimagesize(), in Chapter 4 As well as providing useful information about an images dimensions, PHP can manipulate images by resizing or rotating them It can also add text dynamically without affecting the original; it can even create images on the fly

To give you just a taste of PHP image manipulation, Im going to show you how to generate a smaller copy

of an uploaded image Most of the time, youll want to use a dedicated graphics program, such as Photoshop or Fireworks, to generate thumbnail images because it gives you much better quality control However, automatic thumbnail generation with PHP can be very useful if you want to allow registered users to upload images, but make sure they conform to a maximum size You can save just the resized copy, or the copy along with the original

In Chapter 6, you built a PHP class to handle file uploads In this chapter, youll create two classes: one to generate thumbnail images, the other to upload and resize images in a single operation Rather than build the second class from scratch, youll base it on the Ps2_Upload class from Chapter 6 A great advantage

of using classes is that theyre extensible—a class based on another can inherit the functionality of its parent class Building the classes to upload images and generate thumbnails from them involves a lot of code But once you have defined the classes, using them involves only a few lines of script If youre in a rush or writing a lot of code makes you break out in a cold sweat, you can just use the finished classes Come back later to learn how the code works It uses many basic PHP functions that youll find useful in other situations

In this chapter youll learn about the following:

• Scaling an image

• Saving a rescaled image

• Automatically resizing and renaming uploaded images

• Creating a subclass by extending an existing one

Trang 6

CHAPTER 8

216

Checking your servers capabilities

Working with images in PHP relies on the GD extension Originally GD stood for GIF Draw, but problems with the GIF patent led to support for GIF files being dropped in 1999, but the name GD stuck The problematic patent expired in 2004, and GIF is once again supported The all-in-one PHP packages recommended in Chapter 2 support GD by default, but you need to make sure the GD extension has also been enabled on your remote web server

As in previous chapters, run phpinfo() on your website to check the servers configuration Scroll down until you reach the section shown in the following screenshot (it should be about halfway down the page)

If you cant find this section, the GD extension isnt enabled, so you wont be able to use any of the scripts

in this chapter on your website Ask for it to be enabled or move to a different host

Strictly for abbreviation/acronym freaks: GIF stands for Graphics Interchange Format, JPEG is the standard created by the Joint Photographic Experts Group, and PNG is short for Portable Network Graphics Although JPEG is the correct name for the standard, the “E” is frequently dropped, particularly when used as a filename extension

Manipulating images dynamically

The GD extension allows you to generate images entirely from scratch or work with existing images Either way, the underlying process always follows four basic steps:

1 Create a resource for the image in the servers memory while its being processed

Trang 7

GENERATING THUMBNAIL IMAGES

217

2 Process the image

3 Display and/or save the image

4 Remove the image resource from the servers memory

This process means that you are always working on an image in memory only and not on the original Unless you save the image to disk before the script terminates, any changes are discarded Working with images requires a lot of memory, so its vital to destroy the image resource as soon as its no longer needed If a script runs very slowly or crashes, it probably indicates that the original image is too large

Making a smaller copy of an image

The aim of this chapter is to show you how to resize images automatically on upload This involves extending the Ps2_Upload class from Chapter 6 However, to make it easier to understand how to work with PHPs image manipulation functions, I propose to start by using images already on the server, and create a separate class to generate the thumbnail images

Getting ready

The starting point is the following simple form, which uses PHP Solution 7-3 to create a drop-down menu of the photos in the images folder You can find the code in create_thumb_win01.php and create_thumb_mac01.php in the ch08 folder Copy it to a new folder called gd in the phpsols site root, and rename it create_thumb.php

<form id="form1" name="form1" method="post" action="">

<p>

<select name="pix" id="pix">

<option value="">Select an image</option>

<?php

$files = new DirectoryIterator(' /images');

$images = new RegexIterator($files, '/\.(?:jpg|png|gif)$/i');

foreach ($images as $image) {

?>

<option value="C:/xampp/htdocs/phpsols/images/<?php echo $image; ?>"> 

<?php echo $image; ?></option>

<?php } ?>

</select>

</p>

<p>

<input type="submit" name="create" id="create" value="Create Thumbnail">

</p>

</form>

The Win and Mac versions contain the fully qualified path to the images folder in default installations of XAMPP and MAMP If necessary, change the path (highlighted in bold) to match your setup When loaded into a browser, the drop-down menu should display the names of the photos in the images folder This makes it easier to pick images quickly for testing

Trang 8

CHAPTER 8

218

Inside the upload_test folder that you created in Chapter 6, create a new folder called thumbs, and make sure it has the necessary permissions for PHP to write to it Refer to “Establishing an upload directory” in Chapter 6 if you need to refresh your memory

Building the Ps2_Thumbnail class

To generate a thumbnail image, the class needs to execute the following steps:

1 Get the dimensions of the original image

2 Get the images MIME type

3 Calculate the scaling ratio

4 Create an image resource of the correct MIME type for the original image

5 Create an image resource for the thumbnail

6 Create the resized copy

7 Save the resized copy to the destination folder using the correct MIME type

8 Destroy the image resources to free memory

In addition to generating a thumbnail image, the class automatically inserts _thb before the filename extension, but a public method allows you to alter this value The class also needs public methods to set the destination folder and the maximum size of the thumbnail, and to retrieve messages generated by the class To keep the calculations simple, the maximum size controls only the larger of the thumbnails dimensions

Theres a lot to do, so Ill break up the code into sections Theyre all part of the same class definition, but presenting the script this way should make it easier to understand, particularly if you want to use some of the code in a different context

PHP Solution 8-1: Getting the image details

This PHP Solution describes how to get the dimensions and MIME type of the original image

1 Create a new page called Thumbnail.php in the classes/Ps2 folder The file will contain only

PHP, so strip out any HTML code inserted by your editing program

2 The class needs to keep track of quite a few properties Begin the class definition by listing

them like this:

<?php

class Ps2_Thumbnail {

protected $_original;

protected $_originalwidth;

protected $_originalheight;

protected $_thumbwidth;

protected $_thumbheight;

protected $_maxSize = 120;

protected $_canProcess = false;

protected $_imageType;

Trang 9

GENERATING THUMBNAIL IMAGES

219

protected $_destination;

protected $_name;

protected $_suffix = '_thb';

protected $_messages = array();

}

As in the Ps2_Upload class, all the properties have been declared as protected, which means they cant be changed accidentally outside the class definition Again, I have followed the convention of beginning protected property names with an underscore The names are

descriptive, so they need little explanation The $_maxSize property has been given a default value of 120 (pixels) This determines the maximum size of the thumbnails longer dimension The $_canProcess Boolean is initially set to false This is to prevent the script from

attempting to process a file that isnt an image The value will be reset to true if the MIME type matches that of an image You can also use it to prevent the generation of a thumbnail if

another error occurs

3 The constructor takes one argument, the path to an image Add the constructor definition after

the list of protected properties, but inside the the closing curly brace:

protected $_messages = array();

public function construct($image) {

if (is_file($image) && is_readable($image)) {

$details = getimagesize($image);

} else {

$details = null;

$this->_messages[] = "Cannot open $image.";

}

// if getimagesize() returns an array, it looks like an image

if (is_array($details)) {

$this->_original = $image;

$this->_originalwidth = $details[0];

$this->_originalheight = $details[1];

// check the MIME type

$this->checkType($details['mime']);

} else {

$this->_messages[] = "$image doesn't appear to be an image.";

}

}

}

The constructor begins with a conditional statement that checks that $image is a file and is readable If it is, its passed to getimagesize() and the result is stored in $details

Otherwise, $details is set to null, and an error message is added to the $_messages

property

When you pass an image to getimagesize(), it returns an array containing the following elements:

Trang 10

CHAPTER 8

220

• 0: width (in pixels)

• 1: height

• 2: an integer indicating the type of image

• 3: a string containing the correct width and height attributes ready for insertion

in an <img> tag

• mime: the images MIME type

• channels: 3 for RGB, and 4 for CMYK images

• bits: the number of bits for each color

If the value passed as an argument to getimagesize() isnt an image, it returns false Consequently, if $details is an array, you know youre dealing with an image The images path is stored in the $_original property, and its width and height are stored in

$_originalWidth and $_originalHeight respectively

However, the image might not be a suitable type, so the final check is to pass its MIME type to

an internal method called checkType(), which youll define next

4 The checkType() method compares the MIME type with an array of acceptable image types If

it finds a match, it resets the $_canProcess property to true, and stores the type in the

$_imageType property The method is used internally, so it needs to be declared as protected Add the following code to the class definition:

protected function checkType($mime) {

$mimetypes = array('image/jpeg', 'image/png', 'image/gif');

if (in_array($mime, $mimetypes)) {

$this->_canProcess = true;

// extract the characters after 'image/'

$this->_imageType = substr($mime, 6);

}

}

There are many types of images, but only JPEG, PNG, and GIF are used in web pages, so the

$_canProcess property is set to true only if the images MIME type matches one of those listed in the $mimetypes array If the MIME type isnt in the list $_canProcess remains false, which later prevents the class from attempting to create a thumbnail

All image MIME types begin with image/ To make the value easier to use later, the substr() function extracts the characters after the slash and stores them in the $_imageType

property When used with two arguments, substr() starts at the position (counting from 0) specified in the second argument, and returns the rest of the string

5 Its a good idea to test your code as you build the class Catching errors early is much easier

than hunting for a problem in a long script To test the code, create a new public method called test() inside the class definition

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

TỪ KHÓA LIÊN QUAN