Ich verwende das MVC-Framework Symfony , und es scheint, dass viele der integrierten Objekte, die ich debuggen möchte, Zirkelverweise haben. Dies macht es unmöglich, die Variablen mit print_r()
oder var_dump()
zu drucken.
Gibt es bessere Alternativen, als meinen eigenen print_r
- Klon mit etwas Intelligenz zu schreiben? Ich möchte nur in der Lage sein, ein variables (Objekt, Array oder Skalar) entweder in einer Protokolldatei, einem http-Header oder auf der Webseite selbst zu drucken.
Bearbeiten: Um das Problem zu lösen, versuchen Sie diesen Code:
<?php
class A
{
public $b;
public $c;
public function __construct()
{
$this->b = new B();
$this->c = new C();
}
}
class B
{
public $a;
public function __construct()
{
$this->a = new A();
}
}
class C
{
}
ini_set('memory_limit', '128M');
set_time_limit(5);
print_r(new A());
#var_dump(new A());
#var_export(new A());
Es funktioniert nicht mit print_r()
, var_dump()
oder var_export()
. Die Fehlermeldung lautet:
Schwerwiegender PHP-Fehler: Zulässige Speichergröße von 134217728 Byte erschöpft (versucht, 523800 Byte zuzuweisen) in print_r_test.php in Zeile 10
Wir verwenden das PRADO Framework und haben eine eingebaute Klasse mit dem Namen "TVarDumper". Satzstellung markieren. Sie können diese Klasse von HIER erhalten.
Doctrine haben die gleichen Serviceklasse.
Anwendungsbeispiel:
<?php echo "<pre>"; \Doctrine\Common\Util\Debug::dump($result, 4); echo "</pre>";?>
TVarDumper soll die fehlerhaften PHP Funktionen var_dump
und print_r
ersetzen, da es die rekursiv referenzierten Objekte in einer unterschiedlichen Objektstruktur korrekt identifizieren kann. Some special variables to avoid.
Überprüfen Sie TVarDumper.php
:
<?php
/**
* TVarDumper class file
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.pradosoft.com/
* @copyright Copyright © 2005-2013 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Util
*/
/**
* TVarDumper class.
*
* TVarDumper is intended to replace the buggy PHP function var_dump and print_r.
* It can correctly identify the recursively referenced objects in a complex
* object structure. It also has a recursive depth control to avoid indefinite
* recursive display of some peculiar variables.
*
* TVarDumper can be used as follows,
* <code>
* echo TVarDumper::dump($var);
* </code>
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package System.Util
* @since 3.0
*/
class TVarDumper
{
private static $_objects;
private static $_output;
private static $_depth;
/**
* Converts a variable into a string representation.
* This method achieves the similar functionality as var_dump and print_r
* but is more robust when handling complex objects such as PRADO controls.
* @param mixed variable to be dumped
* @param integer maximum depth that the dumper should go into the variable. Defaults to 10.
* @return string the string representation of the variable
*/
public static function dump($var,$depth=10,$highlight=false)
{
self::$_output='';
self::$_objects=array();
self::$_depth=$depth;
self::dumpInternal($var,0);
if($highlight)
{
$result=highlight_string("<?php\n".self::$_output,true);
return preg_replace('/<\\?php<br \\/>/','',$result,1);
}
else
return self::$_output;
}
private static function dumpInternal($var,$level)
{
switch(gettype($var))
{
case 'boolean':
self::$_output.=$var?'true':'false';
break;
case 'integer':
self::$_output.="$var";
break;
case 'double':
self::$_output.="$var";
break;
case 'string':
self::$_output.="'$var'";
break;
case 'resource':
self::$_output.='{resource}';
break;
case 'NULL':
self::$_output.="null";
break;
case 'unknown type':
self::$_output.='{unknown}';
break;
case 'array':
if(self::$_depth<=$level)
self::$_output.='array(...)';
else if(empty($var))
self::$_output.='array()';
else
{
$keys=array_keys($var);
$spaces=str_repeat(' ',$level*4);
self::$_output.="array\n".$spaces.'(';
foreach($keys as $key)
{
self::$_output.="\n".$spaces." [$key] => ";
self::$_output.=self::dumpInternal($var[$key],$level+1);
}
self::$_output.="\n".$spaces.')';
}
break;
case 'object':
if(($id=array_search($var,self::$_objects,true))!==false)
self::$_output.=get_class($var).'#'.($id+1).'(...)';
else if(self::$_depth<=$level)
self::$_output.=get_class($var).'(...)';
else
{
$id=array_Push(self::$_objects,$var);
$className=get_class($var);
$members=(array)$var;
$keys=array_keys($members);
$spaces=str_repeat(' ',$level*4);
self::$_output.="$className#$id\n".$spaces.'(';
foreach($keys as $key)
{
$keyDisplay=strtr(trim($key),array("\0"=>':'));
self::$_output.="\n".$spaces." [$keyDisplay] => ";
self::$_output.=self::dumpInternal($members[$key],$level+1);
}
self::$_output.="\n".$spaces.')';
}
break;
}
}
}
Verwenden Sie die Erweiterung XDebug PHP, um zu erkennen und zu ignorieren, z.
echo xdebug_var_dump($object);
print_r
+ array_slice
Nach diesem Beitrag können Sie versuchen:
print_r(array_slice($desiredArray, 0, 4));
Using the following function, the Part of the Moduls Features for Drupal ( features.export.inc
) is:
/**
* Export var function
*/
function features_var_export($var, $prefix = '', $init = TRUE, $count = 0) {
if ($count > 50) {
// Recursion depth reached.
return '...';
}
if (is_object($var)) {
$output = method_exists($var, 'export') ? $var->export() : features_var_export((array) $var, '', FALSE, $count+1);
}
else if (is_array($var)) {
if (empty($var)) {
$output = 'array()';
}
else {
$output = "array(\n";
foreach ($var as $key => $value) {
// Using normal var_export on the key to ensure correct quoting.
$output .= " " . var_export($key, TRUE) . " => " . features_var_export($value, ' ', FALSE, $count+1) . ",\n";
}
$output .= ')';
}
}
else if (is_bool($var)) {
$output = $var ? 'TRUE' : 'FALSE';
}
else if (is_int($var)) {
$output = intval($var);
}
else if (is_numeric($var)) {
$floatval = floatval($var);
if (is_string($var) && ((string) $floatval !== $var)) {
// Do not convert a string to a number if the string
// representation of that number is not identical to the
// original value.
$output = var_export($var, TRUE);
}
else {
$output = $floatval;
}
}
else if (is_string($var) && strpos($var, "\n") !== FALSE) {
// Replace line breaks in strings with a token for replacement
// at the very end. This protects whitespace in strings from
// unintentional indentation.
$var = str_replace("\n", "***BREAK***", $var);
$output = var_export($var, TRUE);
}
else {
$output = var_export($var, TRUE);
}
if ($prefix) {
$output = str_replace("\n", "\n$prefix", $output);
}
if ($init) {
$output = str_replace("***BREAK***", "\n", $output);
}
return $output;
}
Verwendungszweck:
echo features_var_export($object);
Verwenden Sie serialize
, um das Objekt in serialisierter Darstellung zu sichern, z.
echo serialize($object);
Verwenden Sie json_encode
, um es im JSON-Format zu konvertieren, z.
echo json_encode($object);
Siehe auch: Test, ob Variable Zirkelverweise enthält
Sie könnten var_export()
verwenden.
var_export () verarbeitet keine Zirkelverweise, da es nahezu unmöglich wäre, dafür syntaktisch analysierbaren PHP Code zu generieren. If you have you much is available of a arrays or objects to want, use you serialize () () () () () () () () () () () () () () () ().
UPDATE: Scheint, als hätte ich mich geirrt. Ich dachte, ich hätte diese Funktion für einige Zeit verwendet, aber es muss eine betrunkene Vorstellung gewesen sein.
Auf diese Weise kann ich nur raten, Xdebug zu installieren.
class Test {
public $obj;
}
$obj = new Test();
$obj->obj = $obj;
print_r($obj);
var_dump($obj);
Ausgabe:
Test Object
(
[obj] => Test Object
*RECURSION*
)
object(Test)[1]
public 'obj' =>
&object(Test)[1]
Es scheint mir, dass sowohl print_r()
als auch var_dump()
problemlos mit Rekursionen umgehen können. Verwenden von PHP 5.3.5 unter Windows.
var_export()
erkennt keine Rekursion, was zu einem sofortigen schwerwiegenden Fehler führt:
Fatal error: Nesting level too deep - recursive dependency? in \sandbox\index.php on line 28
Ich hatte dieses Problem auch und ich löste es, indem ich die Methode __get () implementierte, um den Referenzkreis zu durchbrechen. Die __get () -Methode wird aufgerufen, nachdem ein Attribut in der Klassendeklaration nicht gefunden wurde. Die __get () -Methode ruft auch den Namen des fehlenden Attributs ab. Hiermit können Sie "virtuelle Attribute" definieren, die gleiche Weise wie üblich funktionieren, jedoch nicht von der Funktion print_r erwähnt werden. Hier ein Beispiel:
public function __get($name)
{
if ($name=="echo") {
return Zend_Registry::get('textConfig');
}
}
Dies schien die Arbeit für mich zu erledigen:
print_r(json_decode(json_encode($value)));
Symfony hat heutzutage auch eine VarDumer-Komponente: https://symfony.com/doc/current/components/var_dumper.html
Es verarbeitet Zirkelverweise und unterstützt Remote-Dump-Server.
Die Installation ist ziemlich einfach:
composer require symfony/var-dumper --dev
Dann können Sie die globale Funktion dump
verwenden (ich nehme an, dass die autoload.php des Komponisten bereits enthalten ist):
<?php
/* ... */
dump($someVar);