11 Stimmen

Testen, ob eine Variable serialisierbar ist

Ich bin auf der Suche nach einer eleganten Methode zum Testen, ob eine Variable serialisierbar ist. Zum Beispiel array( function() {} ) wird die Serialisierung fehlschlagen.

Ich verwende derzeit den unten stehenden Code, aber es scheint ein eher nicht-optimaler Weg zu sein, dies zu tun.

function isSerializable( $var )
{
    try {
        serialize( $var );
        return TRUE;
    } catch( Exception $e ) {
        return FALSE;
    }
}

var_dump( isSerializable( array() ) );                // bool(true)
var_dump( isSerializable( function() {} ) );          // bool(false)
var_dump( isSerializable( array( function() {} ) ) ); // bool(false)

10voto

luka8088 Punkte 360

Die Alternative könnte lauten:

function isSerializable ($value) {
  $return = true;
  $arr = array($value);

  array_walk_recursive($arr, function ($element) use (&$return) {
    if (is_object($element) && get_class($element) == 'Closure') {
      $return = false;
    }
  });

  return $return;
}

Aber aus den Kommentaren schließe ich, dass es das ist, wonach Sie suchen:

function mySerialize ($value) {
  $arr = array($value);

  array_walk_recursive($arr, function (&$element) {

    # do some special stuff (serialize closure) ...
    if (is_object($element) && get_class($element) == 'Closure') {
      $serializableClosure = new SerializableClosure($element);
      $element = $serializableClosure->serialize();
    }

  });

  return serialize($arr[0]);
}

1voto

Tivie Punkte 18643

Späte Antwort, aber...

Gemäß der PHP-Dokumentation können Variablen vom Typ Ressource nicht serialisiert werden. Zumindest in PHP 5.4 löst der Versuch, eine Ressource zu serialisieren, jedoch keinen Fehler aus.

Ich denke, ein besserer Ansatz wäre es, auf Abschlüsse und Ressourcen ohne try/catch zu testen:

$resource = fopen('composer.json', 'r');
$closure = function() {
    return 'bla';
};
$string = 'string';

function isSerializable($var)
{
    if (is_resource($var)) {
        return false;
    } else if ($var instanceof Closure) {
        return false;
    } else {
        return true;
    }
}

var_dump(isSerializable($resource));
var_dump(isSerializable($closure));
var_dump(isSerializable($string));

Ausgänge:

boolean false 
boolean false
boolean true

0voto

Tyler V. Punkte 2115

Ich verwende das hier. Es kombiniert eine Reihe von Vorschlägen hier, plus eine Prüfung für instaneof ArrayAccess die serialisierbar sein sollten.

if (!function_exists('is_iterable')) {
    function is_iterable($var) {
        return is_array($var) || (is_object($var) && ($var instanceof \Traversable));
    }
}

function is_serializable($var, $iterate=true) {
    if (is_resource($var)) {
        return false;
    } else if (is_object($var)) {
        if ($var instanceof Closure) {
            return false;
        } else if (!$var instanceof Serializable && !$var instanceof ArrayAccess) {
            return false;
        }
    }

    if ($iterate && is_iterable($var)) {
        foreach ($var as $key => $value) {
            if (!is_serializable($value, true)) {
                return false;
            }
        }
    }

    return true;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X