🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 示例 装饰在 PHP 代码中可谓是标准配置,尤其是在与流式加载相关的代码中 ### 概念示例 <details> <summary>main.php</summary> ``` <?php // 部件 interface Component{ public function operation(): string; } // 具体部件 class ConcreteComponent implements Component{ public function operation(): string{ return "ConcreteComponent"; } } // 基础装饰 class Decorator implements Component{ /** * @var Component */ protected $component; public function __construct(Component $component){ $this->component = $component; } public function operation(): string{ return $this->component->operation(); } } // 具体装饰类 class ConcreteDecoratorA extends Decorator{ public function operation(): string{ return "ConcreteDecoratorA(".parent::operation().")"; } } //具体装饰类 class ConcreteDecoratorB extends Decorator{ public function operation(): string{ return "ConcreteDecoratorB(".parent::operation().")"; } } function clientCode(Component $component){ // ... echo "RESULT: ".$component->operation(); // ... } $simple = new ConcreteComponent(); clientCode($simple); echo "\n\n"; $decorator1 = new ConcreteDecoratorA($simple); $decorator2 = new ConcreteDecoratorB($decorator1); clientCode($decorator2); ``` </details> <br /> 输出 ``` RESULT: ConcreteComponent RESULT: ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent)) ``` ### 文本过滤 <details> <summary>main.php</summary> ``` <?php interface InputFormat { public function formatText(string $text): string; } class TextInput implements InputFormat { public function formatText(string $text): string { return $text; } } class TextFormat implements InputFormat { /** * @var InputFormat */ protected $inputFormat; public function __construct(InputFormat $inputFormat) { $this->inputFormat = $inputFormat; } public function formatText(string $text): string { return $this->inputFormat->formatText($text); } } class PlainTextFilter extends TextFormat { public function formatText(string $text): string { $text = parent::formatText($text); return strip_tags($text); } } class DangerousHTMLTagsFilter extends TextFormat { private $dangerousTagPatterns = [ "|<script.*?>([\s\S]*)?</script>|i", // ... ]; private $dangerousAttributes = [ "onclick", "onkeypress", // ... ]; public function formatText(string $text): string { $text = parent::formatText($text); foreach ($this->dangerousTagPatterns as $pattern) { $text = preg_replace($pattern, '', $text); } foreach ($this->dangerousAttributes as $attribute) { $text = preg_replace_callback('|<(.*?)>|', function ($matches) use ($attribute) { $result = preg_replace("|$attribute=|i", '', $matches[1]); return "<" . $result . ">"; }, $text); } return $text; } } class MarkdownFormat extends TextFormat { public function formatText(string $text): string { $text = parent::formatText($text); // Format block elements. $chunks = preg_split('|\n\n|', $text); foreach ($chunks as &$chunk) { // Format headers. if (preg_match('|^#+|', $chunk)) { $chunk = preg_replace_callback('|^(#+)(.*?)$|', function ($matches) { $h = strlen($matches[1]); return "<h$h>" . trim($matches[2]) . "</h$h>"; }, $chunk); } // Format paragraphs. else { $chunk = "<p>$chunk</p>"; } } $text = implode("\n\n", $chunks); // Format inline elements. $text = preg_replace("|__(.*?)__|", '<strong>$1</strong>', $text); $text = preg_replace("|\*\*(.*?)\*\*|", '<strong>$1</strong>', $text); $text = preg_replace("|_(.*?)_|", '<em>$1</em>', $text); $text = preg_replace("|\*(.*?)\*|", '<em>$1</em>', $text); return $text; } } function displayCommentAsAWebsite(InputFormat $format, string $text) { // .. echo $format->formatText($text); // .. } $dangerousComment = <<<HERE Hello! Nice blog post! Please visit my <a href='http://www.iwillhackyou.com'>homepage</a>. <script src="http://www.iwillhackyou.com/script.js"> performXSSAttack(); </script> HERE; // 不过滤 $naiveInput = new TextInput(); echo "======TextInput======".PHP_EOL; displayCommentAsAWebsite($naiveInput, $dangerousComment); echo "\n\n\n"; // 过滤标签 $filteredInput = new PlainTextFilter($naiveInput); echo "======PlainTextFilter======".PHP_EOL; displayCommentAsAWebsite($filteredInput, $dangerousComment); echo "\n\n\n"; $dangerousForumPost = <<<HERE # Welcome This is my first post on this **gorgeous** forum. <script src="http://www.iwillhackyou.com/script.js"> performXSSAttack(); </script> HERE; $naiveInput = new TextInput(); echo "======TextInput======".PHP_EOL; displayCommentAsAWebsite($naiveInput, $dangerousForumPost); echo "\n\n\n"; // 过滤标签,过滤Markdown,过滤危险标签 $text = new TextInput(); $markdown = new MarkdownFormat($text); $filteredInput = new DangerousHTMLTagsFilter($markdown); echo "======DangerousHTMLTagsFilter======".PHP_EOL; displayCommentAsAWebsite($filteredInput, $dangerousForumPost); echo "\n\n\n"; ``` </details> <br /> 输出 ``` ======TextInput====== Hello! Nice blog post! Please visit my <a href='http://www.iwillhackyou.com'>homepage</a>. <script src="http://www.iwillhackyou.com/script.js"> performXSSAttack(); </script> ======PlainTextFilter====== Hello! Nice blog post! Please visit my homepage. performXSSAttack(); ======TextInput====== # Welcome This is my first post on this **gorgeous** forum. <script src="http://www.iwillhackyou.com/script.js"> performXSSAttack(); </script> ======DangerousHTMLTagsFilter====== <h1>Welcome</h1> <p>This is my first post on this <strong>gorgeous</strong> forum.</p> <p></p> ```