PHPはどのように科学的にjson_Encodeクラスオブジェクトデータ


実はこの文章はpythonに対してもっとすべきです.pythonはデフォルトでjsonがクラスオブジェクトをシーケンス化するとき、エラーを報告するからです.
しかし、phpの私たちはもっと多いと思います.そして、主に一つの思想を伝えたいと思っています.思想には国境がありません.
ではPHPで粟をあげてみましょう
1. json_Encode対クラスの処理
まず、セグメントテストコードを見てみましょう.
class A {
    public $a;
    public $b;
    private $c;
    static public $d;
    static protected $e;
    
    public function __construct(){
        $this->a = 1;
        $this->b = 2;
        $this->c = 3;
        self::$d = 4;
        self::$e = 5;
    }
}
$obj = new A;
echo json_encode($obj);

出力結果:
>> {"a":1,"b":2}

get_object_vars()装飾下出力コード:
echo json_encode( get_object_vars($obj) );

出力結果は次のとおりです.
>> {"a":1,"b":2}

以上、私たちは結論を下すことができます:json_Encode()は、オブジェクトをシーケンス化する場合、(get_object_vars)オブジェクトの共通属性を抽出して配列に結合し、シーケンス化します.private、protected、staticプロパティ、クラスメソッドは破棄されます.
1.1属性宣言を変更せずにJSONシーケンス化のフィールドをカスタマイズしますか?
はい、実操の中で本当に出会った問題が来ました.
class A {
    public $a;
    public $b;
    public function __construct($a, $b){
        $this->a = $a;
        $this->b = $b;
    }
    public function sum(){
        return $this->a + $this->b;
    }
}
$obj = new A(1,2);

json_encodeは、{「a」:1,「b」:2,「sum」:3}のようなsumフィールドを得る.
どうやって実現しますか?子供靴たちはPHPの類に魔法の方法があることを覚えなければなりません_オブジェクトを文字列に変換しようとすると、関数が呼び出され、所望の文字列が得られるtoString()です.
class B{
    public function __toString(){
        return "     B";
    }
}

echo(new B); // such as print(), strval(), ...
>>      B

もしあなたがPython coderであれば、pythonの魔法の方法は本当に柄が多すぎないので、不思議ではありません.
では、不思議な方法はありませんか.json()カスタムJSONシーケンス化を実現しましょうか?
しばらくありませんが、PHPの作者たちはとっくにこのような需要を受けて、解決策を作っています.見てください.
1.2インタフェースJsonSerializable::jsonSerialize()、了解!
システムサポート:(PHP 5>=5.4.0、PHP 7)はどのように使いますか?コードを見てください:
// 1.      JsonSerializable  
class A implements JsonSerializable {
    public $a;
    public $b;
    public function __construct($a, $b){
        $this->a = $a;
        $this->b = $b;
    }
    public function sum(){
        return $this->a + $this->b;
    }
    
    // 2.   jsonSerialize()   
    public function jsonSerialize(){
        //          
        return array(
            "a"=>$this->a,
            "b"=>$this->b,
            "sum"=>$this->sum()
        );
    }
}

$obj = new A(1,2);
echo json_encode($obj);

これで満足したでしょう.見てください.
>> {"a":1,"b":2,"sum":3}

クラスがjsonSerialize()を実装すると、json_encode(object)はget_の代わりにjsonSerialize()を使用します.object_vars()は、シーケンス化が必要なフィールド情報を得る.
1.3 DateTimeなどのシステムオブジェクトの処理方法
これらのクラスはシステム定義であるため,上記のインタフェースを追加できないことを示し,もう1つのサブクラスを定義して互換性を作ることも作業量が少ないという問題である.
echo json_encode(date_create());
>> {"date":"2019-12-17 07:49:24.086271", "timezone_type":3, "timezone":"UTC"}

しかし、ビジネスニーズのため、すべてのインタフェースで返される時間オブジェクトは、YYYY-MM-DD HH:MM:SSというフォーマット文字列に統一したいだけです.
そこで、フレームワークを適用する際には
2.自分のjsonをカスタマイズするEncodeメソッド
json_encode()は明らかに書き換えられないので、私は自分で方法を定義します.
2.1 my_json_encode()
その後、プロジェクト全体でjson_を検索します.encodeをmyに置き換えるjson_encodeは迅速に解決できます.
完全互換性を定義するjson_Encode()パラメータの方法
function my_json_encode($value, $options=0, $depth=512){
    $value = my_json_handle($value);
    return json_encode($value, $options, $depth);
}

コードには、パーソナライズされたシーケンス化処理方法が定義されています.
2.2 my_json_handle($value)
ここでは、任意のデータ型をJSONシーケンス化する方法を定義できます.
function my_json_handle($mixed, $depth=512, $recursion=1){
    // recursion limited.
    if($recursion >= $depth){ 
        return strval($mixed);
    }
    //          
    if(is_object($mixed)){
        $klass = get_class($mixed);
        // DateTime   
        if(in_array($klass, array("DateTime", "DateTimeImmutable")){
            return date_format($mixed, 'Y-m-d H:i:s');
        }
        //                   ...
        
        // __json()        .
        //      __json() jsonSerialize()      
        //       implements JsonSerializable
        if(method_exists($mixed, "__json")){
            $mixed = $mixed->__json();
        }
        
        //      jsonSerialize()    .
        if(method_exists($mixed, "jsonSerialize")){
            $mixed = $mixed->jsonSerialize();
        }

        //   get_object_vars()      
        if(is_object($mixed)){
            $mixed = get_object_vars($mixed);
        }
    }
    //         
    if(is_array($mixed)){
        foreach($mixed as $k=>$v){
            //       +1
            $mixed[$k] = my_json_handle($v, $depth, $recursion+1);
        }
    }
    return $mixed;
}

2.3我々の成果をテストする
//      implements JsonSerializable
class A {
    public $a;
    public $b;
    public $datetime;
    public function __construct($a, $b){
        $this->a = $a;
        $this->b = $b;
        $this->datetime = date_create("now",  new DateTimeZone('+0800'));
    }
    public function sum(){
        return $this->a + $this->b;
    }
    
    //      __json()   
    public function __json(){
        //          
        return array(
            "datetime"=>$this->datetime,
            "timestamp"=>$this->datetime->getTimestamp(),
            "sum"=>$this->sum()
        );
    }
}

echo my_json_encode(new A(1,2));
>> {"datetime":"2019-12-17 16:34:15", "timestamp":1576571655, "sum":3}

プロジェクトで=ORMフレームワークを使用し、大量のModelを定義し、jsonでこれらのModelをシーケンス化すると、この文章は実用的であることがわかります.あなたのインタフェースの出力フィールドを規範化することができて、ajaxインタフェースはいつも多くのフィールドあるいは少ないフィールドではありませんて、同じフィールドは文字列の1つでまた整型の各種の気まずいことです.
後記
PHPのスカラー(Scalar Data)は、float浮動小数点データのみがjson_Encodeでオーバーフローが発生する可能性があります.PHP 7はserializeを構成することができます.precision=-1で解決します.
また、ブラウザ側ではロング整数型はサポートされていない可能性があり、注文IDのビット数が比較的長い場合(32 bitより大きい整数)、ブラウザ側JSONがある.parse()の場合はデータを短くしやすく,バックグラウンド処理では文字列に変換できる.