为了账号安全,请及时绑定邮箱和手机立即绑定

PHP如何使用Decorator模式解密后使用解压?

PHP如何使用Decorator模式解密后使用解压?

PHP
一只斗牛犬 2023-07-15 18:33:16
出于学习目的,我尝试创建一个 GoF Decorator 实现,以将文本转换为压缩文本或加密文本的可能性为例。    <?php    interface DataSource {        public function gerar($texto): string;        public function recuperar($texto) : string;    }    class TextoBase implements DataSource {        public function gerar($texto): string {            return $texto;        }        public function recuperar($texto) : string {            return $texto;        }    }    abstract class Decorator implements DataSource {        private DataSource $decorado;        public function __construct(DataSource $decorado) {            $this->decorado = $decorado;        }        public function gerar($texto): string {            return $this->decorado->gerar($texto);        }        public function recuperar($texto) : string {            return $this->decorado->recuperar($texto);        }    }   class CriptoDecorator extends Decorator {    const KEY = 'vDIa5JdknBqfrKOu8d7UpddnBMCH1vza';    const NONCE = 'Ra5LeH7ntW2rvkz3dmqI5Stx';    public function gerar($texto): string {        return $this->encrypt(parent::gerar($texto));    }    public function recuperar($texto): string {        return $this->decrypt(parent::recuperar($texto));    }    public function encrypt($data) {        return sodium_crypto_secretbox($data, self::NONCE, self::KEY);    }    private function decrypt(string $data): string {        return sodium_crypto_secretbox_open($data, self::NONCE, self::KEY);    }}    class CompressaoDecorator extends Decorator {        const NIVEL_COMPRESSAO = 6;        public function gerar($texto): string {            return $this->comprimir(parent::gerar($texto));        }由于某种原因,我收到警告:Warning: gzuncompress(): data error in C:\wamp64\www\curso\designer_patterns\estrutural\decorator\real_life.php on line 93那么,有没有办法解决这个问题并允许两个装饰器堆叠并用于 gerar(generate) 和 recuperar(retrieve) ?
查看完整描述

1 回答

?
白衣非少年

TA贡献1155条经验 获得超0个赞

您需要按照您设置的顺序展开。如果先压缩然后加密,则需要解密然后解压缩。


此特定代码的快速修复方法是更改您的recuperar方法CompressaoDecorator


class CompressaoDecorator extends Decorator

{

    public function recuperar($texto): string

    {

        return parent::recuperar($this->descomprimir($texto));

    }

}

如果你想抽象地解决这个问题,我会用一个可以保证订单的工厂来处理这个问题。为此,我认为单个对象本身不应该关心parent,工厂应该完成链接事物的工作。


编辑


实际上,当我更多地考虑这一点时,您不需要工厂,您只需将所有方法的顺序交换即可recuperar,因此这个也会改变:


class CriptoDecorator extends Decorator

{

    public function recuperar($texto): string

    {

        return parent::recuperar($this->decrypt($texto));

    }

}

这应该允许您首先调用加密或压缩,并且只要您使用相同的链,相反的操作也应该起作用。


查看完整回答
反对 回复 2023-07-15
  • 1 回答
  • 0 关注
  • 87 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信