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.
1 Answer 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.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])) {
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
andelse
to explicitly returntrue
andfalse
instead of returning the evaluation itself.
I recommend that you scrap the method entirely and just callstrtotime($string) !== false
. That said, there are LOADS of strings thatstrtotime()
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.- It declares
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 );
You are writing a battery of
preg_replace_callback()
calls on$var_dump
. Generally speaking this looks like a perfect candidate forpreg_replace_callback_array()
.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 theGetType()
method.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);
Pattern&Replacement:
"/(\w+\s*\[)$/", '1ドル]'
could be:"/\w+\s*\[$/", '0ドル]'
"/\r|\n|<br>/"
can be simplified to"/\R|<br>/"
I don't see where constants
PRES
,PREE
, andEOL_SYS
are defined.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 ofnull !==
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.
-
\$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$Mathieu Guindon– Mathieu Guindon2020年07月01日 19:17:02 +00:00Commented Jul 1, 2020 at 19:17
Explore related questions
See similar questions with these tags.