3
\$\begingroup\$

I have a class that exposes var_dump data in order to get better human readable layout.

I have achieved this with a lot of preg_replace and a series of regular expressions that run one after another. They parse the result of the var_dump to have a more readable and highlighted output.

I would like them to review and verify it in order to optimize it and reduce the code if possible.

Check the Update 1

My code can also be found on GitHub.

<?php //this PHP code is old. In the repository is the updated code, see update # 1.
class ClassVarsManager
{
 private function GetType($var)
 {
 if (in_array($var, ['null', 'NULL', null], true)) {
 return '(Type of NULL)';
 }
 if (in_array($var, ['TRUE', 'FALSE', 'true', 'false', true, false], true)) {
 return 'boolean';
 }
 if (is_array($var)) {
 return 'array';
 }
 if (is_object($var)) {
 return 'object';
 }
 if ((int) $var == $var && is_numeric($var)) {
 return 'integer';
 }
 if ((float) $var == $var && is_numeric($var)) {
 return 'float';
 }
 if (strpos($var, 'resource') !== false) {
 foreach ($this->GetResourceTypeArray() as $value) {
 if (strpos($var, $value) !== false) {
 return 'resource (' . $value . ')';
 }
 }
 }
 if (strpos($var, '/') !== false) {
 if (in_array($var, timezone_identifiers_list())) {
 return 'time-zone';
 }
 }
 if (strpos($var, ' ') !== false and strpos($var, ':') !== false) {
 $testdate = explode(' ', $var);
 if ($this->ValidateDate($testdate[0], false) && $this->ValidateDate($testdate[1], false && strpos($testdate[1], ':') !== false)) {
 return 'datetime';
 }
 }
 if ($this->ValidateDate($var, false) and strpos($var, ':') !== false) {
 return 'time';
 }
 if ($this->ValidateDate($var, false) and strlen($var) >= 8) {
 return 'date';
 }
 if (is_string($var)) {
 return 'string(' . strlen($var) . ')';
 }
 }
 private function VarExportFormat($var, $highlight = false)
 {
 ob_start();
 var_dump($var);
 $var_dump = ob_get_clean();
 $var_dump = preg_replace(["/\[\"/", "/\"\]/", "/\]/", "/\[/", "/\)\s*\{(\s*\w*)/", "/(\s*\w*)\}(\s*\w*)/", "/=>\s*(\w)/", "/\[\s*\](,)/", "~^ +~m"], ["'", "'", '', '', ') [1ドル', '1ドル],2ドル', ' => 1ドル', '[]1ドル', '0ドル0ドル'], $var_dump);
 $var_dump = preg_split('~\R~', $var_dump);
 $var_dump = preg_replace_callback(
 '/(\s*=>\s*)(NULL)/',
 function ($m) {
 return $m[1] . $this->GetType(str_replace("'", '', $m[2])) . ": {$m[2]},";
 }, $var_dump
 );
 $var_dump = preg_replace_callback(
 '/(\w+\W\d\W)\s*"([^"]+)"$/',
 function ($m) {
 return $this->GetType(str_replace("'", '', $m[2])) . ": {$m[2]},";
 }, $var_dump
 );
 $var_dump = preg_replace_callback(
 '/\w+\((\D+)\)$/',
 function ($m) {
 return $this->GetType(str_replace("'", '', $m[1])) . ": {$m[1]},";
 }, $var_dump
 );
 $var_dump = preg_replace_callback(
 '/\w+\((\d+)\)$/',
 function ($m) {
 return $this->GetType(str_replace("'", '', $m[1])) . ": {$m[1]},";
 }, $var_dump
 );
 $var_dump = preg_replace_callback(
 '/\w+\((\d*\.\d*)\)$/',
 function ($m) {
 return $this->GetType(str_replace("'", '', $m[1])) . ": {$m[1]},";
 }, $var_dump
 );
 $var_dump = preg_replace_callback(
 '/\w+\(\d+\)(\s*)"([^"]*)"$/',
 function ($m) {
 return $m[1] . $this->GetType(str_replace("'", '', $m[2])) . ': "' . $m[2] . '",';
 }, $var_dump
 );
 $var_dump = implode(PHP_EOL, $var_dump);
 $var_dump = preg_replace("/(NULL)(\r|\n)/", '1,ドル2ドル', $var_dump);
 $var_dump = preg_replace("/(\w+\s*\[)$/", '1ドル]', $var_dump);
 $var_dump = rtrim($var_dump, ',');
 if ($highlight && VERSYSTEM !== 'cli') {
 $textvar = highlight_string('<?php ' . PHP_EOL . '/***** Output of Data *****/' . PHP_EOL . $var_dump . ';' . PHP_EOL . '/***** Output of Data *****/' . PHP_EOL . '', true);
 $textvar = preg_replace("/\r|\n|<br>/", "", $textvar);
 }
 return $textvar;
 }
 public function VarExport($Var, $Var2 = null, $Var3 = null, $Var4 = null, $Var5 = null)
 {
 echo PRES;
 echo $this->VarExportFormat($Var, true) . EOL_SYS;
 if (null !== $Var2) {
 echo $this->VarExportFormat($Var2, true) . EOL_SYS;
 }
 if (null !== $Var3) {
 echo $this->VarExportFormat($Var3, true) . EOL_SYS;
 }
 if (null !== $Var4) {
 echo $this->VarExportFormat($Var4, true) . EOL_SYS;
 }
 if (null !== $Var5) {
 echo $this->VarExportFormat($Var5, true) . EOL_SYS;
 }
 echo PREE;
 }
 public function ValidateDate($date)
 {
 if (($timestamp = strtotime($date)) != false) {
 return true;
 } else {
 return false;
 }
 }
}

UPDATE 1

After the Suggestions and Updates from mickmackusa.

class-vars.php

asked Jun 26, 2020 at 0:31
\$\endgroup\$
0

1 Answer 1

3
\$\begingroup\$
  1. Unless you have a valuable/deliberate reason to use and in your condition statements, I recommend consistently using &&. Condition logic can sometimes fall prey to unintended "precedence" complications.

  2. This whole line is "jacked" (wrong / incorrectly coded):

    if ($this->ValidateDate($testdate[0], false) && $this->ValidateDate($testdate[1], false && strpos($testdate[1], ':') !== false)) {
    

    ValidateDate() only accepts one parameter, but you are passing two (in several instances to be honest). The second time that you call this method in this line, you omitted a ), so you are effectively doing this:

    $this->ValidateDate(
     $testdate[1],
     false && strpos($testdate[1], ':') !== false // <-- this, of course, will always be false
     // ...not that the 2nd parameter is ever respected by the method
    )
    

    I think you mean to write the following:

    if (strpos($testdate[1], ':') !== false && $this->ValidateDate($testdate[0]) && $this->ValidateDate($testdate[1])) {
    
  3. I don't like the body of the ValidateDate() method at all.

    • It declares $timestamp but never uses it.
    • It does a falsey check on strtotime()'s return value which can technically return 0.
    • It uses if and else to explicitly return true and false instead of returning the evaluation itself.


    I recommend that you scrap the method entirely and just call strtotime($string) !== false. That said, there are LOADS of strings that strtotime() will deem to be a date and/or time expression, so I don't know if this is the right form of validation -- maybe this is a subjective judgement call -- the decision/power is yours.

  4. Regarding this line:

    $var_dump = preg_replace(["/\[\"/", "/\"\]/", "/\]/", "/\[/", "/\)\s*\{(\s*\w*)/", "/(\s*\w*)\}(\s*\w*)/", "/=>\s*(\w)/", "/\[\s*\](,)/", "~^ +~m"], ["'", "'", '', '', ') [1ドル', '1ドル],2ドル', ' => 1ドル', '[]1ドル', '0ドル0ドル'], $var_dump);
    

    It is far beyond the recommended character width. It will make your script easier to read if you can avoid horizontal scrolling. Write each function parameter on a new line. Better still, write the elements on their own line; not only will this improve readability, it will afford you the space to write inline comments if you wish. Also, the first two patterns are replaced by ' so just combine the patterns with a pipe. Same advice with the 3rd and 4th patterns. Something like this:

    $var_dump = preg_replace(
     [
     '/\["|"]/',
     "/]|\[/",
     "/\)\s*{(\s*\w*)/",
     "/(\s*\w*)}(\s*\w*)/",
     "/=>\s*(\w)/",
     "/\[\s*](,)/",
     "~^ +~m"
     ],
     [
     "'",
     '',
     ') [1ドル',
     '1ドル],2ドル',
     ' => 1ドル',
     '[]1ドル',
     '0ドル0ドル'
     ],
     $var_dump
     );
    
  5. You are writing a battery of preg_replace_callback() calls on $var_dump. Generally speaking this looks like a perfect candidate for preg_replace_callback_array().

  6. I notice that you are making several str_replace() calls in callbacks where the match string cannot possibly have a single quote in it. These needless calls should be removed -- just pass the value to the GetType() method.

  7. This replacement:

    preg_replace("/(NULL)(\r|\n)/", '1,ドル2ドル', $var_dump);
    

    could be written without the captures/references as:

    preg_replace("/NULL\K(?=\R)/", ',', $var_dump);
    
  8. Pattern&Replacement: "/(\w+\s*\[)$/", '1ドル]' could be: "/\w+\s*\[$/", '0ドル]'

  9. "/\r|\n|<br>/" can be simplified to "/\R|<br>/"

  10. I don't see where constants PRES, PREE, and EOL_SYS are defined.

  11. I assume that you have arbitrarily decided to permit a maximum of 5 parameters to be passed into your VarExport() method. You needn't make such a rigid distinction. You can liberate the method and eliminate the battery of null !== checks using the splat operator and some native functions. Check out this Demonstration:

    class ClassVarsManager
    {
     private function VarExportFormat($data) {
     return '*' . $data . '*';
     }
     public function VarExport(...$var) {
     echo PRES , implode(EOL_SYS, array_map([$this, 'VarExportFormat'], $var)) , PREE;
     }
    }
    define('PRES', '<pre>');
    define('PREE', '</pre>');
    define('EOL_SYS', "\n");
    $obj = new ClassVarsManager();
    $obj->VarExport('one', 'two', 'three');
    

    Output:

    <pre>*one*
    *two*
    *three*</pre>
    

Finally, I just want to say good work. I know that you have been toiling at this task for a while now. This is such a great way to challenge yourself and learn new skills.

answered Jun 26, 2020 at 14:34
\$\endgroup\$
1
  • \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$ Commented Jul 1, 2020 at 19:17

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.