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

PHP如何使用Decorator模式在解密后使用解压缩?,php,compression,decorator,libsodium,Php,Compression,Decorator,Libsodium,出于研究目的,我试图创建一个GoF装饰器实现,使用一个将文本转换为压缩文本或加密文本的可能性作为示例 <?php interface DataSource { public function gerar($texto): string; public function recuperar($texto) : string; } class TextoBase implements DataSource { pu

出于研究目的,我试图创建一个GoF装饰器实现,使用一个将文本转换为压缩文本或加密文本的可能性作为示例

    <?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));
        }
        public function recuperar($texto): string {
            return $this->descomprimir(parent::recuperar($texto));
        }
        private function comprimir(string $stringData): string {
            return gzcompress($stringData, self::NIVEL_COMPRESSAO);
        }
        private function descomprimir(string $stringData): string {
            return gzuncompress($stringData);
        }
    }
    $texto = "olá mundo !";
    $decorado = new CompressaoDecorator(new CriptoDecorator(new TextoBase()));
    $texto_decorado = $decorado->gerar($texto);
    echo PHP_EOL;
    echo $decorado->recuperar($texto_decorado);
那么,有没有一种方法可以解决这个问题,并允许这两个装饰器堆叠起来,并用于生成和检索


提前感谢

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

此特定代码的快速修复方法是在
compressodecorator

类compressodecorator扩展Decorator
{
公共函数重现器($texto):字符串
{
返回父项::Reciperar($this->decomprimir($texto));
}
}
如果你想抽象地解决这个问题,我会找一家能保证订单的工厂来处理。要做到这一点,我认为单个对象本身不应该与父对象相关,工厂应该做链接的工作

编辑

实际上,当我进一步思考这个问题时,您不需要工厂,只需要将订单交换为所有的
recurperar
方法,所以这个方法也会改变:

类scriptodecorator扩展Decorator { 公共函数重现器($texto):字符串 { 返回父级::Reciperar($this->decrypt($texto)); } } 这应该允许您首先调用encrypt或compress,并且只要使用相同的链,反向调用也会起作用。

非常感谢,我这样做了:(不幸的是3v4l没有启用钠:()
Warning: gzuncompress(): data error in C:\wamp64\www\curso\designer_patterns\estrutural\decorator\real_life.php on line 93