Übernimmt von einem JSON-Webdienst abgerufene Daten und wandelt sie in verschachtelte Objekte und Arrays um – unter Verwendung Ihrer eigenen Modellklassen.
Ausgehend von einem Basisobjekt ordnet es JSON-Daten Klasseneigenschaften zu und konvertiert sie in die richtigen einfachen Typen oder Objekte.
Es ist ein bisschen wie die native SOAP-Parameterzuordnung, die PHPs SoapClient
Ihnen bietet, aber für JSON. Es basiert nicht auf einem Schema, sondern nur auf Ihren PHP-Klassendefinitionen.
Die Typerkennung erfolgt durch das Parsen von Typdeklarationen und @var
Docblock-Anmerkungen von Klasseneigenschaften sowie von Typhinweisen in Setter-Methoden.
Sie müssen Ihre Modellklassen nicht durch Hinzufügen von JSON-spezifischem Code ändern; Es funktioniert automatisch, indem es bereits vorhandene Dokumentblöcke analysiert.
Diese Bibliothek hat keine Abhängigkeiten.
Schlüsselwörter: Deserialisierung, Hydratation
Inhalt
map()
Modellklassen müssen von Hand geschrieben werden
Da JsonMapper nicht auf Schemainformationen (z. B. von json-schema) angewiesen ist, können Modellklassen nicht automatisch generiert werden.
netresearch/jsonmapper
mit ComposerJsonMapper
Objektinstanzmap
oder mapArray
aufOrdnen Sie ein normales Objekt zu:
<?php
require ' autoload.php ' ;
$ mapper = new JsonMapper ();
$ contactObject = $ mapper -> map ( $ jsonContact , new Contact ());
// or as classname
$ contactObject = $ mapper -> map ( $ jsonContact , Contact::class);
Ordnen Sie ein Array von Objekten zu:
<?php
require ' autoload.php ' ;
$ mapper = new JsonMapper ();
$ contactsArray = $ mapper -> mapArray (
$ jsonContacts , array (), ' Contact '
);
Anstelle von array()
können Sie auch ArrayObject
und abgeleitete Klassen sowie Klassen verwenden, ArrayAccess
implementieren.
JSON von einem Adressbuch-Webdienst:
{
"name" : "Sheldon Cooper" ,
"address" : {
"street" : "2311 N. Los Robles Avenue" ,
"city" : "Pasadena"
}
}
Ihre lokale Contact
:
<?php
class Contact
{
/**
* Full name
*/
public string $ name ;
public ? Address $ address ;
}
Ihre lokale Address
:
<?php
class Address
{
public $ street ;
public $ city ;
public function getGeoCoords ()
{
//do something with $street and $city
}
}
Ihr Anwendungscode:
<?php
$ json = json_decode ( file_get_contents ( ' http://example.org/sheldon.json ' ));
$ mapper = new JsonMapper ();
$ contact = $ mapper -> map ( $ json , new Contact ());
echo " Geo coordinates for " . $ contact -> name . " : "
. var_export ( $ contact -> address -> getGeoCoords (), true );
JsonMapper
verwendet mehrere Quellen, um den richtigen Typ einer Eigenschaft in der folgenden Reihenfolge zu erkennen:
Setter-Methode ( set
+ ucwords($propertyname)
)
Unterstriche „ _
“ und Bindestriche „ -
“ machen den nächsten Buchstaben groß. Die Eigenschaft foo_bar-baz
führt zur Setter-Methode setFooBarBaz
.
Wenn die Methodensignatur einen Typhinweis enthält, wird folgender Typ verwendet:
öffentliche Funktion setPerson(Contact $person) {...}
Der Dokumentblock der Methode wird auf @param $type
-Anmerkungen überprüft:
/** * @param Kontakt $person Hauptkontakt für diese Anwendung */ öffentliche Funktion setPerson($person) {...}
Wenn kein Typ erkannt werden konnte, wird der einfache JSON-Wert an die Setter-Methode übergeben.
Klasseneigenschaftstypen (seit PHP 7.4):
öffentlicher Kontakt $person;
Typen der Konstruktor-Eigenschaftsförderung (seit PHP 8.0):
öffentliche Funktion __construct(protected Contact $person) {}
@var $type
docblock Annotation von Klasseneigenschaften:
/** * @var myapplicationmodelContact */ öffentliche $person;
Für eine unmittelbare Nutzung muss das Grundstück öffentlich sein. Sie können $bIgnoreVisibility auch verwenden, um geschützte und private Eigenschaften zu nutzen.
Wenn kein Typ erkannt werden konnte, erhält die Eigenschaft den einfachen JSON-Wertsatz.
Wenn eine Eigenschaft nicht gefunden werden kann, versucht JsonMapper, die Eigenschaft ohne Berücksichtigung der Groß-/Kleinschreibung zu finden. Eine JSON-Eigenschaft isempty
würde dann einer PHP-Eigenschaft isEmpty
zugeordnet.
Notiz
Damit der Typ funktioniert, müssen Sie den vollständig qualifizierten Namespace bereitstellen. Relative Klassennamen werden im Kontext des aktuellen Klassen-Namensraums ausgewertet, wobei eventuell vorhandene Importe NICHT berücksichtigt werden.
PHP stellt die Importe nicht über Reflection bereit; Der Kommentartext enthält nur den Literaltext des Typs. Aus Leistungsgründen analysiert JsonMapper den Quellcode nicht selbst, um etwaige Importe zu erkennen und zu erweitern.
Einfache Typen
string
bool
, boolean
int
, integer
double
, float
array
object
mixed
Klassennamen, mit und ohne Namespaces
Contact
– Eine Ausnahme wird ausgelöst, wenn der JSON-Wert null
istArrays einfacher Typen und Klassennamen:
int[]
Contact[]
Mehrdimensionale Arrays:
int[][]
TreeDeePixel[][][]
ArrayObjects einfacher Typen und Klassennamen:
ContactList[Contact]
NumberList[int]
Unterstützte Aufzählungen mit und ohne Namespaces
Suit:string|Suit:int
– Ausnahme wird ausgelöst, wenn der JSON-Wert nicht in der Aufzählung vorhanden ist
Nullable-Typen:
int|null
oder ?int
– ist null
, wenn der Wert in JSON null
ist, andernfalls ist es eine GanzzahlContact|null
oder ?Contact
– ist null
, wenn der Wert in JSON null
ist, andernfalls handelt es sich um ein Objekt vom Typ Contact
ArrayObjects und Erweiterungsklassen werden als Arrays behandelt.
Variablen ohne Typ oder mit mixed
Typ erhalten den JSON-Wert direkt und ohne Konvertierung.
Weitere Informationen finden Sie in der Typdokumentation von phpdoc.
Notiz
Diese Funktion ist aus Sicherheitsgründen seit Version 5 standardmäßig deaktiviert. Weitere Informationen finden Sie unter $bStrictObjectTypeChecking.
Wenn ein Objekt erstellt werden soll, der JSON jedoch nur einen einfachen Typ enthält (z. B. String, Float, Boolean), wird dieser Wert an den Konstruktor der Klassen übergeben. Beispiel:
PHP-Code:
public DateTime $ date ;
JSON:
{ "date" : "2014-05-15" }
Dies führt dazu, dass new DateTime('2014-05-15')
aufgerufen wird.
Wenn Variablen als Objekte abstrakter Klassen oder Schnittstellen definiert werden, versucht JsonMapper normalerweise, diese direkt zu instanziieren, was zum Absturz führt.
Mit der Eigenschaft $classMap
von JsonMapper können Sie angeben, welche Klassen stattdessen instanziiert werden sollen:
$ jm = new JsonMapper ();
$ jm -> classMap [ ' Foo ' ] = ' Bar ' ;
$ jm -> map (...);
Dadurch würden Objekte vom Typ Bar
erstellt, wenn eine Variable als Typ Foo
definiert ist.
Es ist auch möglich, ein Callable zu verwenden, wenn die tatsächliche Implementierungsklasse dynamisch bestimmt werden muss (z. B. im Fall einer Union). Die zugeordnete Klasse (im Beispiel unten „Foo“) und die Json-Daten werden als Parameter an den Aufruf übergeben.
$ mapper = function ( $ class , $ jvalue ) {
// examine $class and $jvalue to figure out what class to use...
return ' DateTime ' ;
};
$ jm = new JsonMapper ();
$ jm -> classMap [ ' Foo ' ] = $ mapper ;
$ jm -> map (...);
JsonMapper löst eine Ausnahme aus, wenn eine JSON-Eigenschaft null
ist, es sei denn, die PHP-Klasseneigenschaft hat einen nullfähigen Typ – z. B. Contact|null
oder ?Contact
.
Wenn Ihre API viele Felder enthält, die möglicherweise null
sind, und Sie nicht alle Ihre Typdefinitionen auf NULL setzen möchten, legen Sie Folgendes fest:
$ jm -> bStrictNullTypes = false ;
Seit Version 5.0.0 führen null
in Arrays zu einer JsonMapper_Exception
es sei denn, der Typ ist nullbar – z. B. array[?string]
oder array[string|null]
.
Um das vorherige Verhalten wiederherzustellen (Nullwerte sind auch dann zulässig, wenn dies nicht deklariert ist), legen Sie Folgendes fest:
$ jm -> bStrictNullTypesInArrays = false ;
setLogger()
Methode von JsonMapper unterstützt alle PSR-3-kompatiblen Logger-Instanzen.
Ereignisse, die protokolliert werden:
Während der Entwicklung ändern sich APIs häufig. Um über solche Änderungen benachrichtigt zu werden, kann JsonMapper so konfiguriert werden, dass bei fehlenden oder noch unbekannten Daten Ausnahmen ausgelöst werden.
Wenn JsonMapper Eigenschaften in den JSON-Daten erkennt, die nicht in der PHP-Klasse definiert sind, können Sie eine Ausnahme auslösen lassen, indem Sie $bExceptionOnUndefinedProperty
festlegen:
$ jm = new JsonMapper ();
$ jm -> bExceptionOnUndefinedProperty = true ;
$ jm -> map (...);
Sie können diese Eigenschaften auch selbst verwalten, indem Sie einen Callable auf $undefinedPropertyHandler
setzen:
/**
* Handle undefined properties during JsonMapper::map()
*
* @param object $object Object that is being filled
* @param string $propName Name of the unknown JSON property
* @param mixed $jsonValue JSON value of the property
*
* @return void
*/
function setUndefinedProperty ( $ object , $ propName , $ jsonValue )
{
$ object ->{ ' UNDEF ' . $ propName } = $ jsonValue ;
}
$ jm = new JsonMapper ();
$ jm -> undefinedPropertyHandler = ' setUndefinedProperty ' ;
$ jm -> map (...);
Oder wenn Sie JsonMapper den Setter für Sie übernehmen lassen möchten, können Sie eine Zeichenfolge vom $undefinedPropertyHandler
zurückgeben, die als Eigenschaftsname verwendet wird.
/**
* Handle undefined properties during JsonMapper::map()
*
* @param object $object Object that is being filled
* @param string $propName Name of the unknown JSON property
* @param mixed $jsonValue JSON value of the property
*
* @return void
*/
function fixPropName ( $ object , $ propName , $ jsonValue )
{
return ucfirst ( $ propName );
}
$ jm = new JsonMapper ();
$ jm -> undefinedPropertyHandler = ' fixPropName ' ;
$ jm -> map (...);
Notiz
Dies funktioniert nur, wenn $bStrictObjectTypeChecking aktiviert bleibt.
Eigenschaften in Ihren PHP-Klassen können als „erforderlich“ markiert werden, indem Sie @required
in ihren Dokumentblock einfügen:
/**
* @var string
* @required
*/
public $ someDatum ;
Wenn die JSON-Daten diese Eigenschaft nicht enthalten, löst JsonMapper eine JsonMapper_Exception
aus, wenn $bExceptionOnMissingData
aktiviert ist:
$ jm = new JsonMapper ();
$ jm -> bExceptionOnMissingData = true ;
$ jm -> map (...);
Die Option $bRemoveUndefinedAttributes
bewirkt, dass JsonMapper Eigenschaften aus dem endgültigen Objekt entfernt, wenn sie nicht in den JSON-Daten enthalten waren:
$ jm = new JsonMapper ();
$ jm -> bRemoveUndefinedAttributes = true ;
$ jm -> map (...);
Sie können die Zuordnung zu privaten und geschützten Eigenschaften und Setter-Methoden zulassen, indem Sie $bIgnoreVisibility
auf true setzen:
$ jm = new JsonMapper ();
$ jm -> bIgnoreVisibility = true ;
$ jm -> map (...);
Wenn der Typ einer Variablen eine Klasse ist und JSON-Daten ein einfacher Typ wie string
sind, kann JsonMapper diesen Wert an den Konstruktor der Klasse übergeben, wenn er entsprechend konfiguriert ist:
$ jm = new JsonMapper ();
$ jm -> bStrictObjectTypeChecking = false ;
$ jm -> map (...);
Dies kann verwendet werden, um DateTime-Objekte automatisch aus Datumszeichenfolgen zu initialisieren.
Das Deaktivieren dieser strengen Objekttypprüfungen kann jedoch zu Problemen führen:
@required
-Eigenschaften werden nicht gefülltNotiz
Der Standardwert wurde in Version 5 von false
auf true
geändert, um die Sicherheit zu erhöhen.
Jetzt müssen Sie sich anmelden, wenn Sie einfache Typen an den Klassenkonstruktor übergeben möchten.
map()
Möglicherweise möchten Sie Array-Daten an map()
übergeben, die Sie durch den Aufruf erhalten haben
json_decode ( $ jsonString , true )
Standardmäßig löst JsonMapper eine Ausnahme aus, da map()
ein Objekt als ersten Parameter erfordert. Sie können dies umgehen, indem Sie $bEnforceMapType
auf false
setzen:
$ jm = new JsonMapper ();
$ jm -> bEnforceMapType = false ;
$ jm -> map (...);
JsonMapper kann eine benutzerdefinierte Methode direkt für jedes Objekt aufrufen, nachdem die Zuordnung abgeschlossen ist:
$ jm = new JsonMapper ();
$ jm -> postMappingMethod = ' afterMapping ' ;
$ jm -> map (...);
Jetzt wird afterMapping()
für jedes zugeordnete Objekt aufgerufen (sofern die Klasse über diese Methode verfügt).
Sie können dem Post-Mapping-Callback zusätzliche Argumente übergeben:
$ jm = new JsonMapper ();
$ jm -> postMappingMethod = ' afterMapping ' ;
$ jm -> postMappingMethodArguments = [ 23 , ' foo ' ];
$ jm -> map (...);
Über Composer von Packagist:
$ Composer erfordert Netresearch/Jsonmapper
Alternativen
JsonMapper ist unter OSL 3.0 lizenziert.
JsonMapper folgt den PEAR-Codierungsstandards.
Christian Weiske, cweiske.de