4

I have this script Runing: Format var_export() PHP Script | WTOOLS

Main code of the link:

<?php
#Class Initialization
class Example {
    function foo_function() {
        return "Hello World! Object";
    }
}
$var_object = new Example;
#Store Class in and Array
$Test       = array('level1' => array('level2' => $var_object));
#function get my Type of value correctly:
function myGetType($var) {
    if (is_null($var) OR $var == 'null' OR $var == 'NULL') {
        return "(Type of NULL)";
    }

    if (is_array($var)) {
        return "(array)";
    }

    if (in_array($var, array("true", "false"), true)) {
        return "boolean";
    }

    if ((int) $var == $var && is_numeric($var)) {
        return "integer" . '(' . strlen($var) . ')';
    }

    if ((float) $var == $var && is_numeric($var)) {
        return "float" . '(' . strlen($var) . ')';
    }

    if (is_object($var)) {
        return "object";
    }

    if (strpos($var, 'resource') !== false AND strpos($var, 'of type ') !== false) {
        return "resource";
    }

    if (is_string($var)) {
        return "string" . '(' . strlen($var) . ')';
    }

    return "unknown";
}
#function to know if Exist a resource in the text:
function CheckResourceType($Var) {
    foreach ($Var as $k => $v) {
        if (is_array($v)) {
            $wrappedArray[$k] = CheckResourceType($v);
        } else {
            if (is_resource($v)) {
                ob_start();
                var_dump($v);
                $v = ob_get_clean();
                $v = preg_replace('~\R~', '', $v);
            }
            $wrappedArray[$k] = $v;
        }
    }
    return $wrappedArray;
}

#Main function to Format:
function VarExportFormat($Var) {
    $textvar = '';
    if (!is_array($Var)) {
        $textvar       = var_export($Var, true);
        $textvar       = preg_replace('~^ +~m', '$0$0', $textvar);
        $typeval       = myGetType($Var);
        $textvarArr[0] = $typeval . ' ' . var_export($Var, true);
    } else {
        //Check Point A Start
        $Var     = CheckResourceType($Var);
        $textvar = var_export($Var, true);
        $textvar = preg_replace('~^ +~m', '$0$0', $textvar);
        $textvar = preg_split("~\R~", $textvar);
        $textvar = preg_replace_callback(
            "~ => \K\V+(?=,)~",
            function ($m) {
                return myGetType(str_replace("'", "", $m[0])) . ": {$m[0]}";
            }, $textvar
        );
        $textvarArr = preg_replace(["/\s*array\s\($/", "/\)(,)?$/", "/\s=>\s$/"], [NULL, ']$1', ' => array ['], $textvar);
        //Check Point A END
    }
    if (!isset($textvarArr[1])) {
        $textvar = PHP_EOL . $textvarArr[0];
    } else {
        $textvar = join(PHP_EOL, array_filter(["array ["] + $textvarArr));
    }
    if (substr($textvar, -1) == '[') {
        $textvar = str_replace("[", "[]", $textvar);
    }
    //Check Point B Start

    $textvar = preg_replace('/(.*\(\K\V+\s+\)],)/', 'object)[]' . PHP_EOL . '],', $textvar);

    //Check Point B END
    $textvar = highlight_string("<?php \n#Output of Variable:\n" . $textvar . ";\n?>", true);
    return $textvar;
}

#Call to Format function.
echo VarExportFormat($Test);

and I search Regular Expression to filter the format of a var_export() and other given from user of Stackoverflow.

The problem is that, I am not an expert in regular expressions and I minimally understand some, but the ones I am using are somewhat complex and that I have found in other scripts.

The following are regular expressions used to filter and format every string line of array:

Section A

    //Check Point A Start
    $Var     = CheckResourceType($Var);
    $textvar = var_export($Var, true);
    $textvar = preg_replace('~^ +~m', '$0$0', $textvar);
    $textvar = preg_split("~\R~", $textvar);
    $textvar = preg_replace_callback(
        "~ => \K\V+(?=,)~",
        function ($m) {
            return myGetType(str_replace("'", "", $m[0])) . ": {$m[0]}";
        }, $textvar
    );
    $textvarArr = preg_replace(["/\s*array\s\($/", "/\)(,)?$/", "/\s=>\s$/"], [NULL, ']$1', ' => array ['], $textvar);
    //Check Point A END

Section B

$textvar = preg_replace('/(.*\(\K\V+\s+\)],)/', 'object)[]' . PHP_EOL . '],', $textvar);

One of these regular expressions is responsible for adding 4 spaces or tabs, but only for the strings that start with single quotes.

I found some inconsistencies, in case the value is an object or classes or functions, the output look this:

    <?php 
    #Output of Variable:
    array [
        'level1' => array [
            'level2' => array [
            Example::__set_state(object)[]
    ],
        ],
    ];
    ?>

which should be like this:

    <?php
    #Output of Variable:
    array [
        'level1' => array [
            'level2' => array [
                Example::__set_state(object)[]
            ],
        ],
    ];
    ?>

I guess there must be something wrong with regular expressions, which is that I can't determine it, i need add more space for Example::__set_state(object)[] and add the spaces needed to the next line.

  • 2
    Instead of trying to explain what you are trying to achieve with code which does not work, try explaining it in words and provide example inputs and the expected outputs. – symcbean Oct 21 '19 at 22:08
  • @symcbean For that, the example link, with an example working correctly, php code not run in stackoverflow, and the other example you view is the espectaed output, on link the output is wrong –  Oct 22 '19 at 00:28
  • 1
    To provide more context: https://codereview.stackexchange.com/q/230185/141885 – mickmackusa Oct 22 '19 at 23:31
  • @mickmackusa i am working around this: https://regex101.com/r/pk5ICt/3 –  Oct 22 '19 at 23:35
  • `\n` doesn't need to be inside of square braces. `\n` will not pick up `\r` if you are going for a system agnostic approach. I recommend `\v` or `\R`. – mickmackusa Oct 22 '19 at 23:43
  • 1
    after a six hour: `$textvar = preg_replace('/(\K\v+\s+)(.+\()(\v+\s+\)],)/', '$1 $2object))[],$1],', $textvar);` this solve the problem but i dont know if is the best way... –  Oct 22 '19 at 23:50
  • At this point, I reckon the focus of the bounty should be on reducing the battery of `preg_` calls into something more elegant. Also, have you considered the impact of string values containing newline characters? – mickmackusa Oct 23 '19 at 06:46
  • @mickmackusa No, I really have not considered improvements in efficiency or elegance, for me it was a challenge just to get the result. and I know it's not the best, but I don't have the knowledge to improve the code further. I would like to take it to the code review, but I don't know how to avoid the double post. –  Oct 23 '19 at 14:11
  • and yes the bounty will work around to improve the code. –  Oct 23 '19 at 14:12
  • https://wtools.io/php-sandbox/boyq –  Oct 23 '19 at 14:23
  • Cross-posting is not a sin. Perhaps wait until after this bounty period to see how much support/improvement transpires here. (Sorry, I've been too busy to contribute on this page because I'm very busy this week) – mickmackusa Oct 23 '19 at 20:45
  • @mickmackusa I don't think he gets much support in this post ... I think the bounty will get lost ... –  Oct 23 '19 at 21:20
  • Please be aware that `preg_split()` creates an array from a string -- therefore, the data should be declared as `$textvarArr` going forward. – mickmackusa Oct 23 '19 at 22:31
  • @mickmackusa jajajaja ok I am thinking of uploading it to github and publishing it with a composer as a library, something that is not done ... but it is time to investigate to learn. –  Oct 24 '19 at 01:57
  • I would have liked to help you, so that your bounty didn't go to waste, but there are just too many fringe cases to deal with. Regex is going to be vulnerable to breakage depending on some occurrences. Here is a sample input for you to continue testing against. https://3v4l.org/GGtXj Don't you want all arrays to be square-braced? @walternuñez – mickmackusa Oct 27 '19 at 11:21
  • @mickmackusa Fatal error: Uncaught Error: Class 'mysqli' not found in /in/php_5db6fe2b99bd15.20432083:37 Stack trace: thrown in /in/php_5db6fe2b99bd15.20432083 on line 37 –  Oct 28 '19 at 14:42
  • @mickmackusa i update the script in check resource to work with your example: https://wtools.io/php-sandbox/bqdA –  Oct 28 '19 at 16:14
  • See how the key of the first subarray element is mangled by the regex? https://wtools.io/php-sandbox/bqiX Also, I still see some `array(` occurrences -- is that what you want? – mickmackusa Oct 28 '19 at 21:30
  • @mickmackusa sure, only that not meet the regex `__set_state(array(` i would need update to capture it and make the changes. –  Oct 29 '19 at 02:03

0 Answers0