3v4l.org

run code in 300+ PHP versions simultaneously
<?php // @source https://refactoring.guru/ru/design-patterns/decorator/php/example#example-1 namespace RefactoringGuru\Decorator\RealWorld; /** * Интерфейс Компонента объявляет метод фильтрации, который должен быть * реализован всеми конкретными компонентами и декораторами. */ 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); } } /** * Этот Конкретный Декоратор удаляет все теги HTML из данного текста. */ class PlainTextFilter extends TextFormat { public function formatText(string $text): string { $text = parent::formatText($text); return strip_tags($text); } } /** * Этот Конкретный Декоратор удаляет только опасные теги и атрибуты HTML, * которые могут привести к XSS-уязвимости. */ 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; } } /** * Этот Конкретный Декоратор предоставляет элементарное преобразование Markdown * → HTML. */ class MarkdownFormat extends TextFormat { public function formatText(string $text): string { $text = parent::formatText($text); // Форматирование элементов блока. $chunks = preg_split('|\n\n|', $text); foreach ($chunks as &$chunk) { // Форматирование заголовков. if (preg_match('|^#+|', $chunk)) { $chunk = preg_replace_callback('|^(#+)(.*?)$|', function ($matches) { $h = strlen($matches[1]); return "<h$h>" . trim($matches[2]) . "</h$h>"; }, $chunk); } // Форматирование параграфов. else { $chunk = "<p>$chunk</p>"; } } $text = implode("\n\n", $chunks); // Форматирование встроенных элементов. $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); // .. } /** * Модули форматирования пользовательского ввода очень удобны при работе с * контентом, создаваемым пользователями. Отображение такого контента «как есть» * может быть очень опасным, особенно когда его могут создавать анонимные * пользователи (например, комментарии). Ваш сайт не только рискует получить * массу спам-ссылок, но также может быть подвергнут XSS-атакам. */ $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 "Website renders comments without filtering (unsafe):\n"; displayCommentAsAWebsite($naiveInput, $dangerousComment); echo "\n\n\n"; ///////////////////////////////////////////////////////////////////////////////////////// /** * Отфильтрованное отображение комментариев (безопасное). */ $filteredInput = new PlainTextFilter($naiveInput); echo "Website renders comments after stripping all tags (safe):\n"; 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 "Website renders a forum post without filtering and formatting (unsafe, ugly):\n"; displayCommentAsAWebsite($naiveInput, $dangerousForumPost); echo "\n\n\n"; /** * Форматтер Markdown + фильтрация опасных тегов (безопасно, красиво). */ $text = new TextInput(); $markdown = new MarkdownFormat($text); $filteredInput = new DangerousHTMLTagsFilter($markdown); //$filteredInput = new PlainTextFilter($filteredInput); echo "Website renders a forum post after translating markdown markup" . " and filtering some dangerous HTML tags and attributes (safe, pretty):\n"; displayCommentAsAWebsite($filteredInput, $dangerousForumPost); echo "\n\n\n"; /////////////////////////////////////////////////////////////////////////////////////////

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.3.60.0080.00818.39
8.3.50.0100.00618.45
8.3.40.0040.01820.38
8.3.30.0070.01019.08
8.3.20.0080.00024.18
8.3.10.0050.00324.66
8.3.00.0030.00526.16
8.2.180.0100.01025.92
8.2.170.0130.01019.33
8.2.160.0090.00622.96
8.2.150.0030.00525.66
8.2.140.0040.00424.66
8.2.130.0080.00026.16
8.2.120.0080.00019.61
8.2.110.0000.01021.12
8.2.100.0110.00018.09
8.2.90.0000.00818.47
8.2.80.0040.00418.28
8.2.70.0030.00618.00
8.2.60.0000.00818.00
8.2.50.0040.00418.07
8.2.40.0060.00318.34
8.2.30.0080.00018.21
8.2.20.0000.00918.29
8.2.10.0000.00821.23
8.2.00.0040.00419.34
8.1.280.0150.00025.92
8.1.270.0000.00823.99
8.1.260.0060.00326.35
8.1.250.0030.00528.09
8.1.240.0030.00623.80
8.1.230.0090.00322.63
8.1.220.0000.00817.78
8.1.210.0080.00018.85
8.1.200.0060.00317.73
8.1.190.0040.00417.48
8.1.180.0080.00018.10
8.1.170.0040.00419.02
8.1.160.0040.00418.92
8.1.150.0080.00018.95
8.1.140.0000.00719.18
8.1.130.0040.00420.25
8.1.120.0040.00817.55
8.1.110.0000.00917.58
8.1.100.0040.00717.72
8.1.90.0030.00517.68
8.1.80.0000.00817.73
8.1.70.0070.00017.67
8.1.60.0080.00017.81
8.1.50.0060.00317.77
8.1.40.0030.00517.77
8.1.30.0040.00417.90
8.1.20.0030.00617.85
8.1.10.0000.00817.82
8.1.00.0000.00817.63
8.0.300.0040.00420.13
8.0.290.0000.00817.00
8.0.280.0000.01018.51
8.0.270.0000.00718.29
8.0.260.0030.00318.61
8.0.250.0040.00417.27
8.0.240.0040.00417.21
8.0.230.0030.00517.20
8.0.220.0000.00817.16
8.0.210.0030.00317.05
8.0.200.0040.00417.28
8.0.190.0000.00817.27
8.0.180.0080.00017.10
8.0.170.0000.01117.21
8.0.160.0000.01117.20
8.0.150.0060.00317.08
8.0.140.0100.00017.04
8.0.130.0030.00313.52
8.0.120.0040.00416.98
8.0.110.0050.00217.08
8.0.100.0080.00017.21
8.0.90.0040.00417.03
8.0.80.0090.01517.21
8.0.70.0200.01217.20
8.0.60.0260.00617.11
8.0.50.0260.00617.15
8.0.30.0220.01417.07
8.0.20.0170.01717.26
8.0.10.0250.00817.35
8.0.00.0080.01217.27
7.4.330.0050.00015.55
7.4.320.0070.00016.85
7.4.300.0000.00716.97
7.4.290.0000.00816.81
7.4.280.0040.00416.89
7.4.270.0070.00016.94
7.4.260.0030.00516.85
7.4.250.0090.00016.80
7.4.240.0030.00516.84
7.4.230.0050.00217.01
7.4.220.0000.00716.77
7.4.210.0210.00716.79
7.4.200.0210.00616.88
7.4.190.0140.01416.90
7.4.180.0210.00616.91
7.4.160.0190.01216.97
7.4.150.0210.00816.85
7.4.140.0250.00616.79
7.4.130.0220.00616.98
7.4.120.0190.01116.89
7.4.110.0230.00716.92
7.4.100.0170.01316.95
7.4.90.0210.01216.76
7.4.80.0180.01116.79
7.4.70.0170.01416.89
7.4.60.0170.01416.81
7.4.50.0160.01616.62
7.4.40.0250.00916.61
7.4.30.0250.00716.70
7.4.20.0260.00416.73
7.4.10.0200.00916.84
7.4.00.0190.01916.71
7.3.330.0030.00316.51
7.3.320.0060.00013.57
7.3.310.0070.00016.55
7.3.300.0000.00816.64
7.3.290.0200.00916.66
7.3.280.0210.01316.56
7.3.270.0180.00916.67
7.3.260.0120.01616.71
7.3.250.0190.01316.58
7.3.240.0120.01516.66
7.3.230.0180.01716.63
7.3.220.0180.01116.59
7.3.210.0220.01216.60
7.3.200.0100.02116.54
7.3.190.0200.00716.60
7.3.180.0190.01016.60
7.3.170.0210.01216.56
7.3.160.0140.01816.57
7.3.150.0230.00716.55
7.3.140.0190.01216.52
7.3.130.0150.00916.61
7.3.120.0190.01116.57
7.3.110.0050.01716.54
7.3.100.0110.00716.48
7.3.90.0090.01516.89
7.3.80.0220.01116.65
7.3.70.0220.00916.71
7.3.60.0250.00616.71
7.3.50.0140.01416.72
7.3.40.0170.01316.71
7.3.30.0170.01716.70
7.3.20.0150.01916.63
7.3.10.0230.01116.62
7.3.00.0290.01016.57

preferences:
54.31 ms | 401 KiB | 5 Q