Класс, показывающий формат, аналогичный var_dump

Некоторые методы этой библиотеки требуют некоторых улучшений (см. Это описание):

  1. в constructor Я пытаюсь создать возможность того, что пользователь изменит цвета вывода. Я думаю, что он может улучшиться, но я не знаю, есть ли в этом отношении какие-либо стандарты или передовые методы, или есть ли способ оптимизировать этот класс.

  2. Метод getIndent использует анализ переменной для определения отступа вывода с помощью функции array_walk_recursive. У меня мало знаний об обработке массивов, поэтому я использовал этот метод, потому что он мне показался простым. Я не знаю, лучше ли это выполнить цель getIndent метод.

  3. В AnalVariable метод использует абстракцию pretty функция. Это был единственный найденный мною пример, в котором он позволил мне получить результат, аналогичный результату var_dump или же var_export. Некоторые другие разработчики предложили мне использовать отражение, но я не нашел примера, связанного с использованием / назначением, которое я хочу дать.

    У меня также есть кластер анализа для интервалов с использованием троичного анализа. Я бы хотел, чтобы кто-нибудь с большим опытом проверял, искал возможные ошибки или улучшения. С минимальными тестами, которые я провел, я не получил никаких ошибок.

  4. В EvalVariable метод мой любимый; Этот метод отвечает за анализ данных переданной переменной, чтобы определить тип данных и вернуть их, принимая во внимание, что возвращенный код / ​​значение можно использовать. Но мне не удалось воссоздать объекты или ресурсы, чтобы сделать их пригодными для использования, давайте посмотрим на пример:

    Пример массива у нас есть узел следующим образом:

    'resource' => curl_init()
    

    а вот в выходную трубку поставить:

    'resource' => resource
    

    Это происходит потому, что тип данных не говорит, что он исходит из curl_init(); то, что я надеялся сделать, чего мне не удалось, — это показать результат:

    'resource' => curl_init()
    
  5. Еще одна вещь, которая, как мне кажется, может негативно повлиять на производительность библиотеки, — это анализ, выполненный EvalVariable метод, поскольку это набор if и проверок. Я думаю, что это можно улучшить, но я не знаю, с чего начать и что мне следует изменить.

  6. Мне также удалось немного улучшить результат, добавив или обогатив его комментарием, в котором я описываю более глубокий анализ.

    // object (stdClass) # 2 (2).
    // object (FooBar) # 3 (0).
    // resource (6) of type (curl).
    
  7. Метод HighlightCode отвечает за исправление вывода на экран. В этом случае я использую highlight_string в сочетании с другими конкатенациями, чтобы преобразовать его в HTML. Но я не знаю, как мне воссоздать это для интерфейса командной строки, который я хотел бы реализовать.

  8. Еще один важный момент для меня — оценить, соответствует ли сценарий / библиотека в целом действующим стандартам PSR. Я использую среду разработки phpStorm, но она не обнаруживает ошибки такого типа.

Моя цель — улучшить этот сценарий. Я перечислил основные моменты и жду комментариев по ним. Хотя это не основная цель, я также готов выслушать мнения, основанные на задокументированных и приведенных в качестве примеров улучшениях.

Описание класса / библиотеки:

[BOH] Базовый обработчик вывода для PHP

Акроним: [BOH].
Имя: Базовый обработчик вывода.
Зависимости: Автономный / PHP v7.4.

Что значит [BOH] делать?

[BOH] это очень простой PHP [output handler] реализация, которая показывает информацию в удобном для чтения виде вместо использования параметров PHP по умолчанию:

  • var_dump() — Отображает информацию о переменной.
  • print_r() — Печатать удобочитаемую информацию о переменной.
  • debug_zval_dump() — Выводит строку, представляющую внутреннее значение zend.
  • var_export() — Распечатать или вернуть строковое представление анализируемой переменной.

Это означает, что все переданные данные предоставляются разработчику в соответствии с выбранными параметрами. Это также означает, что отображаемые данные можно напрямую повторно использовать в качестве кода. Для каждого значения также создаются комментарии, которые кратко объясняют тип данных.

Зачем использовать [BOH]?

Разработчикам нужна возможность решать, как их код ведет себя при проверке данных. Собственные методы PHP предоставляют ряд информации, которая не может быть повторно использована разработчиком или может даже потребовать дополнительной работы для получения правильного вывода для проверки данных.

Эта библиотека обрабатывает вывод данных, который оказался чрезвычайно эффективным. [BOH] это автономная реализация, которая может использоваться для любого проекта и не требует сторонней библиотеки или программного обеспечения.

Помогите улучшить [BOH]?

Если вы хотите сотрудничать с разработкой библиотеки; Вы можете выразить свои идеи или сообщить о любой ситуации, связанной с этим, в: https://github.com/arcanisgk/BOH-Basic-Ouput-Handler/issues

Мой код

<?php

namespace IcarosNetBOHBasicOutputHandler;


class OutputHandler
{
    public string $background = '';
    public string $themeused;

    public function __construct($theme="default")
    {
        $this->themeused = $theme;
        $this->ThemeSelector($theme);
    }

    private function ThemeSelector(string $theme)
    {
        switch ($theme) {
            case 'x-space':
                $this->background = 'black';
                ini_set("highlight.comment", "#2B8029");
                ini_set("highlight.default", "#636363");
                ini_set("highlight.html", "#808080");
                ini_set("highlight.keyword", "#485EBB; font-weight: bold");
                ini_set("highlight.string", "#DD4F4F");
                break;
            case 'mauro-dark':
                $this->background = '#121212';
                ini_set("highlight.comment", "#BB86FC");
                ini_set("highlight.default", "#FAFAFA");
                ini_set("highlight.html", "#03DAC5");
                ini_set("highlight.keyword", "#FF7597; font-weight: bold");
                ini_set("highlight.string", "#CF6679");
                break;
            case 'natural-flow':
                $this->background = '#042903';
                ini_set("highlight.comment", "#919B98");
                ini_set("highlight.default", "#1E9C6B");
                ini_set("highlight.html", "#03DAC5");
                ini_set("highlight.keyword", "#069C04; font-weight: bold");
                ini_set("highlight.string", "#8B9C33");
                break;
            case 'monokai':
                $this->background = '#272822';
                ini_set("highlight.comment", "#70716A");
                ini_set("highlight.default", "#FAFAFA");
                ini_set("highlight.html", "#03DAC5");
                ini_set("highlight.keyword", "#F92672; font-weight: bold");
                ini_set("highlight.string", "#A39249");
                break;
            default:
                $this->background = 'white';
                break;
        }
    }

    public function Output($varname, $retrive = false)
    {
        $indents = $this->GetIndent($varname);
        $string  = $this->GetString($varname, $indents);
        $string  = $this->HighlightCode($string);
        return ($retrive ? $string : $this->OutView($string));
    }

    /*
    public function AdvanceOutput($var)
    {
        echo 'hello world';
    }
    */

    private function GetIndent(string $varname): array
    {
        $data    = $GLOBALS[$varname];
        $indents = ['key' => 0, 'val' => 0];
        if (is_array($data) || is_object($data)) {
            array_walk_recursive($data, function (&$value) {
                $value = is_object($value) ? (array) $value : $value;
            });
            $deep = ($this->CalcDeepArray($data) + 1) * 4;
            array_walk_recursive($data, function ($value, $key) use (&$indents) {
                $indents['key'] = ($indents['key'] >= mb_strlen($key)) ? $indents['key'] : mb_strlen($key);
                if (!is_array($value) && !is_object($value) && !is_resource($value)) {
                    $indents['val'] = ($indents['val'] >= mb_strlen($value)) ? $indents['val'] : mb_strlen($value);
                }
            }, $indents);
            $indents['key'] += $deep;
            $indents['val'] += $deep / 2;
        } else {
            $indents = ['key' => mb_strlen($varname), 'val' => mb_strlen($data)];
        }
        return $indents;
    }

    private function CalcDeepArray(array $array): int
    {
        $max_depth = 0;
        foreach ($array as $key => $value) {
            if (is_array($value)) {
                $depth = $this->CalcDeepArray($value) + 1;
                if ($depth > $max_depth) {
                    $max_depth = $depth;
                }
            }
        }
        return $max_depth;
    }

    private function GetString(string $varname, array $indents): string
    {
        $var = $GLOBALS[$varname];
        return $this->AnalVariable($varname, $var, $indents);
    }

    private function AnalVariable(string $varname, $var, array $indents): string
    {
        $pretty      = function ($indents, $varlentitle, $v = '', $c = " ", $in = 0, $k = null) use (&$pretty) {
            $r="";
            if (in_array(gettype($v), array('object', 'array'))) {
                $lenname = mb_strlen("'$k'");
                $lenkeys = $indents['key'] - $in - $lenname;
                if ($lenkeys < 0) {
                    $lenkeys = 0;
                }
                $eval   = $this->EvalVariable($v);
                $v      = (array) $v;
                $lenkey = $indents['val'] - mb_strlen($eval['val']) + 1;
                if (empty($v)) {
                    $r .= ($in != 0 ? str_repeat($c, $in) : '') . (is_null($k) ? '' : "'$k'"
                            . str_repeat($c, $lenkeys) . "=> " . $eval['val'] . "[],"
                            . str_repeat(" ", $lenkey - 6) . "// "
                            . $eval['desc']) . (empty($v) ? '' : PHP_EOL);
                } else {
                    $r .= ($in != 0 ? str_repeat($c, $in) : '') . (is_null($k) ? '' : "'$k'"
                            . str_repeat($c, $lenkeys) . "=> " . $eval['val'] . "["
                            . str_repeat(" ", $lenkey - 4) . "// "
                            . $eval['desc']) . (empty($v) ? '' : PHP_EOL);
                    foreach ($v as $sk => $vl) {
                        $r .= $pretty($indents, $varlentitle, $vl, $c, $in + 4, $sk) . PHP_EOL;
                    }
                    $r .= (empty($v) ? '],' : ($in != 0 ? str_repeat($c, $in / 2) : '')
                        . (is_null($v) ? '' : str_repeat($c, $in / 2) . "],"));
                }
            } else {
                $lenkey = $indents['key'] - mb_strlen("'$k'") - $in;
                if ($lenkey < 0) {
                    $lenkey = 0;
                }
                $eval   = $this->EvalVariable($v);
                $lenval = $indents['val'] - (mb_strlen("'" . $eval['val'] . "'"));
                if ($lenval < 0) {
                    $lenval = 0;
                }
                $r .= ($in != -1 ? str_repeat($c, $in) : '') . (is_null($k) ? '' : "'$k'"
                        . str_repeat($c, $lenkey) . '=> ') . $eval['val']
                    . str_repeat(" ", $lenval) . '// ' . $eval['desc'];
            }
            return $r;
        };
        $varlentitle = mb_strlen('$' . $varname);
        if (in_array(gettype($var), array('object', 'array'))) {
            return '$' . $varname . str_repeat(" ", ($indents['key'] - $varlentitle)) . '=['
                . str_repeat(" ", $indents['val'] - 1) . '// main array node'
                . rtrim($pretty($indents, $varlentitle, $var), ',') . ';';
        } else {
            $eval = $this->EvalVariable($var);
            return '$' . $varname . str_repeat(" ", $indents['key']) . '=' . $eval['val'] . ';'
                . str_repeat(" ", $indents['val'] - 1) . '// ' . $eval['desc'];
        }

    }

    public function EvalVariable($var): array
    {
        if (null === $var || 'null' === $var || 'NULL' === $var) {
            if (is_string($var)) {
                return ['val' => "'null'", 'desc' => 'null value string.'];
            } else {
                return ['val' => 'null', 'desc' => 'null value.'];
            }
        }

        if (is_array($var)) {
            return ['val' => "", 'desc' => 'array node.'];
        }

        if (in_array($var, ["true", "false", true, false], true)) {
            if (is_string($var)) {
                return ['val' => "'" . $var . "'", 'desc' => 'string value boolean ' . $var . '.'];
            } else {
                return ['val' => ($var ? 'true' : 'false'), 'desc' => 'boolean value ' . ($var ? 'true' : 'false') . '.'];
            }
        }

        ob_start();
        var_dump($var);
        $string = ob_get_clean();
        if (is_object($var)) {
            $string = explode('{', $string);
            return ['val' => '(object) ', 'desc' => rtrim($string[0]) . '.'];
        }
        unset($string);

        if ((int) $var == $var && is_numeric($var)) {
            if (is_string($var)) {
                return ['val' => "'" . $var . "'", 'desc' => '(' . mb_strlen($var) . ') integer value string.'];
            } else {
                return ['val' => $var, 'desc' => '(' . mb_strlen($var) . ') integer value.'];
            }
        }

        if ((float) $var == $var && is_numeric($var)) {
            if (is_string($var)) {
                return ['val' => "'" . $var . "'", 'desc' => '(' . mb_strlen($var) . ') float value string.'];
            } else {
                return ['val' => $var, 'desc' => '(' . mb_strlen($var) . ') float value.'];
            }
        }

        ob_start();
        var_dump($var);
        $string = ob_get_clean();
        if (mb_strpos($string, 'resource') !== false) {
            return ['val' => 'resource', 'desc' => rtrim($string) . '.'];
        } elseif (mb_strpos($string, 'of type ') !== false) {
            return ['val' => 'resource', 'desc' => rtrim($string) . '.'];
        }
        unset($string);

        if (mb_strpos($var, ' ') !== false && mb_strpos($var, ':') !== false && mb_strpos($var, '-') !== false) {
            $datetime = explode(" ", $var);
            $validate = 0;
            foreach ($datetime as $value) {
                if ($this->ValidateDate($value)) {
                    $validate++;
                }
            }
            if ($validate >= 2) {
                return ['val' => "'" . $var . "'", 'desc' => '(' . mb_strlen($var) . ') string value datetime.'];
            }
        }

        if ($this->ValidateDate($var) && mb_strpos($var, ':') !== false) {
            return ['val' => "'" . $var . "'", 'desc' => '(' . mb_strlen($var) . ') string value time.'];
        }

        if ($this->ValidateDate($var) && mb_strlen($var) >= 8 && mb_strpos($var, '-') !== false) {
            return ['val' => "'" . $var . "'", 'desc' => '(' . mb_strlen($var) . ') string value date.'];
        }

        if ($this->ValidateDate($var) && mb_strlen($var) >= 8 && mb_strpos($var, '-') !== false) {
            return ['val' => "'" . $var . "'", 'desc' => '(' . mb_strlen($var) . ') string value date.'];
        }

        if (is_string($var)) {
            $arr           = $this->StrSplitUnicode($var);
            $currencylist  = [
                '¤', '$', '¢', '£', '¥', '₣', '₤', '₧', '€', '₹', '₩', '₴',
                '₯', '₮', '₰', '₲', '₱', '₳', '₵', '₭', '₪', '₫', '₠', '₡', '₢', '₥', '₦',
                '₨', '₶', '₷', '₸', '₺', '₻', '₼', '₽', '₾', '₿'
            ];
            $currencycheck = [];
            foreach ($arr as $char) {
                if (in_array($char, $currencylist, true)) {
                    $currencycheck[] = $char;
                }
            }
            if (!empty($currencycheck)) {
                return [
                    'val' => "'" . $var . "'", 'desc' => 'string/amount value related to currency ('
                        . implode(',', $currencycheck) . ').'
                ];
            }
        }

        if (is_string($var)) {
            return ['val' => "'" . $var . "'", 'desc' => 'string value of ' . mb_strlen($var) . ' character.'];
        }

        return ['val' => 'unknow', 'desc' => 'unknow'];
    }

    private function ValidateDate(string $date): bool
    {
        return (strtotime($date) !== false);
    }

    private function StrSplitUnicode(string $str, $length = 1): array
    {
        $tmp = preg_split('~~u', $str, -1, PREG_SPLIT_NO_EMPTY);
        if ($length > 1) {
            $chunks = array_chunk($tmp, $length);
            foreach ($chunks as $i => $chunk) {
                $chunks[$i] = join('', (array) $chunk);
            }
            $tmp = $chunks;
        }
        return $tmp;
    }

    private function HighlightCode(string $string): string
    {
        $bg    = $this->background;
        $class = mt_rand();
        return '<style>.outputhandler-' . $class
            . '{background-color: ' . $bg . '; padding: 8px}</style><div class="outputhandler-' . $class . '">'
            . highlight_string("<?php n#output of Variable:" . str_repeat(' ', 10)
                . '*****| Theme Used: ' . $this->themeused . " |*****n" . $string . "n?>", true) . '</div>';
    }

    private function OutView(string $string)
    {
        echo $string;
    }
}

Пример использования

<?php

use IcarosNetBOHBasicOutputHandler as Output;

require __DIR__ . '..vendorautoload.php';

/**
 * FooBar is an example class.
 */
class FooBar
{
    function foo_function()
    {
        return "Hello World!";
    }
}

$var_class = new FooBar;

$example_single = true;

$example_single="2021-Jan-17 6:31:00 AM";

$example_array = [//1
    'null'         => null,
    'null_text'    => 'null',
    'integer'      => 10,
    'integer_text' => '10',
    'float'        => 20.35,
    'float_text'   => '20.35',
    'string'       => 'Hello World',
    'date_1'       => '2021-01-17',
    'date_2'       => '2021-Jan-17',
    'hour_1'       => '6:31:00 AM',
    'hour_2'       => '17:31:00',
    'datetime_1'   => '2021-01-17 17:31:00',
    'datetime_2'   => '2021-Jan-17 6:31:00 AM',
    'datetime_3'   => '2021-01-17 6:31:00 AM',
    'datetime_4'   => '2021-Jan-17 17:31:00',
    'currency_1'   => '1.45$',
    'currency_2'   => '£ 1.45 ₹',
    'array'        => [//2
        'boolean_true'       => true,
        'boolean_false'      => false,
        'boolean_true_text'  => 'true',
        'boolean_false_text' => 'false',
        'object'             => (object) [//3
            'key_index_most_highed_of_the_example' => 'Hello Wolrd,Hello Wolrd,Hello Wolrd,Hello Wolrd',
            'joder'                                => [//4
                'prueba' => 'prueba',
            ]
        ],
        'nested'             => [                                               // deep = 3 no cuenta ya existe
            'other_obj' => (object) [                               // deep = 4 no cuenta ya existe
                'apple',
                'banana',
                'coconut',
            ],
        ],
    ],
    'objects_list' => [
        'object_empty' => (object) [],
        'class'        => $var_class,
        'resource'     => curl_init(),
    ],
];

$output = new OutputOutputHandler();
$output->output('example_array');

Пример вывода:

Имейте в виду, что этот вывод был записан в браузере, хотя он имеет формат кода, это одна из функций класса. формат невозможно воспроизвести на сайтах SE, поэтому я добавляю изображения.

  • тема по умолчанию
    введите описание изображения здесь

  • монокай тема
    монокай тема

  • естественный поток
    введите описание изображения здесь

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *