代码之家  ›  专栏  ›  技术社区  ›  celsowm

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

  •  0
  • celsowm  · 技术社区  · 4 年前

    出于研究的目的,我试图创建一个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);
    

    出于某种原因我得到警告:

    Warning: gzuncompress(): data error in C:\wamp64\www\curso\designer_patterns\estrutural\decorator\real_life.php on line 93
    

    那么,有没有一种方法可以解决这个问题,允许这两个装饰器被堆叠起来,并被用于gerar(generate)和reciperar(retrieve)?

    0 回复  |  直到 4 年前
        1
  •  1
  •   Chris Haas    4 年前

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

    recuperar 方法 CompressaoDecorator

    class CompressaoDecorator extends Decorator
    {
        public function recuperar($texto): string
        {
            return parent::recuperar($this->descomprimir($texto));
        }
    }
    

    如果你想抽象地解决这个问题,我会找一个能保证订单的工厂来处理。要做到这一点,我不认为单个对象本身应该关心它们自己 parent ,工厂应该做链锁的工作。

    编辑

    事实上,当我想得更多的时候,你不需要工厂,你只需要把你的订单换成你所有的 复发者 方法,所以这个方法也会改变:

    class CriptoDecorator extends Decorator
    {
        public function recuperar($texto): string
        {
            return parent::recuperar($this->decrypt($texto));
        }
    }