将环境变量变为全局是一种好习惯吗?

时间:2012-04-16 18:58:39

标签: php

我有一些模块化(对象和类)JavaScript和PHP。我一直在寻求摆脱全局变量的建议......“它们很糟糕”......我想因为它们会导致依赖性。

但是我应该在哪里放置环境变量 - 最好的例子是路径信息。

这是一个典型的例子。

下面的UploadFile类需要

const     PICTURES = '../pictures/';

特别是在这个地方(无需阅读全班)

$this->path_medium = UploadedFile::PICTURES . "$this->sessionId.jpg";
$this->path_small = UploadedFile::PICTURES . "$this->sessionId-1.jpg";

没有上传文件的位置。我宁愿把它放在GlobalClass中并从那里访问它。这是有意义的,因为其他代码需要知道图片的去向,我将只有一个位置进行更新。

将环境变量O.K作为全局变量,以便可以从多个模块访问它们,但只能在一个地方进行编辑。

<?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; 
    }
}

对象制作者示例

class ObjectMaker
{
    public function makeSignUp()
    {
        $DatabaseObject = new Database();
        $TextObject = new Text();
        $MessageObject = new Message();

        $SignUpObject = new ControlSignUp();        
        $SignUpObject->setObjects($DatabaseObject, $TextObject, $MessageObject);
        return $SignUpObject;
    }

对象制作者示例已修订

    class ObjectMaker
    {
        public function makeSignUp()
        {
            $DatabaseObject = new Database();
            $TextObject = new Text();
            $MessageObject = new Message();

            return new ControlSignUp( $DatabaseObject, $TextObject, $MessageObject );        
        }

备注:

我有类似于SignUp的类,所以我可以使用继承通过使用ObjectMaker类来减少对象创建的冗余 - 回到原始问题 - 我可以包括注入Globals而不仅仅是这个“模式”中的对象。

3 个答案:

答案 0 :(得分:3)

如果你想让你的课程可以重复使用,你不应该在那里硬编码,而是注入它。像会话ID和图像的基本目录。将它们作为参数添加到构造函数中:

function __construct($fileType, $fileName, $sessionId, $prefixPictures)
{
    $this->fileType = $fileType;
    $this->fileName = $fileName;
    $this->sessionId = $sessionId;
    $this->prefixPictures = $prefixPictures;

    $this->path_medium = $prefixPictures . $this->sessionId . ".jpg";
    $this->path_small = $prefixPictures . $this->sessionId . "-1.jpg";
}

此外,您应该创建一个自己的类,一个用于调整图片大小,另一个用于进行大小计算。实际上这些类已经存在,所以你只需要包含一些文件,并进行调整大小(例如使用WideImage)。

答案 1 :(得分:1)

可能不是。您可以创建一个路径getter来输出路径类的属性(即Paths::pictures

然后再次,在那个层面上它取决于开发者。

我认为,出于组织的考虑,将它们全部放在命名空间中并以这种方式调用它是很好的。当新的开发者出现时它会有所帮助

答案 2 :(得分:1)

常量不像全局变量那么糟糕,并且将它用于路径是迄今为止最常用的方法来克服PHP没有“真正的”根路径变量的尴尬(你可以使用<基于当前脚本来获取它) strong> DIR ,但不是基于调用当前脚本的脚本。)

全局变量坏的主要原因不是因为它们是全局变量,而是因为它们可以在脚本的任何地方进行更改。事实上,这是我对PHP的主要抱怨之一 - $ _SERVER变量可以在脚本运行期间更改,我希望它们是常量。

只能定义和使用常量,并且无法编辑它们。只要你足够好地记录全局变量的存在,那么管理它们并不比管理任何其他PHP环境变量困难。

只要你不跟他们一起疯狂就可以了。请记住,环境在测试时总是起作用,只要您了解环境并且可以轻松模拟它,那么它就不会给测试带来更多问题。