Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
建筑a";“工厂”;在PHP中_Php_Oop_Factory Pattern - Fatal编程技术网

建筑a";“工厂”;在PHP中

建筑a";“工厂”;在PHP中,php,oop,factory-pattern,Php,Oop,Factory Pattern,我创建了一个File类,它负责对文件、I/O的所有操作,并根据文件的性质采取不同的操作。我对它的实际结构不满意,它看起来是这样的: class File { function __construct($id) { $bbnq = sprintf(" SELECT * FROM documents WHERE id = %u",

我创建了一个File类,它负责对文件、I/O的所有操作,并根据文件的性质采取不同的操作。我对它的实际结构不满意,它看起来是这样的:

    class File
    {
        function __construct($id)
        {
            $bbnq = sprintf("
                SELECT *
                FROM documents
                WHERE id = %u",
                $id);
            $req = bbnf_query($bbnq);
            $bbn = $req->fetch();
            $this->file_type = $bbn['file_type'];
            $this->file_name = $bbn['file_name'];
            $this->title = $bbn['title'];
        }
        function display()
        {
            return '<a href="'.$this->file_name.'">'.$this->title.'</a>';
        }
    }

    class Image extends File
    {
        function __construct($id)
        {
            global $bbng_imagick;
            if ( $bbng_imagick )
                $this->imagick = true;
            parent::__construct($id);
        }
        function display()
        {
            return '<img src="'.$this->file_name.'" alt="'.$this->title.'" />';
        }
    }
类文件
{
函数构造($id)
{
$bbnq=sprintf(“
挑选*
从文件
其中id=%u“,
$id);
$req=bbnf\U查询($bbnq);
$bbn=$req->fetch();
$this->file_type=$bbn['file_type'];
$this->file_name=$bbn['file_name'];
$this->title=$bbn['title'];
}
函数显示()
{
返回“”;
}
}
类图像扩展文件
{
函数构造($id)
{
全球$bbng_imagick;
如果($bbng_imagick)
$this->imagick=true;
父项::_构造($id);
}
函数显示()
{
返回“文件名”。“alt=“”。$this->title。”“/>”;
}
}
在这里,我首先需要知道文件类型,以便确定使用哪个类/子类。
我想实现相反的效果,即向我的类发送一个ID,它返回一个与文件类型对应的对象。
我最近更新了PHP5.3,我知道有一些新特性可用于创建“工厂”(后期静态绑定?)。我的OOP知识非常简单,所以我想知道是否有一些结构建议,以便创建一个独特的类,调用正确的构造函数


谢谢!

我认为后期静态绑定与此无关-工厂模式不需要它们。请尝试以下方法:

class FileFactory
{
    protected static function determineFileType($id) 
    {
        // Replace these with your real file logic
        $isImage = ($id>0 && $id%2);
        $isFile = ($id>0 && !($id%2));

        if ($isImage) return "Image";
        elseif ($isFile) return "File";
        throw new Exception("Unknown file type for #$id");
    }

    public static function getFile($id) {
        $class = self::determineFileType($id);
        return new $class($id);
    }
}

// Examples usage(s)
for ($i=3; $i>=0; $i--) {
    print_r(FileFactory::getFile($i));
}
另一方面,无论您认为输出有多安全,都应该从数据库中转义输出。例如,在标题中使用双引号进行测试(更不用说恶意输入了)


此外,如果它是项目的一部分,您可能希望将视图层(您的HTML输出)与此模型层分离,即实现…

我认为后期静态绑定与此无关-工厂模式不需要它们。请尝试以下方法:

class FileFactory
{
    protected static function determineFileType($id) 
    {
        // Replace these with your real file logic
        $isImage = ($id>0 && $id%2);
        $isFile = ($id>0 && !($id%2));

        if ($isImage) return "Image";
        elseif ($isFile) return "File";
        throw new Exception("Unknown file type for #$id");
    }

    public static function getFile($id) {
        $class = self::determineFileType($id);
        return new $class($id);
    }
}

// Examples usage(s)
for ($i=3; $i>=0; $i--) {
    print_r(FileFactory::getFile($i));
}
另一方面,无论您认为输出有多安全,都应该从数据库中转义输出。例如,在标题中使用双引号进行测试(更不用说恶意输入了)


此外,如果它是项目的一部分,您可能希望将视图层(您的HTML输出)与此模型层分离,即在工厂的构造函数中实现…

,您需要确定文件类型,然后使用该类型创建相应类的对象。可能类似于:

class File
{

    public static function factory($id)
    {
        $fileData = <query this $id>
        switch ($fileData->type) {

            case image:
                return new ImageFile($fileData);
                break;

            case html:
                return new HtmlFile($fileData);
                break;

            default:
                // error?

        }
    }

}

abstract class FileAbstract
{
    // common file methods here
}

// override the custom bits for each type
class ImageFile extends FileAbstract
{
    public function display()
    {
        // ...
    }
}

class HtmlFile extends FileAbstract
{
    public function display()
    {
        // ...
    }
}

在工厂的构造函数中,您需要确定文件类型,然后使用该类型创建相应类的对象。可能类似于:

class File
{

    public static function factory($id)
    {
        $fileData = <query this $id>
        switch ($fileData->type) {

            case image:
                return new ImageFile($fileData);
                break;

            case html:
                return new HtmlFile($fileData);
                break;

            default:
                // error?

        }
    }

}

abstract class FileAbstract
{
    // common file methods here
}

// override the custom bits for each type
class ImageFile extends FileAbstract
{
    public function display()
    {
        // ...
    }
}

class HtmlFile extends FileAbstract
{
    public function display()
    {
        // ...
    }
}

谢谢!就是这样!关于你的其他评论,我刚刚举了一个例子,因为我的类是50000个字符。我没有用这个::)只是一个问题:FileFactory::getFile()在5.3之前可行吗?(我知道我在OOP方面很差劲)是的,OO在PHP5.3之前就存在了,只是5.3对它进行了一些扩展和限制。
FileFactory::getFile()
使用head getFile()调用FileFactory上的静态方法;看看它是如何声明的
static
。谢谢!就是这样!关于你的其他评论,我刚刚举了一个例子,因为我的类是50000个字符。我没有使用它。:)只是一个问题:FileFactory::getFile()在5.3之前是可行的吗?(我知道我在OOP方面很差劲)是的,OO在PHP5.3之前就已经存在了,只是5.3对它进行了一些扩展和严格化。
FileFactory::getFile()
使用head-getFile()调用FileFactory上的静态方法;看看它是如何声明的
静态的
。谢谢,但是该死的,现在我必须理解类的抽象!我正在做…如果你有时间,这里有一个抽象类比有一个主类(文件)有什么好处使用普通方法?很明显,有不止一种方法可以做到这一点,您选择哪种方法是个人偏好的问题,也是“良好实践”的问题。在这种情况下,优点之一是您坚持单一责任原则。(请参阅)具体实现(例如,ImageFile()的实例)不会使用工厂方法本身,因此将这些代码放在它们都从中继承的类中是没有意义的。换句话说,工厂类包含工厂方法的代码,而具体类永远不会需要这些代码——而从抽象继承的具体类包含实际的文件操作逻辑,w工厂类永远不会需要它。谢谢,但是该死的,现在我必须理解类的抽象!我正在做…如果你有时间,这里有一个抽象类比有一个主类(文件)有什么好处使用普通方法?很明显,有不止一种方法可以做到这一点,您选择哪种方法是个人偏好的问题,也是“良好实践”的问题。在这种情况下,优点之一是您坚持单一责任原则。(请参阅)具体实现(例如,ImageFile()的实例)不会使用工厂方法本身,因此将这些代码放在它们都从中继承的类中是没有意义的。换句话说,工厂类包含工厂方法的代码,而具体类永远不会需要这些代码——而从抽象继承的具体类包含实际的文件操作逻辑,w这是工厂级永远不需要的。