Eine beliebige Variable ausgeben

Welche Methoden von PHP zur Verfügung gestellt werden, um beliebige Variablen inklusive der Datentypen auszugeben

1. Einleitung

Für Debugging-Zwecke sind Funktionen nützlich, die jede beliebige Variable ausgeben können (idealerweise inklusive Datentyp). Standardmäßig werden von PHP drei solcher Funktionen zur Verfügung gestellt: var_dump(), print_r() und var_export(). Die Ausgaben dieser Funktionen sind sehr ähnlich. var_dump() ist speziell für Debugging-Zwecke gedacht und stellt daher genaue Informationen zu allen Datentypen dar. print_r() soll die Variablen „lesbar” darstellen und ergänzt daher in der Regel keine Datentypen. var_export() dient — dem Namen nach — zum Exportieren von Variablen, sodass der sich ergebende String wiederum per eval() ausgeführt werden kann, um die selbe Variable erneut zu erzeugen.

Der Nutzen von print_r() ist eher gering, da für Debugging-Zwecke die Datentypen zu wichtig sind als dass man auf sie verzichten kann. Bei Ausgaben, die sich an den Besucher richten, sollten wiederum die Datentypen der auszugebenden Variablen bekannt sein, sodass print_r() nicht notwendig ist. Das Exportieren von Variablen mittels var_export() wird nur sehr selten benötigt. So bleibt var_dump() als empfehlenswerte Methode zur Ausgabe von Variablen übrig.

2. var_dump()

Einige beispielhafte Ausgaben von var_dump():

PHP-Code
<?php
    var_dump((int)1000);
	var_dump((float)1.3144345);
	var_dump((bool)false);
	var_dump((string)"test");
	var_dump((object)new stdClass());
	var_dump((unset)null);
	var_dump((array)array(1, 2, 3));
?>

HTML-Code: Ausgabe
int(1000)
float(1.3144345)
bool(false)
string(4) "test"
object(stdClass)#1 (0) {
}
NULL
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}


var_dump() verhält sich wie echo: Alles was man an die Funktion übergibt wird sofort ausgegeben. Um das zu verhindern kann das Output Buffering verwendet werden. Mit ob_start() wird dies aktiviert — Ausgaben werden dann nicht mehr sofort an den Besucher gesendet. Über ob_get_contents() kann der bisherige Inhalt des Buffers abgefragt werden, um diesen in eine Variable zu übertragen. Beendet wird das Output Buffering wiederum mit ob_end_clean(). Die nachfolgende Funktion „myVarDump()” verwendet diese Technik, um die Ausgabe von var_dump „abzufangen” und per return zurückzugeben.

PHP-Code
<?php
	function myVarDump($var) {
		ob_start();
		var_dump($var);
		$out = ob_get_contents();
		ob_end_clean();
		return $out;
	}

	echo myVarDump((int)1000);
	echo myVarDump((float)1.42342);
	echo myVarDump(null);
?>

HTML-Code: Ausgabe
int(1000)
float(1.42342)
NULL


Um sämtliche definierte Variablen zu sehen kann die Funktion get_defined_vars() zur Hilfe genommen werden. Diese gibt ein Array zurück, welches alle Variablen enthält (Name der Variable als Schlüssel, Inhalt der Variable als Wert, der dem Schlüssel zugeordnet ist).

PHP-Code
<?php
	$a = 1343;
	$b = "example";
	$c = array(10, 11, 12);
	$d = array(array(array("test")));
	$e = false;

	var_dump(get_defined_vars());
?>

HTML-Code: Ausgabe
array(10) {
  ["GLOBALS"]=>
  &array(10) {
    ["GLOBALS"]=>
    *RECURSION*
    ["_POST"]=>
    array(0) {
    }
    ["_GET"]=>
    array(0) {
    }
    ["_COOKIE"]=>
    array(0) {
    }
    ["_FILES"]=>
    array(0) {
    }
    ["a"]=>
    int(1343)
    ["b"]=>
    string(7) "example"
    ["c"]=>
    array(3) {
      [0]=>
      int(10)
      [1]=>
      int(11)
      [2]=>
      int(12)
    }
    ["d"]=>
    array(1) {
      [0]=>
      array(1) {
        [0]=>
        array(1) {
          [0]=>
          string(4) "test"
        }
      }
    }
    ["e"]=>
    bool(false)
  }
  ["_POST"]=>
  array(0) {
  }
  ["_GET"]=>
  array(0) {
  }
  ["_COOKIE"]=>
  array(0) {
  }
  ["_FILES"]=>
  array(0) {
  }
  ["a"]=>
  int(1343)
  ["b"]=>
  string(7) "example"
  ["c"]=>
  array(3) {
    [0]=>
    int(10)
    [1]=>
    int(11)
    [2]=>
    int(12)
  }
  ["d"]=>
  array(1) {
    [0]=>
    array(1) {
      [0]=>
      array(1) {
        [0]=>
        string(4) "test"
      }
    }
  }
  ["e"]=>
  bool(false)
}


Die vorherige Ausgabe ist sehr umfangreich und enthält etwa auch alle globalen Variablen. Das von get_defined_vars() zurückgegebene Array kann daher „zurechtgestutzt” werden indem man array_diff_keys() verwendet. Mit array_diff_keys($arr1, $arr2) lassen sich aus $arr1 alle Schlüssel entfernen, die auch zugleich Schlüssel in $arr2 sind.

PHP-Code
<?php
	$a = 1343;
	$b = "example";
	$c = array(10, 11, 12);
	$d = array(array(array("test")));
	$e = false;

	var_dump(
		array_diff_key(
			// erzeuge get_defined_vars() ...
			get_defined_vars(),
			// ... ohne die folgenden Schluessel:
			array_flip(array('GLOBALS', '_POST', '_FILES', '_COOKIE'))
		)
	);
?>

HTML-Code: Ausgabe
array(6) {
  ["_GET"]=>
  array(0) {
  }
  ["a"]=>
  int(1343)
  ["b"]=>
  string(7) "example"
  ["c"]=>
  array(3) {
    [0]=>
    int(10)
    [1]=>
    int(11)
    [2]=>
    int(12)
  }
  ["d"]=>
  array(1) {
    [0]=>
    array(1) {
      [0]=>
      array(1) {
        [0]=>
        string(4) "test"
      }
    }
  }
  ["e"]=>
  bool(false)
}


3. print_r()

Das nächste Beispiel zeigt die Ausgaben von print_r(). Man beachte dabei, dass die Datentypen in der Regel nicht Teil der Ausgabe sind. Im Gegensatz zu var_dump() erzeugt print_r() zudem nicht immer einen Zeilenumbruch am Ende der Ausgabe, sodass dieser manuell hinzugefügt werden muss.

PHP-Code
<?php
	print_r((int)1000); echo("\n");
	print_r((float)1.3144345); echo("\n");
	print_r((bool)false); echo("\n");
	print_r((string)"test"); echo("\n");
	print_r((object)new stdClass()); echo("\n");
	print_r((unset)null); echo("\n");
	print_r((array)array(1, 2, 3)); echo("\n");
?>

HTML-Code: Ausgabe
1000
1.3144345

test
stdClass Object
(
)


Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)



Übergibt man als zweiten Parameter ein (bool)true an print_r(), dann gibt die Funktion ihr Ergebnis als String zurück, statt diesen direkt auszugeben:

PHP-Code
<?php
	echo(print_r((int)1000, true)); echo("\n");
	echo(print_r((float)1.3144345, true)); echo("\n");
	echo(print_r((bool)false, true)); echo("\n");
	echo(print_r((string)"test", true)); echo("\n");
	echo(print_r((object)new stdClass(), true)); echo("\n");
	echo(print_r((unset)null, true)); echo("\n");
	echo(print_r((array)array(1, 2, 3), true)); echo("\n");
?>

HTML-Code: Ausgabe
1000
1.3144345

test
stdClass Object
(
)


Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)



4. var_export()

Die Ausgaben von var_export() im Beispiel, auch hier fehlen viele Datentypen in der Ausgabe:

PHP-Code
<?php
	var_export((int)1000); echo("\n");
	var_export((float)1.3144345); echo("\n");
	var_export((bool)false); echo("\n");
	var_export((string)"test"); echo("\n");
	var_export((object)new stdClass()); echo("\n");
	var_export((unset)null); echo("\n");
	var_export((array)array(1, 2, 3)); echo("\n");
?>

HTML-Code: Ausgabe
1000
1.3144345
false
'test'
stdClass::__set_state(array(
))
NULL
array (
  0 => 1,
  1 => 2,
  2 => 3,
)


Wie bei print_r() kann auch an var_export() ein (bool)true als zweiter Parameter übergeben werden, sodass die Funktion ihr Ergebnis per return zurückgibt:

PHP-Code
<?php
	echo(var_export((int)1000, true)); echo("\n");
	echo(var_export((float)1.3144345, true)); echo("\n");
	echo(var_export((bool)false, true)); echo("\n");
	echo(var_export((string)"test", true)); echo("\n");
	echo(var_export((object)new stdClass(), true)); echo("\n");
	echo(var_export((unset)null, true)); echo("\n");
	echo(var_export((array)array(1, 2, 3), true)); echo("\n");
?>

HTML-Code: Ausgabe
1000
1.3144345
false
'test'
stdClass::__set_state(array(
))
NULL
array (
  0 => 1,
  1 => 2,
  2 => 3,
)


5. Eigene Funktion

Natürlich lässt sich auch eine eigene Funktion schreiben, um Variablen auszugeben. Diese kann entsprechend vom Design her angepasst werden, während eine Anpassung der Standardfunktionen (var_dump, print_r, var_export) nicht möglich ist. Die nachfolgende Funktion showVar() erwartet eine Variable als Parameter und wandelt diese in die Form „(datentyp)inhalt” um (Rückgabe als String). Bei Arrays wird gleiches auch auf alle Schlüssel und Werte angewendet. Bei Objekten wiederum wird „(object)Klassenname” zurückgegeben.

PHP-Code
<?php
	function showVar($var, $showType=true) {
		if (is_int($var)) {
			// Integers
			return ($showType ? '(int)'.$var : $var);
		} else if (is_float($var)) {
			// Floats
			return ($showType ? '(float)'.round($var, 4) : round($var, 4));
		} else if (is_string($var)) {
			// Strings
			return ($showType ? '(string)"'.$var.'"' : '"'.$var.'"');
		} else if (is_bool($var)) {
			// Booleans
			$var = ($var ? 'true' : 'false');
			return ($showType ? '(bool)'.$var : $var);
		} else if (is_array($var)) {
			// Arrays
			$out = ($showType ? '(array)(' : '(');
			$c = '';
			foreach ($var as $key=>$val) {
				if ($c!=='') {
					$c .= ', ';
				}
				// Schluessel => Wert
				$c .= showVar($key, $showType) . ' => ' . showVar($val, $showType);
			}
			$out .= $c . ')';
			return $out;
		} else if (is_object($var)) {
			// Objekte
			return ($showType ? '(object)'.get_class($var) : get_class($var));
		} else if (is_resource($var)) {
			// Resourcen
			return '(resource)';
		} else if (is_null($var)) {
			// NULL
			return 'NULL';
		} else {
			// anderes bzw. unbekanntes
			return '('.gettype($var).')?';
		}
	}


	$null = null;
	$int = 1000;
	$float = 1.7773;
	$bool = false;
	$string = "example";
	$obj = new stdClass();
	$arr1 = array(1, 2, 3);
	$arr2 = array(array(1, 2), array("hello", "world"));

	echo('$null: '.showVar($null)."\n");
	echo('$int: '.showVar($int)."\n");
	echo('$float: '.showVar($float)."\n");
	echo('$bool: '.showVar($bool)."\n");
	echo('$string: '.showVar($string)."\n");
	echo('$obj: '.showVar($obj)."\n");
	echo('$arr1: '.showVar($arr1)."\n");
	echo('$arr2: '.showVar($arr2));
?>

HTML-Code: Ausgabe
$null: NULL
$int: (int)1000
$float: (float)1.7773
$bool: (bool)false
$string: (string)"example"
$obj: (object)stdClass
$arr1: (array)((int)0 => (int)1, (int)1 => (int)2, (int)2 => (int)3)
$arr2: (array)((int)0 => (array)((int)0 => (int)1, (int)1 => (int)2), (int)1 => (array)((int)0 => (string)"hello", (int)1 => (string)"world"))


Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0