Class Design - Image Upload - Resize (no cropping)
Here is the edited class which inlcudes the answer:
EDIT: Included Answers
<?php
class Upload
{
private $originalWidth,
$originalHeight,
$newWidth,
$newHeight,
$maxMedium = 50,
$maxSmall = 20;
private $src = NULL;
private
$fileType,
$fileName,
$sessionId,
$path_medium,
$path_small;
function __construct($fileType, $fileName)
{
if(1)
{
Session::start();
Session::activate(0, 1000, 'Test Account A', 'bookmarks');
}
/**
* Initialize the Object
*/
$this->sessionId = Session::get('id');
$this->path_medium = PICTURES . "/$this->sessionId.jpg";
$this->path_small = PICTURES . "/$this->sessionId-1.jpg";
$this->fileType = $fileType;
$this->fileName = $fileName;
开发者_开发技巧 /**
* Instantiate the Object
*/
$this->instantiate();
}
private function instantiate()
{
$this->createImages();
$this->updateSessionAndDb();
}
private function createImages()
{
if(move_uploaded_file($this->fileName, $this->path_medium))
{
if($this->get_image($this->path_medium))
{
list($this->originalWidth,$this->originalHeight)=getimagesize($this->path_medium);
$this->newWidth = $this->originalWidth;
$this->newHeight = $this->originalHeight;
// these could each be another class instead of two functions..but no time to refactor further
$this->resize_move($this->maxMedium,$this->path_medium);
$this->resize_move($this->maxSmall,$this->path_small);
imagedestroy($this->src);
}
}
}
private function updateSessionAndDb()
{
$db = new Database();
$result = $db->_pdoQuery('none', 'update_picture', array($this->sessionId));
Session::set('picture',1);
}
private function resize_move($max, $path)
{
$this->makeProportions($max);
$image_true_color = imagecreatetruecolor($this->newWidth, $this->newHeight);
imagecopyresampled($image_true_color, $this->src, 0, 0, 0, 0, $this->newWidth, $this->newHeight, $this->
originalWidth, $this->originalHeight);
imagejpeg($image_true_color, $path);
imagedestroy($image_true_color);
}
private function makeProportions($max)
{
$this->newWidth=$this->originalWidth;
$this->newHeight=$this->originalHeight;
if(($this->originalWidth > $this->originalHeight) && ($this->originalWidth > $max))
{
$this->newWidth = $max;
$this->newHeight = ($max / $this->originalWidth) * $this->originalHeight;
}
elseif($this->originalHeight > $this->originalWidth && $this->originalHeight > $max)
{
$this->newHeight = $max;
$this->newWidth = ($max / $this->originalHeight) * $this->originalWidth;
}
elseif ($this->originalWidth > $max)
{
$this->newWidth = $this->newHeight = $max;
}
}
private function get_image($path)
{
$type_creators = array(
'image/gif' => 'imagecreatefromgif',
'image/pjpeg' => 'imagecreatefromjpeg',
'image/jpeg' => 'imagecreatefromjpeg',
'image/png' => 'imagecreatefrompng');
if(array_key_exists($this->fileType, $type_creators))
{
$this->src = $type_creators[$this->fileType]($path);
return true;
}
return false;
}
}
A few things I noted:
Your method and variable name should be clearer. Specifically,
rmove
should be renamed to something more descriptive, as well as every single one of your private member variables. Shoot for clarity rather than brevity with function and variable names.Remove references to $_FILES and $_SESSION from you class, and instead pass that information into the constructor. There is no need to couple this class with the implemenation details of the surrounding client code. You might want to reuse it in some other circumstance where the email wasn't in the session variable, or the file info was not in $_FILES.
You can rewrite your
get_image()
method as follows, to make it cleaner and shorter. Note that using this method, adding support for new image types simply involves adding them to the array at the start of the method. You could even move that array out of the method and provide it as a static member variable.function get_image($path) { $type_creators = array( 'image/gif' => 'imagecreatefromgif', 'image/jpeg' => 'imagecreatefromjpeg', 'image/png' => 'imagecreatefrompng', ); $img_type = $_FILES['ufile']['type']; if (array_key_exists($img_type, $type_creators)) { $this->src = $type_creators[$img_type]($path); return true; } return false; }
Don't pass member variables as arguments into methods. Remember, they are automatically available already. So rather than
$this->rmove($this->max1,$path3);
, simply access$this->max1
from withinrmove
.Consider breaking
rmove
down into smaller private functions whose names clearly describe what is going on in each case of the if statement.Also,
rmove
is performing two distinct operations right now: 1) Recalculating the true width and height and 2) creating a new version of the image based on these dimensions. I would break it down into two methods that perfrom each of these tasks separately.Finally, a larger issue to consider: This class does not have any public API. There is no reason any of its methods need to be public right now, as client code will never use them. Right now, the class is just acting as container code to do a bunch of tasks that should be triggered after a file upload. So you should consider rethinking how client code could use this class in other circumstances.
精彩评论