|
#!/usr/bin/env php |
|
<?php |
|
|
|
/** |
|
* * Responding to: http://stackoverflow.com/questions/418066/best-way-to-test-for-a-variables-existence-in-php-isset-is-clearly-broken |
|
* |
|
* $ php path/to/this_file.php (value|v) |
|
* |
|
* arguments: |
|
* none default is to show a combined table |
|
* (value|v) displays a table per value |
|
*/ |
|
|
|
mb_internal_encoding("UTF-8"); |
|
|
|
$values = [ |
|
'$a' => $a |
|
, 'null' => null |
|
, '[ ]' => [] |
|
, '0' => 0 |
|
, '""' => "" |
|
, '1' => 1 |
|
, '-1' => -1 |
|
, '" "' => " " |
|
, '"str"' => "str" |
|
, '[0,1]' => [0,1] |
|
, 'new stdClass ' => new stdClass |
|
]; |
|
|
|
$array_values_source = [ |
|
[ |
|
'null' => null |
|
, 'empty_array' => [] |
|
, 'zero_num' => 0 |
|
, 'empty_string' => "" |
|
],[ // this split is arbirtray to show nesting |
|
'one_num' => 1 |
|
, '-one_num' => -1 |
|
, 'single_space' => " " |
|
, 'string' => "str" |
|
, 'array' => [0,1] |
|
, 'new_stdClass' => new stdClass |
|
] |
|
]; |
|
|
|
$array_values = [ |
|
'(missing key)' => $array_values_source[$missing] |
|
, '(missing index)' => $array_values_source[99] |
|
, 'null' => $array_values_source[0]['null'] |
|
, '[ ]' => $array_values_source[0]['empty_array'] |
|
, '0' => $array_values_source[0]['zero_num'] |
|
, '""' => $array_values_source[0]['empty_string'] |
|
, '1' => $array_values_source[1]['one_num'] |
|
, '-1' => $array_values_source[1]['-one_num'] |
|
, '" "' => $array_values_source[1]['single_space'] |
|
, '"str"' => $array_values_source[1]['string'] |
|
, '[0,1]' => $array_values_source[1]['array'] |
|
, 'new stdClass' => $array_values_source[1]['new_stdClass'] |
|
]; |
|
|
|
$tests = [ |
|
'=== null' => function($a){ return $a === null; } |
|
, 'is_null' => function($a){ return is_null($a); } |
|
, 'isset' => function($a){ return isset($a); } |
|
, 'empty' => function($a){ return empty($a); } |
|
, 'if/else' => function($a){ if($a){ return true; }else{ return false; } } |
|
, 'ternary' => function($a){ return $a ? true : false; } |
|
, 'count > 0' => function($a){ return count($a) > 0; } |
|
]; |
|
|
|
// CLI ARGUMENTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
if ($argv[1] === 'value' || $argv[1] === 'v') |
|
{ |
|
drawTablePerValue( $values, $tests ); |
|
// drawTablePerValue( $array_values, $tests ); |
|
} |
|
else |
|
{ |
|
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; |
|
echo " Values accessed from variables: \n"; |
|
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; |
|
drawCombinedTable( $values, $tests ); |
|
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; |
|
echo " Values accessed from array (identical results): \n"; |
|
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; |
|
drawCombinedTable( $array_values, $tests ); |
|
|
|
echo "~~~~~~~~~~~~~~~~~~~\n"; |
|
echo " array_key_exists: \n"; |
|
echo "~~~~~~~~~~~~~~~~~~~\n"; |
|
drawArrayKeyExist(); |
|
} |
|
|
|
// OUTPUT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
function drawCombinedTable($values, $tests) |
|
{ |
|
// headers |
|
// seed with empty space for upper-left corner |
|
$columns = [['', '-----']]; |
|
// add headings (row 0) and markdown heading-pipes (row 1) |
|
foreach ($tests as $label => $test) { |
|
$columns[] = [ $label, '-----' ]; |
|
} |
|
|
|
// add rows 2…n for each test(value) |
|
foreach ($values as $value_label => $a) { |
|
$i = 0; |
|
// value label in (col 0) |
|
if ($value_label === '$a') $value_label = '$a;'; |
|
$columns[$i][] = $value_label; |
|
// evaluate test(value) (col 1…n) |
|
foreach ($tests as $test_label => $func) { |
|
$columns[++$i][] = $func($a) ? 'true' : ''; |
|
} |
|
} |
|
|
|
// space each column |
|
$columns = array_map( |
|
function($c){ return alignColumn($c); }, $columns |
|
); |
|
|
|
// draw table row by row |
|
$rowcount = count($columns[0]); // assume first column has correct #rows |
|
$colcount = count($columns); |
|
for ($i = 0; $i < $rowcount; $i++) { |
|
for ($j = 0; $j < $colcount; $j++) |
|
echo '| '. $columns[$j][$i] .' '; |
|
echo "|\n"; |
|
} |
|
} |
|
|
|
function drawTablePerValue($values, $tests) |
|
{ |
|
foreach ($values as $table_label => $a) |
|
{ |
|
// format label |
|
if ($table_label !== '$a') |
|
$table_label = '$a = '. $table_label; |
|
|
|
// table top + table label |
|
echo '+'. str_repeat('=', 8) |
|
.' '. $table_label .'; ' |
|
. str_repeat('=', 30-mb_strlen($table_label)) |
|
. "+\n"; |
|
|
|
// first row is a non-test "var_dump" item |
|
$testLabels = ['var_dump']; |
|
$results = [captureVarDump($a)]; |
|
|
|
// evaluate tests |
|
foreach ($tests as $test_label => $func) { |
|
$testLabels[] = $test_label; |
|
$results[] = $func($a) ? 'true' : ''; // expects $func() to return boolean |
|
} |
|
|
|
// space columns |
|
$testLabels = alignColumn($testLabels, 'right', 20); |
|
$results = alignColumn($results, 'left', 60); |
|
|
|
// output rows |
|
for ($i = 0, $len = count($results); $i < $len; $i++) |
|
echo '| '. $testLabels[$i] .' : '. $results[$i] . "\n"; |
|
|
|
// table end |
|
echo "|\n"; |
|
} |
|
} |
|
|
|
function drawArrayKeyExist() |
|
{ |
|
// setup test data |
|
$testdata = [ |
|
'key for 0' => 0 |
|
, 'key for -1' => -1 |
|
, 'key for []' => [] |
|
, 'key for ""' => '' |
|
, 0 => 'set' |
|
, 1 => null |
|
, 'key for null' => null |
|
]; |
|
|
|
// create header |
|
$results = [ |
|
array('key','+-+'), |
|
array('value','+---+'), |
|
array('array_key_exists','+--------------+'), |
|
array('isset','+---+') |
|
]; |
|
|
|
// do tests |
|
foreach ( $testdata as $key_to_test => $z ) |
|
doTest($results, $testdata, $key_to_test); |
|
doTest($results, $testdata, 2); |
|
doTest($results, $testdata, $blah, '($blah: doesn\'t exsist)'); |
|
$testdata['never_set']; |
|
doTest($results, $testdata, 'never_set', 'never_set'); |
|
|
|
// align columns |
|
$label = alignColumn($results[0], 'right'); |
|
$vrdmp = alignColumn($results[1]); |
|
$ake = alignColumn($results[2]); |
|
$isset = alignColumn($results[3]); |
|
|
|
for ($i = 0, $len = count($label); $i < $len; $i++ ) |
|
echo '| '. $label[$i] .' : '. $ake[$i] .' : '. $isset[$i] .' : '. $vrdmp[$i] ." |\n"; |
|
} |
|
|
|
function doTest(&$result, $test_a, $key, $label = null) |
|
{ |
|
if (empty($label)) $label = $key; |
|
if (is_string($label)) $label = "'". $label ."'"; |
|
$result[0][] = $label; |
|
$result[1][] = '('. captureVarDump($test_a[$key]) .')'; |
|
$result[2][] = array_key_exists($key, $test_a) ? 'true' : ''; |
|
$result[3][] = isset($test_a[$key], $test_a) ? 'true' : ''; |
|
} |
|
|
|
|
|
// TOOLBELT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
function captureVarDump($in) |
|
{ |
|
ob_start(); |
|
var_dump($in); |
|
$capture = ob_get_clean(); |
|
ob_end_flush(); |
|
$capture = str_replace("\n", "", $capture); |
|
$capture = str_replace(" ", " ", $capture); |
|
return $capture; |
|
} |
|
|
|
function alignColumn($strings, $position = 'left', $max = 80) |
|
{ |
|
$lengths = array_map( |
|
function($n){ return mb_strlen($n); }, $strings |
|
); |
|
$maxlen = max($lengths); |
|
$maxlen = ($maxlen > $max) ? $max : $maxlen; |
|
|
|
$spaced = array(); |
|
foreach ($strings as $str) |
|
{ |
|
$str = mb_substr($str, 0, $maxlen); |
|
$strlen = mb_strlen($str); |
|
$padlen = $maxlen - $strlen; |
|
switch ($position) { |
|
case 'right' : |
|
$spaced[] = str_repeat(' ', $padlen) . $str; |
|
break; |
|
case 'center' : |
|
$spaced[] = str_repeat(' ', ceil($padlen/2) ) |
|
. $str |
|
. str_repeat(' ', floor($padlen/2) ); |
|
break; |
|
case 'left' : |
|
default : |
|
$spaced[] = $str . str_repeat(' ', $padlen); |
|
} |
|
} |
|
|
|
return $spaced; |
|
} |