ixbox / php-superjson
PHP implementation of superjson with compatibility for Node.js superjson
v0.1.0
2026-10-21 11:44 UTC
Requires
- php: ^8.2
Requires (Dev)
- pestphp/pest: ^3.8
Suggests
- ext-bcmath: Alternative for BigInt support
- ext-gmp: For better BigInt support (recommended)
Provides
None
Conflicts
None
Replaces
None
README
Node.jsのsuperjsonとの互換性を持つPHPライブラリです。
特徴
- 型安全: PHP 8.2+の厳密な型システムを活用
- PHP → JS: PHPの値をsuperjson形式で出力し、JS側の
superjson.parse()でDate、BigInt、Set、Map、Error、URL、RegExp、undefinedとして復元できる - JS → PHP: superjson形式をパースし、DateとBigIntを復元する(Set、Mapなどの復元は未実装)
- プラガブル設計: BigIntハンドラーをGMP/BCMath/Stringから選択可能
- 互換性の検証: JS版superjson 2.xで実際にparseするテストをCIで実行
要件
- PHP 8.2以上
- オプション:
ext-gmpまたはext-bcmath(BigInt型のサポートに推奨)
インストール
composer require ixbox/php-superjson
基本的な使い方
PHPからJavaScriptへ渡す(stringify)
use Superjson\Superjson; use Superjson\Type\JsMap; use Superjson\Type\JsSet; use Superjson\Type\Undefined; $json = Superjson::stringify([ 'createdAt' => new DateTimeImmutable('2024-01-01T09:00:00+09:00'), 'tags' => new JsSet(['php', 'js']), 'scores' => JsMap::fromArray(['alice' => 10]), 'deletedAt' => Undefined::value(), ]);
// JavaScript側 import superjson from 'superjson'; const data = superjson.parse(json); data.createdAt; // Date data.tags; // Set { 'php', 'js' } data.scores; // Map { 'alice' => 10 } data.deletedAt; // undefined
Superjson::serialize()はjson_encodeする前の{json, meta}を配列で返します。
型の対応(PHP → JS)
| PHPの値 | JSでの値 | 備考 |
|---|---|---|
string / bool / null |
string / boolean / null |
nullToUndefined: trueならnullはundefined |
int |
number |
±2^53-1を超えると例外。bigintで送るにはJsBigIntかGMPを使う |
float |
number |
NAN、INF、-INF、-0.0もそのまま復元される |
連番の配列([]を含む) |
Array |
|
連想配列 / stdClass |
Object |
|
DateTimeInterface |
Date |
UTC・ミリ秒精度(マイクロ秒は切り捨て) |
GMP / BcMath\Number(整数) / JsBigInt |
bigint |
|
Throwable |
Error |
nameは短いクラス名。getPrevious()はcauseになる。スタックトレースは送らない |
JsSet |
Set |
|
JsMap |
Map |
キーにも任意の値を使える |
Undefined::value() |
undefined |
|
JsRegExp |
RegExp |
パターンはJavaScriptの構文で書く |
JsUrl |
URL |
|
BackedEnum |
その値 | |
JsonSerializable |
jsonSerialize()の結果 |
結果の中の特殊型も変換される |
| その他のオブジェクト | Object |
json_encodeと同じく公開プロパティのみ |
クロージャ、Pure enum、リソース、循環参照は例外(SuperjsonException)になります。同じオブジェクトを複数箇所に置くことはできますが、JS側では別々のオブジェクトになります(referentialEqualitiesは出力しません)。
パース(JavaScriptからPHPへ)
use Superjson\Superjson; $json = '{"json":{"name":"Alice","age":30},"meta":{"v":1}}'; $data = Superjson::parse($json); echo $data->name; // "Alice"
特殊型のパース
$json = '{ "json": { "created": "2024-01-01T00:00:00.000Z", "count": "9007199254741992" }, "meta": { "values": { "created": ["Date"], "count": ["bigint"] }, "v": 1 } }'; $result = Superjson::parse($json); // DateTimeImmutableオブジェクト var_dump($result->created instanceof DateTimeImmutable); // true // BigInt(GMP拡張がある場合はGMPオブジェクト) var_dump($result->count);
設定オプション
BigIntハンドラー
use Superjson\Superjson; use Superjson\SuperjsonConfig; use Superjson\Handler\GMPBigIntHandler; $config = new SuperjsonConfig( bigIntHandler: new GMPBigIntHandler() ); $result = Superjson::parse($json, $config);
strictBigIntモード
GMP/BCMath拡張がない場合の動作を制御します:
// デフォルト(false): 文字列にフォールバック $config = new SuperjsonConfig(strictBigInt: false); // strict(true): 例外を投げる $config = new SuperjsonConfig(strictBigInt: true);
パースで復元される型(JS → PHP)
| JavaScript型 | PHP型 | 備考 |
|---|---|---|
string |
string |
|
number |
int|float |
|
boolean |
bool |
|
null |
null |
|
Array |
array |
数値インデックス配列 |
Object |
stdClass |
|
bigint |
string|GMP|BcMath\Number |
プラガブルハンドラー(PHP 8.4以上のBCMathはBcMath\Number) |
Date |
DateTimeImmutable |
undefined、Set、Map、Error、URL、RegExpの復元は未実装です(Phase 3)。現在はjson部分の値がそのまま返ります。
テスト
composer test
JS版superjsonとの互換性テストを動かすには、Node.jsを用意して依存を入れてください。入れていない場合、このテストはスキップされます。
npm install --prefix tests/Compat
composer test
ライセンス
MIT