2.9. Avatars

I'm taking advantage of the fact that each user must have a unique alphanumeric username. When saving an uploaded graphic for the avatar with the username as the filename, you don't have to worry about overwriting files. If a file does get overwritten, it's because the user is uploading a newer file for his or her avatar. This also spares you from tracking additional information in the database as mentioned earlier.

To upload a file through an HTML form, the form element must have the enctype attribute set to multipart/form-data. Then the user can specify the file through an input element:

<form action=upload_avatar.php" method="post" enctype="multipart/form-data">
 <div>
  <input type="file" name="avatar"/>
  <input type="submit" value="upload"/>
 </div>
</form>

Information about uploaded files is available to PHP in the $_FILES superglobal array. It's a multidimensional array with the name assigned to the HTML form's input element as the first index (useful when uploading multiple files) and the following for the second:

  • name — the original filename

  • tmp_name — the name of the file as it is stored temporarily on the server

  • size — the size of the file (reported in bytes)

  • type — the file's mime-type

  • error — an error code indicating the reason for failure of an upload (the value will be 0 if the upload was successful)

The uploaded file is temporarily stored and will be deleted once the script is done running, so usually it is necessary to copy the file to a permanent location using move_uploaded_file(). I'm going to take a different approach though because there's no telling what type of image the user will submit, or if the file will even be an image at all. And if it is a file, you want to make sure the dimensions aren't gigantic. I'll instead open the uploaded image and save a resized copy in the permanent location so I can guarantee its size and format.

The functionality of resizing the image can be encapsulated into a class for the purpose of reusability. Table 2-1 shows the publically available methods for JpegThumbnail.

Table 2-1. JpegThumbnail Properties and Methods
PropertyDescription
heightThe specified height of the thumbnail image
widthThe specified width of the thumbnail image
MethodDescription
__construct(width, height)Initialize a new JpegThumbnail object with the specified width and height
generate(image, [filename])Resize image image and send it to the browser or save to a file if filename is provided

Here is the code for lib/JpegThumbnail.php:

<?php
class JpegThumbnail
{
    public $width;  // maximum thumbnail width
    public $height; // maximum thumbnail height

    // intialize a new Thumbnail object
    public function __construct($width = 50, $height = 50)
    {
        $this->width = $width;
        $this->height = $height;

    }
    // accept a source file location and return an open image handle or
    // save to disk if destination provided
    public function generate($src, $dest = '')
    {
        // retrive image dimensions
        list($width, $height) = getimagesize($src);

        // determine if resize is necessary
        if(($lowest = min($this->width / $width, $this->height / $height)) < 1)
        {
            $tmp = imagecreatefromjpeg($src);

            // resize
            $sm_width = floor($lowest * $width);
            $sm_height = floor($lowest * $height);
            $img = imagecreatetruecolor($sm_width, $sm_height);
            imagecopyresized($img, $tmp, 0,0, 0,0, $sm_width, $sm_height,
                $width, $height);
            imagedestroy($tmp);
        }
        // image is already thumbnail size and resize not necessary
        else
        {
            $img = imagecreatefromjpeg($src);
        }

        // save to disk or return the open image handle
        if ($dest)
        {
            imagejpeg($img, $dest, 100);
            imagedestroy($img);
        }
        else
        {
            return $img;
        }
    }
}
?>

The upload_avatar.php code to handle the upload would then make use of the JpegThumbnail class:

<?php
// include shared code
include '../lib/common.php';
include '../lib/db.php';
include '../lib/functions.php';
include '../lib/User.php';
include '../lib/JpegThumbnail.php';
include '401.php';

$user = User::getById($_SESSION['userId']);

if (!$_FILES['avatar']['error'])
{
    // create a thumbnail copy of the image
    $img = new JpegThumbnail();
    $img->generate($_FILES['avatar']['tmp_name'],
        'avatars/' . $user->username . '.jpg'),
}
?>

But what happens if the user hasn't upload an avatar yet? It makes sense to have a default avatar to show for those users so view.php will not show a broken image link. You could modify the account creation script to copy a default icon into the avatar directory for the user, but this would needlessly waste hard disk space by having multiple copies of the same file. It would be better to check if the file exists and if it doesn't, then serve a default image.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.140.198.12