PHP8.0でWebAPIを使用する方法
著者は、 Write forDOnationsプログラムの一環として寄付を受け取るためにTechEducationFundを選択しました。
序章
RESTful API は、リソース共有、タスク自動化、リモート検証など、さまざまな方法でさまざまな目的に使用されます。 たとえば、APIを提供するプラットフォームには、Facebook、LinkedIn、Twitter、GitHub、DigitalOceanなどがあります。 これらのプラットフォームのAPIを活用することで、アプリケーションは人間の介入なしにこれらのリモートシステムと対話できます。 たとえば、アプリケーションでユーザーのFacebookウォールに写真を投稿し、LinkedInを使用してユーザーの身元を確認し、負荷が大きすぎる場合に新しいDigitalOceanドロップレットを生成することができます。
PHP を使用したアプリケーション開発に精通している場合は、大規模なプログラムを最初から作成したり、複雑なインフラストラクチャをオンラインに維持したりすることなく、既存のサービスを使用してアプリケーションを強化できます。
このチュートリアルでは、HTTP POSTおよびGET呼び出しを使用してサーバーと対話することにより、RESTfulAPIのクライアントを構築します。 OpenWeather MapAPIから情報を取得して表示するWebアプリケーションを構築します。 ユーザー入力を有効にし、ソフトウェア開発キット(SDK)を使用してコードの将来を保証する前に、基本的なアプリから始めます。 最終的なWebアプリケーションは、選択した都市に関するリアルタイムの気象情報をユーザーに提供します。
新しいAPIを扱うときは、ドキュメントを読むことから始めることをお勧めします。 この場合、OpenWeatherガイドで役立つ情報を見つけることができます。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- XMLサポートが有効になっているPHPのローカル開発環境。これは、チュートリアルのステップ1、PHP7.4をインストールしてUbuntu20.04にローカル開発環境をセットアップする方法に従って実行できます。 手順1の最後に追加のパッケージをインストールする場合は、必要に応じて
php7.4
をphp8.0
に置き換え、パッケージインストールコマンドからphp7.4-json
を削除します。 - チュートリアルのステップ1〜2、Composerのインストールと使用方法に従って実行できるComposerがマシンにインストールされています。
- チュートリアルシリーズPHPでのコーディング方法から得られるPHPの知識。
- 無料アカウントを作成することで取得できるOpenWeatherMapのAPIキー。 登録後、アカウントのマイAPIキーに移動します。
ステップ1—Webアプリのインターフェイスを構築する
このステップでは、Webアプリケーションの基本バージョンを作成します。これは、後のステップで変更します。 ここでは、HTMLフォームとリクエストハンドラーを作成します。
プロジェクトのディレクトリ(weather-app
)を作成し、そこに移動することから始めます。
mkdir weather-app cd weather-app
お気に入りのテキストエディタまたはnano
を使用して、index.php
ファイルを作成します。
nano index.php
次の内容をファイルにコピーします。
天気-app/index.php
<html> <body> <h1>Weather query</h1> <?php if ( 'post' === strtolower($_SERVER['REQUEST_METHOD']) ) { ?> <h2>6.36</h2> <?php } else { ?> <form method="post"> <input type="submit" value="Get London's temperature"> </form> <?php } ?> </body> </html>
最初のif
ステートメントは、HTMLフォームとリクエストハンドラーを分離します。 チェックしている条件('post' === strtolower($_SERVER['REQUEST_METHOD'])
)は、要求の生成に使用されたHTTP動詞を検証することです。 ここでは、単純な'post' === $_SERVER['REQUEST_METHOD']
の代わりに比較'post' === strtolower($_SERVER['REQUEST_METHOD'])
を使用して、Webサーバーまたはブラウザーの構成に依存する代わりに値を正規化します。
メソッドがpost
の場合、それはリクエストがフォームの送信から発信されたことを意味します。したがって、2番目のステップにいることがわかります。 メソッドがpost
でない場合は、ユーザーがサイトに初めてアクセスしたものと安全に想定できるため、フォームを表示してワークフローを開始させることは理にかなっています。この場合は、ロンドンに依頼することを意味します。温度。
if
ステートメントの次にの部分を詳しく見ると、固定の6.36
値があることがわかります。 これはランダムなプレースホルダー番号であり、後でライブデータに置き換えます。
完了したら、ファイルを保存して閉じます。
次に、次のコマンドを実行して、組み込みのPHPWebサーバーを起動します。
php -S localhost:8707
出力は次のようになります。
[Wed Nov 17 11:54:10 2021] PHP 8.0.12 Development Server (http://localhost:8707) started
次に、ブラウザで新しいタブを開き、http://localhost:8707
をポイントします。
注:前提条件のチュートリアル PHP7.4をインストールしてUbuntu20.04にローカル開発環境をセットアップする方法のようにリモートマシンを使用している場合は、ポート転送を使用して表示できますあなたのアプリ。 PHP Webサーバーを起動した後、ローカルマシンで新しいターミナルを開き、次のコマンドを実行します:ssh -L 8707:localhost:8707 your-non-root-user@your-server-ip
。 リモートサーバーへの接続が成功すると、http://localhost:8707
でアプリを表示できます。
次のような画面が表示されます。
ロンドンの気温を取得をクリックして、結果を確認します。
データは現在アプリケーションにハードコーディングされているため、6.36
が唯一の可能な応答です。
このステップでは、ユーザーが現在ハードコーディングされているロンドンの現在の気温のクエリを開始できるようにするWebアプリケーションを作成しました。 次のステップでは、APIからデータを取得するようにアプリを更新します。
ステップ2—RESTfulAPIからデータを取得する
このステップでは、信頼できるソース(OpenWeather Map)からデータをフェッチするようにアプリケーションを更新します。
PHPを使用してRESTfulAPIから情報を取得する方法はたくさんあります。 最も一般的な方法の1つは、curlライブラリを使用することです。 このライブラリは完全に機能しますが、HTTP通信を低レベルで制御するように設計されているため、多くの場合、煩雑になる可能性があります。
ここでは、関数file_get_contentsを使用してRESTfulAPIから読み取ります。 この関数を使用してローカルファイルを読み取ることはご存知かもしれませんが、PHPのストリーム管理システムは、多くの基盤となるストレージメカニズムに対して同じ抽象化を提供します。 file_get_contents
を使用して、ローカルドライブに存在するかのようにリモートファイルから読み取ることができます。 RESTfulリソースはURIによって識別されるため、そのエンドポイントを関数にフィードすると、リモートサーバーから送信された応答の内容(すでにヘッダーが削除されている)が返されます。
認証を使用するなど、より複雑な方法でサーバーと対話する必要がある場合は、3番目のパラメーターとして特定のstream_contextを指定することで実行できます。
OpenWeather Map APIからデータを取得するには、index.php
を開いて編集し、次のように更新します。
天気-app/index.php
<html> <body> <h1>Weather query</h1> <?php if ( 'post' === strtolower($_SERVER['REQUEST_METHOD'])) { ?> <h2><?php echo file_get_contents('https://api.openweathermap.org/data/2.5/weather?mode=xml&units=metric&q=London&appid=YOUR_API_KEY'); ?></h2> <?php } else { ?> <form method="post"> <input type="submit" value="Get London's temperature"> </form> <?php }?> </body> </html>
OpenWeatherAPIキーの実際の値のYOUR_API_KEY
を変更することを忘れないでください。
このスクリプトは、固定URL https://api.openweathermap.org/data/2.5/weather?mode=xml&units=metric&q=London&appid=YOUR_API_KEY
を受け取り、HTTP呼び出しを行い、受信したとおりに応答を出力します。
このURLは次の要素で構成されています。
- ベースURL(
https://api.openweathermap.org/data/2.5/
) - エンドポイント(
weather
) - クエリ文字列(
?mode=xml&units=metric&q=London&appid=YOUR_API_KEY
)
これは、RESTfulAPIの一般的な構造です。 探しているリソースに関係なく、ベースURLは同じになります。 エンドポイントは、探している特定の種類の情報によって異なります。最後に、クエリ文字列を使用して、リクエストを絞り込むためのいくつかのオプションを提供します。
この場合、次の修飾子を使用しています。
mode
:応答で使用する形式(この場合はxml
)。units
:測定単位、この場合はmetric
。q
:都市表現、この場合はLondon
。appid
:APIキー。
追加のパラメーターについては、OpenWeather製品のドキュメントを参照してください。
完了したら、ファイルを保存して閉じます。
ブラウザに戻り、ページを更新して結果を確認します。 出力は次のようになります。
この時点では、結果はユーザーが期待するものではありません。これにより、英国の国の指定(GB
)とタイムゾーン(3600
)が返されます。
このページのソースコードを見ると、次のような出力が表示されます。
Webアプリのソースコード
<html> <body> <h1>Weather query</h1> <h2> <?xml version="1.0" encoding="UTF-8"?> <current> <city id="2643743" name="London"> <coord lon="-0.1257" lat="51.5085"></coord> <country>GB</country> <timezone>3600</timezone> <sun rise="2022-04-12T05:11:24" set="2022-04-12T18:50:48"></sun> </city> <temperature value="18.21" min="15.02" max="19.87" unit="celsius"></temperature> <feels_like value="17.73" unit="celsius"></feels_like> <humidity value="63" unit="%"></humidity> <pressure value="1006" unit="hPa"></pressure> <wind> <speed value="4.63" unit="m/s" name="Gentle Breeze"></speed> <gusts></gusts> <direction value="210" code="SSW" name="South-southwest"></direction> </wind> <clouds value="40" name="scattered clouds"></clouds> <visibility value="10000"></visibility> <precipitation mode="no"></precipitation> <weather number="802" value="scattered clouds" icon="03d"></weather> <lastupdate value="2022-04-12T14:11:48"></lastupdate> </current> </h2> </body> </html>
問題は、スクリプトがAPIサーバーの応答を受信したとおりに正確に出力しているため、正しくレンダリングするのはブラウザーの責任であるということです。 APIサーバーの応答はXMLであるため、ブラウザーはタグを最大限に解釈します。HTML以外のすべてのタグ(city
、temperature
など)はブラウザーによって無視されます。 。 この問題に対処するには、アプリケーションを更新してXML応答を解析し、ユーザーにとって意味のある部分(temperature
タグの内容)を抽出します。
このステップでは、リモートAPIにクエリを実行し、リアルタイムの情報を取得するようにアプリケーションを更新しました。 次のステップでは、受信したXMLデータを解析するようにアプリを更新します。
ステップ3—データの表示
この時点で、アプリはリモートサーバーにクエリを実行し、応答を受信します。 受信した情報はXMLであるため、都市の気温などの特定の情報を取得するために解析する必要があります。 このステップでは、アプリを更新してXML応答を変換し、ユーザーに関連する情報を表示します。
1つのアプローチは、正規表現などを使用してデータを手動で解析することです。 ただし、このアプローチは複雑でエラーが発生しやすい可能性があります。 より良いアプローチは、クラスSimpleXMLElementを使用することです。 このクラスは、XMLの複雑さを処理するように特別に設計されており、使いやすいインターフェースを提供します。
index.php
ファイルを開いて編集し、次のように更新します。
天気-app/index.php
<html> <body> <h1>Weather query</h1> <?php if ( 'post' === strtolower($_SERVER['REQUEST_METHOD'])) { ?><h2><?php $xml = new SimpleXMLElement('https://api.openweathermap.org/data/2.5/weather?mode=xml&units=metric&q=London&appid=YOUR_API_KEY', 0, true); echo $xml->temperature['value']; ?></h2> <?php } else { ?> <form method="post"> <input type="submit" value="Get London's temperature"> </form> <?php }?> </body> </html>
YOUR_API_KEY
をAPIキーの実際の値に置き換えることを忘れないでください。
$xml
はSimpleXMLElement
のインスタンスです。 XMLテキスト内のすべての子ノードはそのパブリックプロパティであり、属性は配列キーとしてアクセスできます。
クラスコンストラクターの呼び出しは、3つのパラメーターを指定することによって行われます。 1つ目はデータソースです。 この場合、XMLデータのソースとしてURLhttps://api.openweathermap.org/data/2.5/weather?mode=xml&units=metric&q=London&appid=YOUR_API_KEY
を指定します。
次は、XMLの解釈方法を指定するオプション修飾子です。 この場合、0
を使用しています。つまり、デフォルトのオプションを使用する必要があります。 3番目の引数はtrue
値です。 SimpleXMLElement
オブジェクトは、リテラルXML値またはURLの2つの可能なソースを使用して作成できます。 true
を発行すると、URLが使用されることになります。
ラインecho $xml->temperature['value'];
は、SimpleXMLElement
によって提供されるオブジェクト指向インターフェースを活用しています。 このクラスの基本的な機能は、整形式のXMLであると思われる文字列を使いやすいツリー構造に変換することです。
したがって、サーバーから返されたXMLを振り返ると、次のようになります。
Webアプリのソースコード
<?xml version="1.0" encoding="UTF-8"?> <current> <city id="2643743" name="London"> <coord lon="-0.1257" lat="51.5085"></coord> <country>GB</country> <timezone>3600</timezone> <sun rise="2022-04-12T05:11:24" set="2022-04-12T18:50:48"></sun> </city> <temperature value="18.21" min="15.02" max="19.87" unit="celsius"></temperature> <feels_like value="17.73" unit="celsius"></feels_like> <humidity value="63" unit="%"></humidity> <pressure value="1006" unit="hPa"></pressure> <wind> <speed value="4.63" unit="m/s" name="Gentle Breeze"></speed> <gusts></gusts> <direction value="210" code="SSW" name="South-southwest"></direction> </wind> <clouds value="40" name="scattered clouds"></clouds> <visibility value="10000"></visibility> <precipitation mode="no"></precipitation> <weather number="802" value="scattered clouds" icon="03d"></weather> <lastupdate value="2022-04-12T14:11:48"></lastupdate> </current>
$xml
オブジェクトには次のプロパティがあることがわかります。
city
temperature
feels_like
humidity
pressure
wind
clouds
visibility
precipitation
weather
lastupdate
これらの各プロパティは、SimpleXMLElement
のインスタンスでもあります。
この場合、関心があるのは<temperature/>
要素の属性value
のみです。 したがって、$xml->temperature['value']
を使用すると、上記の例では18.21
が得られます。
完了したら、ファイルを保存して閉じます。
ブラウザに戻り、ページを更新すると、次のようなものが表示されます。
出力の数はおそらく異なります。 アプリケーションがリアルタイムクエリを実行しているため、これは予想されることです。
これで、アプリはXMLデータを解析できます。 SimpleXMLElement
は、指定されたURLから読み取り、結果を解析し、リモートサーバーから返されたテキストのオブジェクト指向表現を構築しています。 それが完了すると、アプリケーションはSimpleXMLElement
オブジェクトのプロパティとして温度値を参照できます。
この時点で、スクリプトは、信頼できるソースから取得したライブ情報を、エンドユーザーにとって意味のある形式で表示できます。 次のステップでは、ユーザー入力を有効にして、アプリに双方向性を導入します。
ステップ4—ユーザー入力を有効にする
このステップでは、ユーザーがさまざまな都市の気温を照会できるようにします。 これを行うには、データソースのURLを変更して、リモートサーバーからさまざまな結果を取得します。
最初の変更は、最初の画面に都市のドロップダウンを表示して、ユーザーが興味のある都市を選択できるようにすることです。 index.php
を開いて編集し、次のようにフォームを更新します。
天気-app/index.php
<html> <body> <h1>Weather query</h1> <?php if ( 'post' === strtolower($_SERVER['REQUEST_METHOD'])) { ?><h2><?php $xml = new SimpleXMLElement('https://api.openweathermap.org/data/2.5/weather?mode=xml&units=metric&q=London&appid=YOUR_API_KEY', 0, true); echo $xml->temperature['value']; ?></h2> <?php } else { ?> <form method="post"> <label for="city">Select your city</label> <select name="city" id="city"> <option value="London">London</option> <option value="Buenos Aires">Buenos Aires</option> <option value="New York">New York</option> <option value="Paris">Paris</option> </select> <input type="submit" value="Get your city's temperature"> </form> <?php }?> </body> </html>
これで、アプリケーションはユーザーにドロップダウン選択を表示するので、London
に固定する代わりに、情報を取得する都市を選択できます。
ただし、スクリプトで選択した都市をクエリするには、if
ステートメントの最初の部分も変更する必要があります。 次のようにデータソースのURLを更新します。
天気-app/index.php
<html> <body> <h1>Weather query</h1> <?php if ( 'post' === strtolower($_SERVER['REQUEST_METHOD'])) { ?><h2><?php $xml = new SimpleXMLElement('`https://api.openweathermap.org/data/2.5/weather?mode=xml&units=metric&q=`'.$_POST['city'].'&appid=YOUR_API_KEY', 0, true); echo $xml->temperature['value']; ?></h2> <?php } else { ?> <form method="post"> <label for="city">Select your city</label> <select name="city" id="city"> <option value="London">London</option> <option value="Buenos Aires">Buenos Aires</option> <option value="New York">New York</option> <option value="Paris">Paris</option> </select> <input type="submit" value="Get your city's temperature"> </form> <?php }?> </body> </html>
ここでは、q
パラメーターの値をLondon
からユーザーが選択した都市に変更しました。 URLは、次の連結として作成されます。
https://api.openweathermap.org/data/2.5/weather?mode=xml&units=metric&q=
$_POST['city']
'&appid=YOUR_API_KEY'
完了したら、ファイルを保存して閉じます。
注:これは、OpenWeatherMapがパラメーターを処理する方法です。 他のAPIについては、詳細について特定のドキュメントを参照する必要があります。
変更を確認するには、ブラウザに戻ってナビゲーションを最初からやり直してください。 これで、都市を選択するためのドロップダウンがアプリに表示されます。
異なる都市を選択すると、異なる温度値が返されるはずです。
この手順では、アプリでユーザー入力を有効にし、データソースURLを更新して、ユーザーの選択に基づいてデータを取得しました。
ただし、この時点で、コードはAPIの応答の現在の構造と緊密に結合されており、将来にわたって利用できるとは限りません。 現在、ルート要素の第1レベルの子としてtemperature
タグを探すのは理にかなっていますが、それはいつでも変更される可能性があります。その場合、アプリケーションコードを更新して保持する必要があります。それは機能しています。 この問題に対処する1つの方法は、ソフトウェア開発キット(SDK)を使用することです。これは、次のステップで実行します。
ステップ5—ソフトウェア開発キット(SDK)のインストール
このステップでは、 OpenWeatherMapPHPクライアントをインストールします。 このクライアントは、アプリケーションロジックをOpenWeather Mapサーバーとの通信方法の特定の詳細から完全に分離し、はるかに将来性のあるアプリケーションを効果的に生成します。 前の手順で行ったようにデータを手動で取得するのではなく、SDKを使用してデータを取得します。
アプリケーション内でSDKを使用すると、長期にわたってはるかに保守しやすくなります。 たとえば、サーバーがクライアントと対話する方法に変更が発生した場合、必要なのはユーザー側のSDKを更新することだけです。 比較すると、リクエストを自分でコーディングする場合、コードを適応させるには、すべてのリモート呼び出しを追跡して更新するために多大な労力が必要になります。 さらに、新しいバグが発生する可能性もあります。
OpenWeather Map PHP SDKを使用する最初のステップは、それをインストールすることです。 このチュートリアルでは、前提条件の一部としてインストールしたPHPの依存関係マネージャーであるComposerを使用します。
Composerを使用できるようになったら、次のコマンドを実行してSDKとその依存関係をインストールします。
composer require "cmfcmf/openweathermap-php-api" "http-interop/http-factory-guzzle:^1.0" "php-http/guzzle6-adapter:^2.0 || ^1.0"
SDK自体はパッケージcmfcmf/openweathermap-php-api
です。 http-interop/http-factory-guzzle
およびphp-http/guzzle6-adapter
は、下位レベルでHTTP通信を処理するために必要な補助パッケージです。
これにより、次の出力が生成されます。
Using version ^3.3 for cmfcmf/openweathermap-php-api ./composer.json has been created Running composer update cmfcmf/openweathermap-php-api http-interop/http-factory-guzzle php-http/guzzle6-adapter Loading composer repositories with package information Updating dependencies Lock file operations: 16 installs, 0 updates, 0 removals - Locking cmfcmf/openweathermap-php-api (v3.3.0) - Locking guzzlehttp/guzzle (6.5.5) - Locking guzzlehttp/promises (1.5.1) - Locking guzzlehttp/psr7 (1.8.3) - Locking http-interop/http-factory-guzzle (1.2.0) - Locking php-http/guzzle6-adapter (v2.0.2) - Locking php-http/httplug (2.2.0) - Locking php-http/promise (1.1.0) - Locking psr/cache (1.0.1) - Locking psr/http-client (1.0.1) - Locking psr/http-factory (1.0.1) - Locking psr/http-message (1.0.1) - Locking ralouphie/getallheaders (3.0.3) - Locking symfony/polyfill-intl-idn (v1.23.0) - Locking symfony/polyfill-intl-normalizer (v1.23.0) - Locking symfony/polyfill-php72 (v1.23.0) Writing lock file Installing dependencies from lock file (including require-dev) Package operations: 16 installs, 0 updates, 0 removals - Installing psr/http-message (1.0.1): Extracting archive - Installing psr/http-factory (1.0.1): Extracting archive - Installing psr/http-client (1.0.1): Extracting archive - Installing psr/cache (1.0.1): Extracting archive - Installing cmfcmf/openweathermap-php-api (v3.3.0): Extracting archive - Installing guzzlehttp/promises (1.5.1): Extracting archive - Installing ralouphie/getallheaders (3.0.3): Extracting archive - Installing guzzlehttp/psr7 (1.8.3): Extracting archive - Installing http-interop/http-factory-guzzle (1.2.0): Extracting archive - Installing php-http/promise (1.1.0): Extracting archive - Installing php-http/httplug (2.2.0): Extracting archive - Installing symfony/polyfill-php72 (v1.23.0): Extracting archive - Installing symfony/polyfill-intl-normalizer (v1.23.0): Extracting archive - Installing symfony/polyfill-intl-idn (v1.23.0): Extracting archive - Installing guzzlehttp/guzzle (6.5.5): Extracting archive - Installing php-http/guzzle6-adapter (v2.0.2): Extracting archive 2 package suggestions were added by new dependencies, use `composer suggest` to see details. Generating autoload files 6 packages you are using are looking for funding. Use the `composer fund` command to find out more!
これで、プロジェクト内にvendor
という新しいディレクトリができました。 このディレクトリは、Composerを介してインストールされたすべての依存関係が見つかる場所です。
ライブラリコードと一緒に、それらすべてへのアクセスを提供するファイルがあります:autoload.php
。 持ち込んだ依存関係のいずれかを使用する必要があるすべてのスクリプトの先頭に、このファイルを含める必要があります。
このステップでは、アプリケーションに新しい依存関係を追加しました。OpenWeatherMapAPIのオブジェクト指向クライアントです。 これに依存することで、はるかにクリーンなコーディングインターフェイスが得られ、APIの新しいバージョンに一致するようにコードを更新する全体的な労力を軽減できます。
ステップ6—SDKを使用してWebアプリをリファクタリングする
このステップでは、前のステップでインストールしたSDKを使用するようにコードをリファクタリングします。 スクリプトにSDKコードが必要であり、ライブラリ内で提供されているオブジェクトを使用してリモートAPIにアクセスします。
index.php
を開いて編集し、次のように更新します。
天気-app/index.php
<?php use Cmfcmf\OpenWeatherMap; use Cmfcmf\OpenWeatherMap\Exception as OWMException; use Http\Factory\Guzzle\RequestFactory; use Http\Adapter\Guzzle6\Client as GuzzleAdapter; ?> <html> <body> <h1>Weather query</h1> <?php if ( 'post' === strtolower($_SERVER['REQUEST_METHOD'])) { require_once 'vendor/autoload.php'; $city = $_POST['city']; $owm = new OpenWeatherMap('YOUR_API_KEY', GuzzleAdapter::createWithConfig([]), new RequestFactory()); try { $weather = $owm->getWeather($city, 'metric', 'en'); ?><h2><?php echo $weather->temperature; ?></h2> <?php } catch(OWMException $e) { echo 'OpenWeatherMap exception: ' . $e->getMessage() . ' (Code ' . $e->getCode() . ').'; } catch(\Exception $e) { echo 'General exception: ' . $e->getMessage() . ' (Code ' . $e->getCode() . ').'; } } else { ?> <form method="post"> <label for="city">Select your city</label> <select name="city" id="city"> <option value="London">London</option> <option value="Buenos Aires">Buenos Aires</option> <option value="New York">New York</option> <option value="Paris">Paris</option> </select> <input type="submit" value="Get your city's temperature"> </form> <?php }?> </body> </html>
YOUR_API_KEY
をAPIキーの実際の値に置き換えることを忘れないでください。
まず、上部に名前名を宣言します(use ...
ステートメント)。 これらの行を使用して、短いクラス名を完全に分類された名前(たとえば、OpenWeatherMap
からCmfcmf\OpenWeatherMap
)にマップする方法をインタープリターに指示し、コードの読み取りと書き込みを容易にします。
vendor/autoload.php
ファイルも含めました。 このファイルはcomposer
によって作成され、スクリプトで明示的に必要とされないクラスの新しいインスタンスを作成できるようにするためのspl_autoload_registerへの必要な呼び出しが含まれています。
最も重要な変更は、メソッド(getWeather
)を使用してリモートサーバーを呼び出すことです。これにより、コードがクリーンになり、長期間にわたって保守しやすくなります。 HTTP呼び出しを行い、テキストをPHPオブジェクトに変換します。 ある意味で、リモートコールが行われていることを忘れて、天気情報に直接アクセスしたかのように機能することができます。 また、サーバーからの応答が変更された場合は、APIの呼び出しが行われるコードのすべてのインスタンスを変更するのではなく、SDKのバージョンを更新するだけです。
次に、例外をキャッチするように変更しました。 外部システムを扱うときは、リモートサーバーが応答しなくなったり、ローカルネットワークに障害が発生したりするなどの問題を予測することをお勧めします。 例外をキャッチしていない場合、例外が発生すると、不快なユーザーエクスペリエンスが発生し、スクリプトの実行が予期せず停止するため、システムの安定性が損なわれる可能性があります。
ここでは、デバッグを容易にするために、このスクリプトに2つのcatch
ステートメントがあります。 メソッドOpenWeatherMap::getWeather
は特定の例外(OWMException
)をスローするため、不明な例外がある場合に備えて、それらを使用して別のcatch-all
例外ハンドラーを残すのが理にかなっています。
完了したら、ファイルを保存して閉じます。
ページを更新すると、出力にわずかな変化が見られます。
これで、摂氏記号が温度の横に表示されます。
これは、アプリケーションがecho $weather->temperature;
を使用して出力を生成し、$weather->temperature
がCmfcmf\OpenWeatherMap\Util\Temperature
クラスのオブジェクトであり、__toString
メソッドを実装しているために発生します。戻り値の単位。 前の手順と同じ出力を取得したい場合は、代わりにecho $weather->temperature->getValue()
を使用できます。
このステップでは、既存のSDKを利用して低レベルの通信の詳細を抽象化することにより、アプリケーションの保守をはるかに簡単にしました。
アプリケーションを本番環境に対応させるための最後のステップは、ハードコードされたAPI_KEY
を削除することです。 キーがハードコードされたままの場合、アプリケーションを別の環境にデプロイするたびに、コードを機能させるためにコードにアクセスする必要があります。これはエラーの原因です。
手順7—ハードコーディングを削除する
これまで、ハードコードされたデータの一部であるOpenWeatherAPIキーを使用してきました。 ハードコードされた情報を削除すると、アプリケーションをさまざまな環境で実行できるようになります。これは、複数の実行コンテキスト(dev、test、prodなど)が必要な実際のアプリケーションにとって重要な機能です。
このステップでは、ハードコードされたAPIキーを削除して、さまざまな環境にデプロイするためのアプリケーションを準備します。
1つの手法は、この種の情報を環境変数に格納することです。環境変数は、$_ENV
配列を介してPHPスクリプト内でアクセスできます。
このアプローチを使用するには、index.php
ファイルを開いて編集し、強調表示された部分を更新します。
天気-app/index.php
<?php use Cmfcmf\OpenWeatherMap; use Cmfcmf\OpenWeatherMap\Exception as OWMException; use Http\Factory\Guzzle\RequestFactory; use Http\Adapter\Guzzle6\Client as GuzzleAdapter; ?> <html> <body> <h1>Weather query</h1> <?php if ( 'post' === strtolower($_SERVER['REQUEST_METHOD'])) { require_once 'vendor/autoload.php'; $city = $_POST['city']; $owm = new OpenWeatherMap($_ENV['API_KEY'], GuzzleAdapter::createWithConfig([]), new RequestFactory()); try { $weather = $owm->getWeather($city, 'metric', 'en'); ?><h2><?php echo $weather->temperature; ?></h2> <?php } catch(OWMException $e) { echo 'OpenWeatherMap exception: ' . $e->getMessage() . ' (Code ' . $e->getCode() . ').'; } catch(\Exception $e) { echo 'General exception: ' . $e->getMessage() . ' (Code ' . $e->getCode() . ').'; } } else { ?> <form method="post"> <label for="city">Select your city</label> <select name="city" id="city"> <option value="London">London</option> <option value="Buenos Aires">Buenos Aires</option> <option value="New York">New York</option> <option value="Paris">Paris</option> </select> <input type="submit" value="Get your city's temperature"> </form> <?php }?> </body> </html>
完了したら、ファイルを保存して閉じます。
変更を有効にするには、ローカルWebサーバーを停止し、次のコマンドを使用して再起動する必要があります。
API_KEY=YOUR_API_KEY php -d variables_order=EGPCS -S localhost:8707
YOUR_API_KEY
をAPIキーの実際の値に置き換えます。
この呼び出しでは、最初に環境変数の値を確立してから、PHPインタープリターを呼び出します。 オペレーティングシステムは、APIキー定義を含むPHPプロセスの新しい実行環境を作成します。
-d
修飾子はphp
コマンドに適用され、PHPの構成を変更するために使用されます。 この場合、variables_order
定義は、スーパーグローバルの設定方法を確立します。 値EGPCS
は、環境、取得、投稿、Cookie、サーバーを意味します。 このの詳細については、PHPのドキュメントを参照してください。
実稼働環境の場合、Webサーバー構成を使用してこれらの値を確立できます。
この手順では、APIキーのハードコーディングを削除し、代わりに環境変数を使用しました。 これで、アプリケーションはさまざまな環境での実行により適したものになります。
結論
この記事では、ユーザーがOpenWeather Mapにクエリを実行して、選択した都市の現在の気温を取得できるWebアプリケーションを作成しました。 file_get_contents
を使用してリモートRESTfulAPIからデータを取得し、SimpleXMLElement
を使用してXMLデータを解析しました。 また、利用可能な場合は、SDKを使用してリモートAPIにアクセスしました。 最後に、アプリケーションを更新して、環境変数をハードコーディングする代わりに、環境変数からシークレットを取得しました。
次のステップとして、より複雑なAPIに進み、基本的な原則がどのように同じであるかを確認できます。
存在するAPIタイプはRESTfulAPIだけではないことに注意してください。 SOAP は非常に異なるプロトコルであり、多くのシナリオ、特に政府機関でまだ使用されているため、他のAPIタイプについても理解しておくことをお勧めします。