JSON Web サービスから取得したデータを取得し、独自のモデル クラスを使用して、それらをネストされたオブジェクトと配列に変換します。
基本オブジェクトから開始して、JSON データをクラス プロパティにマッピングし、それらを正しい単純な型またはオブジェクトに変換します。
これは、PHP のSoapClient
が提供するネイティブ SOAP パラメーター マッピングに似ていますが、JSON 用です。スキーマには依存せず、PHP クラス定義のみに依存します。
型検出は、クラス プロパティの型宣言と@var
docblock アノテーション、およびセッター メソッドの型ヒントを解析することによって機能します。
JSON 固有のコードを追加してモデル クラスを変更する必要はありません。既存の docblock を解析することで自動的に機能します。
このライブラリには依存関係はありません。
キーワード: デシリアライゼーション、ハイドレーション
コンテンツ
map()
に渡すモデルクラスは手作業で記述する必要がある
JsonMapper はスキーマ情報 (json-schema など) に依存しないため、モデル クラスを自動的に生成することはできません。
netresearch/jsonmapper
をインストールするJsonMapper
オブジェクトインスタンスを作成するmap
またはmapArray
メソッドを呼び出します。通常のオブジェクトをマッピングします。
<?php
require ' autoload.php ' ;
$ mapper = new JsonMapper ();
$ contactObject = $ mapper -> map ( $ jsonContact , new Contact ());
// or as classname
$ contactObject = $ mapper -> map ( $ jsonContact , Contact::class);
オブジェクトの配列をマップします。
<?php
require ' autoload.php ' ;
$ mapper = new JsonMapper ();
$ contactsArray = $ mapper -> mapArray (
$ jsonContacts , array (), ' Contact '
);
array()
の代わりに、 ArrayObject
および派生クラス、さらにArrayAccess
実装するクラスを使用することもできます。
アドレス帳 Web サービスからの JSON:
{
"name" : "Sheldon Cooper" ,
"address" : {
"street" : "2311 N. Los Robles Avenue" ,
"city" : "Pasadena"
}
}
ローカルのContact
クラス:
<?php
class Contact
{
/**
* Full name
*/
public string $ name ;
public ? Address $ address ;
}
ローカルのAddress
クラス:
<?php
class Address
{
public $ street ;
public $ city ;
public function getGeoCoords ()
{
//do something with $street and $city
}
}
アプリケーションコード:
<?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
、いくつかのソースを使用して、次の順序でプロパティの正しいタイプを検出します。
Setter メソッド ( set
+ ucwords($propertyname)
)
アンダースコア「 _
」とハイフン「 -
」を使用すると、次の文字が大文字になります。プロパティfoo_bar-baz
セッター メソッドsetFooBarBaz
につながります。
メソッド シグネチャに型ヒントがある場合は、その型が使用されます。
public function setperson(Contact $person) {...}
メソッドの docblock は@param $type
アノテーションについて検査されます。
/** * @param Contact $person このアプリケーションの主な連絡先 */ パブリック関数 setPerson($person) {...}
型が検出できなかった場合は、プレーンな JSON 値が setter メソッドに渡されます。
クラスプロパティタイプ (PHP 7.4 以降):
公開連絡先 $person;
コンストラクター プロパティのプロモーション タイプ (PHP 8.0 以降):
public function __construct(protected Contact $person) {}
クラスプロパティの@var $type
docblock アノテーション:
/** * @var myapplicationmodelContact */ パブリック $person;
プロパティを直接使用するにはパブリックである必要があります。 $bIgnoreVisibility を使用して、保護されたプライベート プロパティを利用することもできます。
型が検出できなかった場合、プロパティはプレーンな JSON 値セットを取得します。
プロパティが見つからない場合、JsonMapper は大文字と小文字を区別しない方法でプロパティを検索しようとします。 JSON プロパティisempty
は、PHP プロパティisEmpty
にマップされます。
注記
型が機能するには、完全修飾名前空間を提供する必要があります。相対クラス名は、存在する可能性のあるインポートを尊重せず、現在のクラスの名前空間のコンテキストで評価されます。
PHP はリフレクションを介したインポートを提供しません。コメント テキストには、その型のリテラル テキストのみが含まれます。パフォーマンス上の理由から、JsonMapper はインポートを検出して展開するために独自にソース コードを解析しません。
単純なタイプ
string
bool
、 boolean
int
、 integer
double
、 float
array
object
mixed
クラス名(名前空間ありまたはなし)
Contact
- JSON 値がnull
場合、例外がスローされます単純な型とクラス名の配列:
int[]
Contact[]
多次元配列:
int[][]
TreeDeePixel[][][]
単純な型とクラス名の ArrayObject:
ContactList[Contact]
NumberList[int]
名前空間の有無にかかわらず、バックアップされた列挙型
Suit:string|Suit:int
- JSON 値が列挙型に存在しない場合、例外がスローされます。
Null 許容型:
int|null
または?int
- JSON の値がnull
の場合はnull
になり、それ以外の場合は整数になりますContact|null
または?Contact
- JSON の値がnull
の場合はnull
になり、それ以外の場合はContact
型のオブジェクトになります。ArrayObject と拡張クラスは配列として扱われます。
型のない変数、または型がmixed
変数は、変換せずに JSON 値セットを直接取得します。
詳細については、phpdoc の型ドキュメントを参照してください。
注記
この機能は、バージョン 5 以降、セキュリティ上の理由からデフォルトで無効になっています。詳細については、$bStrictObjectTypeChecking を参照してください。
オブジェクトが作成されるが、JSON に単純な型 (string、float、boolean など) のみが含まれる場合、この値はクラスのコンストラクターに渡されます。例:
PHPコード:
public DateTime $ date ;
JSON:
{ "date" : "2014-05-15" }
これによりnew DateTime('2014-05-15')
が呼び出されます。
変数が抽象クラスまたはインターフェイスのオブジェクトとして定義されている場合、JsonMapper は通常、それらを直接インスタンス化しようとしてクラッシュします。
JsonMapper の$classMap
プロパティを使用すると、代わりにどのクラスがインスタンス化されるかを指定できます。
$ jm = new JsonMapper ();
$ jm -> classMap [ ' Foo ' ] = ' Bar ' ;
$ jm -> map (...);
これにより、変数がFoo
型として定義されている場合、 Bar
型のオブジェクトが作成されます。
実際の実装クラスを動的に決定する必要がある場合 (共用体の場合など)、呼び出し可能オブジェクトを使用することもできます。マップされたクラス (以下の例では「Foo」) と Json データがパラメーターとして呼び出しに渡されます。
$ 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 は、JSON プロパティがnull
の場合、PHP クラス プロパティが null 許容型 ( Contact|null
または?Contact
など) を持っていない限り、例外をスローします。
API にnull
の可能性があるフィールドが多数含まれており、すべての型定義を null 可能にしたくない場合は、次のように設定します。
$ jm -> bStrictNullTypes = false ;
バージョン 5.0.0 以降、型が null 許容でない限り、配列内のnull
値はJsonMapper_Exception
を引き起こします (例: array[?string]
またはarray[string|null]
。
以前の動作を戻すには (宣言されていない場合でも null を許可します)、次のように設定します。
$ jm -> bStrictNullTypesInArrays = false ;
JsonMapper のsetLogger()
メソッドは、すべての PSR-3 互換ロガー インスタンスをサポートします。
ログに記録されるイベント:
開発中に API が変更されることがよくあります。このような変更に関する通知を受け取るために、データが欠落しているかまだ不明な場合に例外をスローするように JsonMapper を構成できます。
JsonMapper が PHP クラスで定義されていない JSON データ内のプロパティを検出した場合、 $bExceptionOnUndefinedProperty
設定することで例外をスローさせることができます。
$ jm = new JsonMapper ();
$ jm -> bExceptionOnUndefinedProperty = true ;
$ jm -> map (...);
呼び出し可能オブジェクトを$undefinedPropertyHandler
に設定することで、これらのプロパティを自分で処理することも選択できます。
/**
* 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 (...);
または、JsonMapper にセッターを処理させる場合は、プロパティ名として使用される文字列を$undefinedPropertyHandler
から返すことができます。
/**
* 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 (...);
注記
これは、$bStrictObjectTypeChecking が有効になっている場合にのみ機能します。
PHP クラスのプロパティは、docblock に@required
入れることで「必須」としてマークできます。
/**
* @var string
* @required
*/
public $ someDatum ;
JSON データにこのプロパティが含まれていない場合、 $bExceptionOnMissingData
がアクティブ化されると、JsonMapper はJsonMapper_Exception
をスローします。
$ jm = new JsonMapper ();
$ jm -> bExceptionOnMissingData = true ;
$ jm -> map (...);
オプション$bRemoveUndefinedAttributes
使用すると、プロパティが JSON データに存在しない場合、JsonMapper は最終オブジェクトからプロパティを削除します。
$ jm = new JsonMapper ();
$ jm -> bRemoveUndefinedAttributes = true ;
$ jm -> map (...);
$bIgnoreVisibility
を true に設定することで、プライベートおよび保護されたプロパティおよびセッター メソッドへのマッピングを許可できます。
$ jm = new JsonMapper ();
$ jm -> bIgnoreVisibility = true ;
$ jm -> map (...);
変数の型がクラスであり、JSON データがstring
ような単純な型である場合、JsonMapper は、そのように構成されていると、この値をクラスのコンストラクターに渡すことができます。
$ jm = new JsonMapper ();
$ jm -> bStrictObjectTypeChecking = false ;
$ jm -> map (...);
これを使用して、日付文字列から DateTime オブジェクトを自動的に初期化できます。
ただし、この厳密なオブジェクト タイプ チェックを無効にすると、問題が発生する可能性があります。
@required
プロパティは入力されません注記
バージョン 5 では、セキュリティを強化するためにデフォルト値がfalse
からtrue
に変更されました。
単純な型をクラス コンストラクターに渡したい場合は、オプトインする必要があります。
map()
に渡す呼び出して取得した配列データをmap()
に渡すこともできます。
json_decode ( $ jsonString , true )
デフォルトでは、 map()
最初のパラメータとしてオブジェクトを必要とするため、JsonMapper は例外をスローします。 $bEnforceMapType
false
に設定することでこれを回避できます。
$ jm = new JsonMapper ();
$ jm -> bEnforceMapType = false ;
$ jm -> map (...);
JsonMapper は、マッピングが完了した後、各オブジェクトでカスタム メソッドを直接呼び出すことができます。
$ jm = new JsonMapper ();
$ jm -> postMappingMethod = ' afterMapping ' ;
$ jm -> map (...);
これで、マップされた各オブジェクトに対してafterMapping()
が呼び出されます (クラスにそのメソッドがある場合)。
マッピング後のコールバックに追加の引数を渡すこともできます。
$ jm = new JsonMapper ();
$ jm -> postMappingMethod = ' afterMapping ' ;
$ jm -> postMappingMethodArguments = [ 23 , ' foo ' ];
$ jm -> map (...);
Packagist の Composer 経由:
$コンポーザーにはnetresearch/jsonmapperが必要です
代替案
JsonMapper は OSL 3.0 に基づいてライセンスされています。
JsonMapper は PEAR コーディング標準に従います。
クリスチャン・ワイスク、cweiske.de