I have some modular ( object and classes ) JavaScript and PHP. I keep getting advice to get rid of global variables…”they are bad”…I guess because they cause dependencies.
However where should I put environment variables – the best example being path information.
Here is a quintessential example.
The UploadFile class below needs
const PICTURES = '../pictures/';
particularly in this spot ( no need to read entire class )
$this->path_medium = UploadedFile::PICTURES . "$this->sessionId.jpg";
$this->path_small = UploadedFile::PICTURES . "$this->sessionId-1.jpg";
to no where to upload files to. I would prefer to put it in a GlobalClass and access it from there. It makes sense as other code will need to know where pictures go, and I will have only one location to make updates.
Are having environment variables O.K to have as globals so they can be accessed from multiple modules yet edited in only one place.
<?php
/**
* Module : Model
* Name : UploadFile
* Input : File Information
* Output : Resized Files in .jpg format
* Notes :
resizeMove() - resizes the picture to $maxMedium and $maxSmall and moves the file to a permanent location.
makeDimensions() - calculates the dimensions of the new images so that there is not distortion if possible.
getImage() - creates a php image for manipulation.
updateSessionAndDb - updates the mysql table - move out.
*/
class UploadedFile
{
const PICTURES = '../pictures/';
private $originalWidth,
$originalHeight,
$newWidth,
$newHeight,
$maxMedium = 50,
$maxSmall = 20;
private $src = NULL;
private
$fileType,
$fileName,
$sessionId,
$path_medium,
$path_small;
function __construct($fileType, $fileName)
{
$this->sessionId = Session::get('id');
$this->path_medium = UploadedFile::PICTURES . "$this->sessionId.jpg";
$this->path_small = UploadedFile::PICTURES . "$this->sessionId-1.jpg";
$this->fileType = $fileType;
$this->fileName = $fileName;
}
public function createImages()
{
if(move_uploaded_file($this->fileName, $this->path_medium))
{
if($this->getImage($this->path_medium))
{
list($this->originalWidth,$this->originalHeight)=getimagesize($this->path_medium);
$this->resizeMove($this->maxMedium,$this->path_medium);
$this->resizeMove($this->maxSmall,$this->path_small);
imagedestroy($this->src);
}
}
}
private function resizeMove($max, $path)
{
$this->makeDimensions($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 makeDimensions($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 getImage($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;
}
}
Object Maker Example
class ObjectMaker
{
public function makeSignUp()
{
$DatabaseObject = new Database();
$TextObject = new Text();
$MessageObject = new Message();
$SignUpObject = new ControlSignUp();
$SignUpObject->setObjects($DatabaseObject, $TextObject, $MessageObject);
return $SignUpObject;
}
Object Maker Example Revised
class ObjectMaker
{
public function makeSignUp()
{
$DatabaseObject = new Database();
$TextObject = new Text();
$MessageObject = new Message();
return new ControlSignUp( $DatabaseObject, $TextObject, $MessageObject );
}
Notes:
I have may classes similar to SignUp so I can use inheritance to reduce redundancy of object creation by using an ObjectMaker Class – Back to the original problem – I can include injection of Globals not just Objects in this “pattern”.
If you want to make your class re-useable, you should not hardcode stuff in there, but inject it instead. Like the session id and the base directory for the images. Add those as parameters to your constructor:
Additionally you should create a class of it’s own, one to resize a picture and one to do the size calculations. Actually such classes already exist, so you just need to include some file, and do the resize (e.g. with WideImage).