ホームページ >ウェブフロントエンド >jsチュートリアル >楽しみと利益のためのJavaScriptのハッキング:パートI

楽しみと利益のためのJavaScriptのハッキング:パートI

William Shakespeare
William Shakespeareオリジナル
2025-03-10 00:29:10353ブラウズ

楽しみと利益のためのJavaScriptのハッキング:パートI

JavaScriptは、過去数年間でWeb開発と設計の経験の大部分になりました。これにより、鈍い静的なページをスプルシングし、ページリフレッシュを避け、インターフェイスエンジニアリングの驚くべき偉業を達成することができます。これは、HTMLとCSSだけを使用して不可能なことです。もちろん、AjaxとDom Scriptingは現在、ミルの実行と見なされており、Webサイトを構築する際のすべてのWeb開発者のツールキットの一部です。しかし、どこまで押すことができますか?これは、豊富な出力メカニズムを備えた強力でオブジェクト指向の言語なので、ポップアップウィンドウを起動する以上のものに使用できます。

では、そのような質問に直面したとき、自尊心のあるオタクは何をしますか?もちろん、彼らは2Dのサイドスクロールプラットフォームゲームを書きます!

この2部構成のシリーズでは、十分なHTML、CSS、およびJavaScriptを学習して、独自のJavaScriptプラットフォームゲームを構築できるようになります。単に私が知っていることだったからといって、プロトタイプJavaScriptライブラリを例で使用しました。

楽しいものに到達する前に、ブラウザをだまして8ビットゲームコンソールだと思うようにする高度なJavaScriptテクニックのいくつかを実行する必要があります。

キーテイクアウト

    JavaScriptは、動的な相互作用とインターフェイスの改善を可能にし、静的HTML/CSS機能を超えて移動することによりWeb開発を強化します。
  • プロトタイプJavaScriptライブラリは、JavaScriptのクラスの作成と継承を簡素化し、複雑な機能の構築を容易にします。
  • JavaScriptのプロトタイプ継承は、古典的なOOP継承に対するネイティブサポートの欠如にもかかわらず、洗練されたオブジェクト指向パターンを作成するためにエミュレートできます。 アニメーションにJavaScriptを使用するには、CSSプロパティを操作し、タイマーを使用してフレームの変更を処理し、スムーズな視覚的遷移を確保することが含まれます。 JavaScriptでのイベント処理は、ブラウザの矛盾を処理し、開発プロセスを合理化するためにプロトタイプなどのライブラリによって提供されるインタラクティブアプリケーションにとって重要です。
  • 建設101
  • JavaScript(JS)は、プロトタイプ化されたオブジェクト指向プログラミング(OOP)言語です。これは、コード内のオブジェクトとして、ビデオゲーム文字などの構成要素を表すことができることを意味します。 JSクラスの構築は、より伝統的なOOP言語のいくつかに精通している場合、少し奇妙に思えるかもしれません。まず第一に、すべてがルビーのようにオブジェクトであるのではなく、JSのすべてがデータ型です。これらのデータ型には、プロトタイプと呼ばれる内部データ型があり、データ型にどのように動作するかを伝えます。したがって、クラスをそのような方法で定義する必要があります:
    1. それがクラス

    2. であることを知っています
    3. は作成して、定義された初期状態に初期化できます

    新しいクラスを構築するいくつかのJSコードを見て、新しいオブジェクトを作成しましょう。

    このコードをめちゃくちゃに見ると、3つのプロパティ(要素、x、y)と1つの関数があるWalkspriteと呼ばれる新しいクラスを構築したことが示されています。オブジェクトの新しいバージョンをインスタンス化して
    // Declare the class <br>
    function WalkingSprite(element, x, y) { <br>
      this.x = x; <br>
      this.y = y; <br>
      this.element = element; <br>
    } <br>
     <br>
    WalkingSprite.prototype = { <br>
      x: 0, <br>
      y: 0, <br>
      element: null, <br>
      <br>
      walk: function(direction) { <br>
        this.x += direction; <br>
      } <br>
    } <br>
     <br>
    koopa = new WalkingSprite(null, 10, 10); <br>
    koopa.walk(20); <br>
    alert(koopa.x + "," + koopa.y);
    をインスタンス化して、それをウォーク関数と呼ぶと、Koopaオブジェクトは座標ポイント(20、30)になります。この方法でクラスを宣言することは少し面倒です。クラスを作成して、プロトタイプを更新する必要があります。ありがたいことに、プロトタイプ(ライブラリ)は、それをclass.createと呼ばれる便利な関数にカプセル化しました。上記のコードはこれになります:

    クラスの継承を操作

    var WalkingSprite = Class.create({ <br>
      x: 0, <br>
      y: 0, <br>
      element: null, <br>
     <br>
      initialize: function(element, x, y) { <br>
        this.element = element; <br>
        this.x = x; <br>
        this.y = y; <br>
      }, <br>
     <br>
      walk: function(steps) { <br>
        this.x += steps; <br>
      } <br>
    }); <br>
     <br>
    koopa = new WalkingSprite(null, 10, 10); <br>
    koopa.walk(20); <br>
    alert(koopa.x + "," + koopa.y);
    OOPのもう1つの基本的なコンポーネントは、継承の概念です。基本的に、特定の変数と関数を持つ基本クラスがある場合、クラスが

    継承これらの変数と関数を継承するすべてのクラスがある場合。その後、追加の機能を追加し、それらの関数をオーバーライドして何か他のことを行うことさえできます。これは、私たちのゲームで本当に役立つ可能性があります。なぜなら、私たちのキャラクターはすべて一般的な属性を示す可能性があるからです。彼らはすべて画面を歩き回ることができるかもしれませんが、ジャンプできるキャラクターのタイプは1つだけです。相続の完璧な候補者のように聞こえます。

    残念ながら、JavaScriptは継承をネイティブにサポートしていません。それで、なぜ私はそれについてあなたに伝える最後の段落を無駄にしたのですか?さて、少しの巧妙なことで、JavaScriptのクラス継承をエミュレートできます。

    JavaScript(クラスの関数を含む)のすべてが変数であるため、他の変数に値を割り当てることができます。したがって、継承が瞬時に何であるかを考える場合、それをエミュレートするために必要なことは、親クラスから子のクラスにプロパティと機能をコピーすることだけです。上記で作成したクラスから継承したい場合は、これを行うことができます。

    コードを実行すると、2つのプロパティと1つの関数がある新しいクラスと、1つの新しい関数、ジャンプがあります。唯一のことは、このようにコーディングすることは実際には規模ではありません。 親クラスにアヒル機能を追加した場合はどうなりますか?すべての子供クラスを経て、関数の署名を追加する必要があります。もう一度、救助のプロトタイプ!以前に学んだClass.Create関数は、別のクラスを最初の引数として取ることができます。この提供されたクラスは親になり、私たちのためのすべてのプロパティと機能を動的に見つけ、それらを子のクラスに自動的に注入します。したがって、上記は次のようになります
    // Declare the class <br>
    function WalkingSprite(element, x, y) { <br>
      this.x = x; <br>
      this.y = y; <br>
      this.element = element; <br>
    } <br>
     <br>
    WalkingSprite.prototype = { <br>
      x: 0, <br>
      y: 0, <br>
      element: null, <br>
      <br>
      walk: function(direction) { <br>
        this.x += direction; <br>
      } <br>
    } <br>
     <br>
    // Create the child class <br>
    JumpingAndWalkingSprite = WalkingSprite; <br>
    JumpingAndWalkingSprite.prototype = { <br>
      x: 0, <br>
      y: 0, <br>
      walk: WalkingSprite.prototype.walk <br>
      jump: function() { <br>
        y += 20; <br>
      } <br>
    }

    予想通り、新しいクラスには親クラスと同じプロパティがすべてあります!では、プロパティと機能を追加およびオーバーライドするのはどうでしょうか?これを手動で行う方法を上記で示しましたが、プロトタイプではclass.create:

    を使用して新しい機能を定義できます。
    // Declare the class <br>
    function WalkingSprite(element, x, y) { <br>
      this.x = x; <br>
      this.y = y; <br>
      this.element = element; <br>
    } <br>
     <br>
    WalkingSprite.prototype = { <br>
      x: 0, <br>
      y: 0, <br>
      element: null, <br>
      <br>
      walk: function(direction) { <br>
        this.x += direction; <br>
      } <br>
    } <br>
     <br>
    koopa = new WalkingSprite(null, 10, 10); <br>
    koopa.walk(20); <br>
    alert(koopa.x + "," + koopa.y);

    ここでは、ウォーク機能をオーバーライドし、ジャンプ機能を追加しました。ハングオン - トラックをバックアップしてください - その$ SUPER変数はどこからポップアップしましたか?良い質問!継承を使用する場合、関数の親クラスのバージョンを実行すると便利な場合があります。この場合、入力変数を2倍にし、この新しい値を親クラスに渡すことにより、当初の要求の2倍のキャラクターを歩きます。プロトタイプは、関数の署名の最初の引数として$ superを宣言する場合、$ super変数に親クラスの関数バージョンを提供します。これにより、オーバーライドバージョン内から関数の親バージョンを簡単に呼び出すことができます。新しいジャンプ関数には$ super変数がないことに気付くでしょう。使用していないので、供給する必要はありません。必要な場合は、関数署名の最初の引数として追加することができます。

    クラス名
    による動作の定義

    JavaScriptクラスが書かれていますが、特定のクラス名を与えるだけでHTML要素にWalkingSpliteオブジェクトになるように指示できたら、クールではないでしょうか? JavaScript 1.6では、document.getElementByClassName関数を使用して、特定のクラス名を持つすべてのDOM要素を簡単に見つけることができます。ただし、ほとんどのブラウザはまだバージョン1.6をサポートしていません。幸いなことに、プロトタイプは$$関数を提供します。CSSセレクターを渡すと、すべての一致する要素の配列が返されます。

    次のコードをご覧ください:

    var WalkingSprite = Class.create({ <br>
      x: 0, <br>
      y: 0, <br>
      element: null, <br>
     <br>
      initialize: function(element, x, y) { <br>
        this.element = element; <br>
        this.x = x; <br>
        this.y = y; <br>
      }, <br>
     <br>
      walk: function(steps) { <br>
        this.x += steps; <br>
      } <br>
    }); <br>
     <br>
    koopa = new WalkingSprite(null, 10, 10); <br>
    koopa.walk(20); <br>
    alert(koopa.x + "," + koopa.y);

    最初に、WalkingSpriteクラスを作成し、次にWalkingSpriteクラスを親として使用するKoopasPriteクラスを作成します。次に、クラス名「koopa」を持つドキュメント内のすべての要素を選択して、Koopaspriteオブジェクトの配列を作成します。

    次に、対応するDOM要素への参照があるKoopaspriteオブジェクトの配列があります(これは後で重要になります)。ここでやったことは、

    控えめなJavaScript の基礎です。関心のあるHTML要素を動的に見つけたので、イベント(OnclickやOnfocusなど)をバインドしたり、それらを停止したり、消えたりすることができます!

    モーション写真を作成
    テキスト主導のアドベンチャーゲームを書いていないので、キャラクターをアニメーション化する方法が必要です。これは、それらを画面の周りに移動するだけでなく、後でカバーされます。また、キャラクターが歩いたり、ジャンプしたり、ダッキングしているように見えるようにすることができればいいでしょう。これを行うには、古いCSSトリック:バックグラウンドポジションハックを呼び出します。

    アイデアはシンプルです。アニメーションのフレームを形成する画像のリボンを作成し、左右のピクセルの数を左右にシフトしてサイクリングします。これが背景画像の例です

    楽しみと利益のためのJavaScriptのハッキング:パートI

    ご覧のとおり、1つの画像に12フレームがあり、それぞれ48ピクセル離れています。クラスのマリオのdivがある場合、いくつかの異なるフレームのCSSは次のようになるかもしれません:

    // Declare the class <br>
    function WalkingSprite(element, x, y) { <br>
      this.x = x; <br>
      this.y = y; <br>
      this.element = element; <br>
    } <br>
     <br>
    WalkingSprite.prototype = { <br>
      x: 0, <br>
      y: 0, <br>
      element: null, <br>
      <br>
      walk: function(direction) { <br>
        this.x += direction; <br>
      } <br>
    } <br>
     <br>
    koopa = new WalkingSprite(null, 10, 10); <br>
    koopa.walk(20); <br>
    alert(koopa.x + "," + koopa.y);

    フリッカーレスロールオーバーを作成する前に、このテクニックを見たことがあるかもしれません。昔は、オンマウスオーバーイベントが発射されたときに画像タグのSRC値を変更するJavaScriptの小さなピースを使用して画像ロールオーバーエフェクトを作成します。しかし、初めてそれをしたとき、ブラウザはサーバーから画像をダウンロードする必要があり、しばしばちらつきを引き起こしました。画像をプリロードすることは可能でしたが、それはすべて少し不格好でした。優れたCSSテクニックにより、設計者はすべてのロールオーバー状態を1つの画像にロードし、以下を使用して別のCSSルールを作成して背景をシフトし、JavaScriptなしでスムーズな遷移を与えました。

    ただし、ゲームエンジンでは、JavaScriptを使用して背景画像の位置を変更します。 JSのバックグラウンド位置を設定するには、要素のstyle.backgroundposition属性を操作します。次のコードでは、マリオスプライトと呼ばれる新しいクラスが作成され、親のウォーキングスプライトクラスにレンダリング関数を追加します。この新しい機能は、時間遅延で繰り返し呼ばれ、2つのフレームを使用してマリオウォーキングをアニメーション化します。

    var WalkingSprite = Class.create({ <br>
      x: 0, <br>
      y: 0, <br>
      element: null, <br>
     <br>
      initialize: function(element, x, y) { <br>
        this.element = element; <br>
        this.x = x; <br>
        this.y = y; <br>
      }, <br>
     <br>
      walk: function(steps) { <br>
        this.x += steps; <br>
      } <br>
    }); <br>
     <br>
    koopa = new WalkingSprite(null, 10, 10); <br>
    koopa.walk(20); <br>
    alert(koopa.x + "," + koopa.y);
    タイマーを使用して

    明らかに、ゲーム全体で繰り返し呼び出されない場合、レンダリング関数はかなり役に立たない。 1秒に数回解雇されるようにするには、JavaScriptタイマーを使用する必要があります。タイマーには2つのタイプがあります。1つはタイマーの有効期限が切れた後に1回発射するものと、停止するように言うまで
    t
    ミリ秒ごとに繰り返し発射するものです。後者を実装して、setinterval関数を使用して実装します

    これにより、マリオは1秒あたり2回一歩踏み出します(500ミリ秒は0.5秒に等しくなります)。 SetIntervalは最初のパラメーターとして関数を必要とするため、Mario.Render関数を呼び出す匿名関数を作成する必要があります。

    後で私たちを噛むために戻ってくるJSの制限を説明する価値があるかもしれません:JavaScriptはマルチスレッドではありません。これは、2つのブロックのコードを同時に実行する方法がないことを意味します。 1ミリ秒の間隔を持つシングルショットタイマーを設定することにより、別のコードを割り当てることができます。これにより、ブラウザは次の機会にコールバック関数を強制しますが、中断されるコードの一部は停止し、中断機能が完了するまで実行を継続しません。したがって、1ミリ秒ごとにタイマーを設定して、機能が迅速に呼ばれることを保証するものではありません。ループについて話すとき、これの結果を確認します。
    // Declare the class <br>
    function WalkingSprite(element, x, y) { <br>
      this.x = x; <br>
      this.y = y; <br>
      this.element = element; <br>
    } <br>
     <br>
    WalkingSprite.prototype = { <br>
      x: 0, <br>
      y: 0, <br>
      element: null, <br>
      <br>
      walk: function(direction) { <br>
        this.x += direction; <br>
      } <br>
    } <br>
     <br>
    // Create the child class <br>
    JumpingAndWalkingSprite = WalkingSprite; <br>
    JumpingAndWalkingSprite.prototype = { <br>
      x: 0, <br>
      y: 0, <br>
      walk: WalkingSprite.prototype.walk <br>
      jump: function() { <br>
        y += 20; <br>
      } <br>
    }
    ユーザーの入力を許可します

    明らかに、ゲームには、キーボード、マウス、ジョイスティックなど、何らかの人間の入力が必要です。そのため、ゲームがその場で走る静止したスプライト以上のものになるためには、ユーザーからの入力に応答する必要があります。 JavaScriptでは、これはイベントリスニングと呼ばれます。
    ブラウザのフレーバーに応じて2つの異なるイベントモデルがあります(驚き、驚き)。プロトタイプは2つのニュアンスをカプセル化するのに素晴らしい仕事をしていますが、ボンネットの下で何が起こっているのかを知る価値があります。

    bubble-bobble

    イベントがDOMを介してそれを発射した要素(イベントキャプチャ)、要素(イベントバブル)、または両方の組み合わせ(公式W3Cモデル)から上に移動するかどうかを選択できます。以下は、何が起こるかのグラフィカルな表現です。インターネットエクスプローラーの土地にいる人はイベントの泡立ちに固執していますが、他のブラウザは両方をサポートしています。

    しばらくWebでプレイしている場合は、オンマウスオーバーやオンクリックなどの属性を使用したインラインイベント処理に精通している可能性があります。この手法は、CSSでスタイル属性を使用することに相当します。それは悪です、それをしないでください。ありがたいことに、JavaScriptの要素にイベントを動的にバインドする方法はいくつかあります。次のコードを検討してください:

    // Declare the class <br>
    function WalkingSprite(element, x, y) { <br>
      this.x = x; <br>
      this.y = y; <br>
      this.element = element; <br>
    } <br>
     <br>
    WalkingSprite.prototype = { <br>
      x: 0, <br>
      y: 0, <br>
      element: null, <br>
      <br>
      walk: function(direction) { <br>
        this.x += direction; <br>
      } <br>
    } <br>
     <br>
    koopa = new WalkingSprite(null, 10, 10); <br>
    koopa.walk(20); <br>
    alert(koopa.x + "," + koopa.y);

    ここでは、DOMの要素にイベントを接続するための3つの異なる方法があります。最初の - AddEventListenerを使用する - は、W3Cの標準的な方法です。最初のパラメーターはイベントの名前、2つ目はコールバック関数の名前、3番目はキャプチャ(False)またはバブル(True)のかどうかを示すブール値です。 2番目の(AttachEventを使用)は、Internet Explorer Wayです。 IEはイベントバブルのみをサポートするため、基本的にW3Cバージョンと同じ署名です。最後のものは、要素のOnClickプロパティを使用する - すべてのブラウザで機能する方法です。

    マウスオーバーやマウスアウトなどのイベントは非常に簡単ですが、キーボードイベントは、どのキーが押されたかを知る必要があるため、もう少し複雑です。この場合、JavaScriptイベントオブジェクトから情報を取得する必要があります。イベントオブジェクトがコールバック関数に渡されるか、IEランドにいる場合、グローバルイベントオブジェクトがウィンドウオブジェクト:window.eventに作成されます。

    例を次に示します

    var WalkingSprite = Class.create({ <br>
      x: 0, <br>
      y: 0, <br>
      element: null, <br>
     <br>
      initialize: function(element, x, y) { <br>
        this.element = element; <br>
        this.x = x; <br>
        this.y = y; <br>
      }, <br>
     <br>
      walk: function(steps) { <br>
        this.x += steps; <br>
      } <br>
    }); <br>
     <br>
    koopa = new WalkingSprite(null, 10, 10); <br>
    koopa.walk(20); <br>
    alert(koopa.x + "," + koopa.y);
    Event.observeを使用してイベントハンドラーをセットアップすることで、関数パラメーターを介してイベントオブジェクトがあるか、ウィンドウイベントからイベントオブジェクトがあるかをチェックする条件付きテストをドロップできます。 プロトタイプによって私たちのためにすべてシームレスに処理されています。
    // Declare the class <br>
    function WalkingSprite(element, x, y) { <br>
      this.x = x; <br>
      this.y = y; <br>
      this.element = element; <br>
    } <br>
     <br>
    WalkingSprite.prototype = { <br>
      x: 0, <br>
      y: 0, <br>
      element: null, <br>
      <br>
      walk: function(direction) { <br>
        this.x += direction; <br>
      } <br>
    } <br>
     <br>
    // Create the child class <br>
    JumpingAndWalkingSprite = WalkingSprite; <br>
    JumpingAndWalkingSprite.prototype = { <br>
      x: 0, <br>
      y: 0, <br>
      walk: WalkingSprite.prototype.walk <br>
      jump: function() { <br>
        y += 20; <br>
      } <br>
    }
    結論
    この時点で、JavaScriptオブジェクトとクラス(継承などのOOPコンセプトを含む)、JavaScriptとCSSクラスを使用して要素の動作を提供する方法、タイマーを使用してタスク(アニメーションなど)を繰り返し実行できる方法、およびイベントを聴くことの基本を調査しました。これにより、プラットフォームゲームを構築するコアに到達できるように、ツールボックスに十分なJavaScriptが得られます。次の記事では、基本的な衝突エンジン(アニメーションループ)の作成について説明し、ブラウザウィンドウをスクロールして80年代の本物のサイドスクロール効果を取得するためのいくつかのトリックを示します。

    その間に、上記の理論を実践するデモをチェックしてください(ヒント:矢印キーを押して、何が起こるかを確認してください)。この記事のコードアーカイブをダウンロードできます。このシリーズの2番目の記事で何が起こっているかを理解する必要があるため、自分で拡張できるかどうかを確認してください。次回まで…

    楽しさと利益のためのJavaScriptについてのよくある質問

    倫理的ハッキングにおけるJavaScriptのいくつかの実用的なアプリケーションは何ですか?

    JavaScriptは、倫理的ハッカーの手の強力なツールです。クロスサイトスクリプト(XSS)攻撃を実行するために使用できます。ハッカーは、悪意のあるスクリプトを信頼できるWebサイトに注入します。 JavaScriptは、データがWebサイトから抽出されるWebサイトスクレイピングにも使用できます。さらに、タスクを自動化するためのボットを作成し、さまざまな種類の浸透テストを実行するために使用できます。これらのツールを使用すると、Webページにアクセスし、その要素と対話し、必要なデータを抽出するプロセスを自動化できます。これは、APIを提供しないWebサイトから情報を収集したり、繰り返しタスクを自動化するのに役立ちます。 XSS攻撃により、攻撃者はクライアント側のスクリプトを他のユーザーが閲覧したWebページに注入できます。攻撃者は、クロスサイトのスクリプト脆弱性を使用して、同種のポリシーなどのアクセス制御をバイパスすることができます。 JavaScriptは、XSS攻撃でよく使用されます。これは、Webブラウザーによって広くサポートされており、Webページのコンテンツを効果的に操作できるためです。

    JavaScriptベースの攻撃からWebサイトを保護するにはどうすればよいですか?

    JavaScriptベースの攻撃からWebサイトを保護する方法はいくつかあります。最も効果的な方法の1つは、入力検証です。ここでは、すべてのユーザー入力をWebサイトにチェックして消毒します。別の方法は出力エンコードです。ここでは、ユーザーが提供するデータがウェブサイトに安全に表示されるようにします。 HTTPのみのCookieを使用して、クロスサイトスクリプト(XSS)攻撃を防ぐこともできます。どのように?

    はい、JavaScriptを使用してボットを作成できます。 ChromeのV8 JavaScriptエンジンに基づいて構築されたJavaScriptランタイムであるNode.jsを使用すると、ボットを含むサーバー側のアプリケーションを構築できます。操り人形師のようなライブラリを使用してブラウザのタスクを自動化できますが、discord.jsのような他のライブラリを使用してAPIと対話し、Discordのようなプラットフォームのボットを作成できます。攻撃者が悪用できる脆弱性。 JavaScriptは、タスクの自動化、XSS攻撃の実行、その他のJavaScriptベースの脆弱性を活用することにより、浸透テストを支援できます。 Codecademy、Udemy、CourseraなどのWebサイトでは、JavaScriptとEthical Hackingのコースを提供しています。さらに、「Web Application Hacker's Handbook」や「JavaScript:The Good Parts」などの本は非常に役立ちます。 Python、Ruby、PHPなどの他の言語も一般的に使用されています。ただし、JavaScriptは、Web上の遍在性のためにWebベースの攻撃に特に役立ちます。

    倫理的ハッキングで使用される一般的なJavaScriptライブラリは何ですか? Express.jsやsocket.ioなどの他のライブラリは、それぞれWebアプリケーションとリアルタイムアプリケーションの構築にも使用されます。

    以前のプログラミングエクスペリエンスなしでハッキングにJavaScriptを使用できますか?これにより、さまざまな攻撃がどのように機能し、JavaScriptを効果的に使用する方法を理解しやすくなります。

以上が楽しみと利益のためのJavaScriptのハッキング:パートIの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。