it-swarm.com.de

Verwenden von print_r und var_dump mit Zirkelverweis

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

38

Wir verwenden das PRADO Framework und haben eine eingebaute Klasse mit dem Namen "TVarDumper". Satzstellung markieren. Sie können diese Klasse von HIER erhalten.

12
ChrFin

Doctrine haben die gleichen Serviceklasse.

Anwendungsbeispiel:

<?php echo "<pre>"; \Doctrine\Common\Util\Debug::dump($result, 4); echo "</pre>";?>
14
Alorian

TVarDumper

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 <[email protected]>
 * @link http://www.pradosoft.com/
 * @copyright Copyright &copy; 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 <[email protected]>
 * @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('/&lt;\\?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;
        }
    }
}

XDebug var_dump

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));

features_var_export

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);

Serialisieren

Verwenden Sie serialize, um das Objekt in serialisierter Darstellung zu sichern, z.

echo serialize($object);

JSON-Codierung

Verwenden Sie json_encode, um es im JSON-Format zu konvertieren, z.

echo json_encode($object);

Siehe auch: Test, ob Variable Zirkelverweise enthält

5
kenorb

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.

4
kapa
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
2
binaryLV

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');
    }

}

1
Lucian Depold

Dies schien die Arbeit für mich zu erledigen:

print_r(json_decode(json_encode($value)));
1
fcrick

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);
0
Ostin