PHP装饰器模式解密后如何使用解压?
PHP How to use decompression after decryption using Decorator Pattern?
出于学习目的,我尝试创建一个 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));
}
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) 和 recuperar(retrieve)?
提前致谢
您需要按照您设置的相同顺序放松。如果先压缩再加密,则需要先解密再解压
此特定代码的快速修复是更改 CompressaoDecorator
中的 recuperar
方法
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));
}
}
这应该允许您先调用加密或压缩,只要您使用相同的链,反向也应该有效。
出于学习目的,我尝试创建一个 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));
}
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) 和 recuperar(retrieve)?
提前致谢
您需要按照您设置的相同顺序放松。如果先压缩再加密,则需要先解密再解压
此特定代码的快速修复是更改 CompressaoDecorator
recuperar
方法
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));
}
}
这应该允许您先调用加密或压缩,只要您使用相同的链,反向也应该有效。