iOSとAndroidを判別するコードの扱い方
PHPを使用して、現在のデバイスがモバイル端末の中でもiOSで実行されているのか、またはAndroidで実行されているのかを判別するコードについて解説します。
これは、モバイル環境で特定のOSに応じた機能を提供したり、iOSおよびAndroidユーザーに異なる体験を提供するWebサイトで役立ちます。
参考してください
ここで扱うモバイル端末の判別およびiOSやAndroidで実行されているかを確認する方法は、正確性や拡張性の面で制限がある場合があるため、その正確性や拡張性を保証するものではありません。そのため、すべての資料やサンプルコードをそのまま信用するのではなく、ご自身の判断でエラー、バグ、脆弱性がないかを十分にテストおよび検証したうえでご利用ください。
モバイルiOSとAndroidを判別する関数
PHPでモバイル端末のiOSとAndroidを判別することは、Web開発においてよく必要とされる処理のひとつです。ユーザーがモバイルデバイスを利用している場合に、それぞれに適した環境を提供するため、このような判別が必要になります。今回の記事では、PHPを使ってモバイル端末を検出し、その中でもiOSとAndroidを区別する方法について紹介します。
モバイルのiOSとAndroidを判別する関数コード
/**
* PHP 8で導入されたstr_contains()関数をpolyfillとして代替する関数です。
* PHP 8未満のバージョンでstr_contains()関数を使用するために利用します。
*
* @param string $haystack 対象となる文字列です。
* @param string $needle 検索したい部分文字列です。
* @return bool 指定した文字列に部分文字列が含まれている場合はtrue、そうでない場合はfalseを返します。
*/
if (!function_exists('str_contains')) {
/*
* str_contains()関数のpolyfill
* 出典:https://core.trac.wordpress.org/browser/trunk/src/wp-includes/compat.php#L423
*/
function str_contains($haystack, $needle) {
if ('' === $needle) {
return true;
}
return false !== strpos($haystack, $needle);
}
}
/**
* モバイル端末を検出して判別する関数です。
* HTTP_SEC_CH_UA_MOBILEヘッダーを確認し、HTTP_USER_AGENTを解析して
* モバイル端末かどうかを判定します。
*
* @return bool モバイル端末が検出された場合はtrue、そうでない場合はfalseを返します。
*/
function is_mobile() {
if (isset($_SERVER['HTTP_SEC_CH_UA_MOBILE'])) {
// HTTP_SEC_CH_UA_MOBILEヘッダーが存在し、
// 値が'?1'の場合はモバイル端末と判定します。
// 参考:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-UA-Mobile
return ('?1' === $_SERVER['HTTP_SEC_CH_UA_MOBILE']);
} elseif (!empty($_SERVER['HTTP_USER_AGENT'])) {
// HTTP_USER_AGENTを解析してモバイル端末の特徴を確認します。
$user_agent = $_SERVER['HTTP_USER_AGENT'];
return str_contains($user_agent, 'Mobile')
|| str_contains($user_agent, 'Android')
|| str_contains($user_agent, 'Silk/')
|| str_contains($user_agent, 'Kindle')
|| str_contains($user_agent, 'BlackBerry')
|| str_contains($user_agent, 'Opera Mini')
|| str_contains($user_agent, 'Opera Mobi');
} else {
// HTTP_SEC_CH_UA_MOBILEヘッダーもHTTP_USER_AGENTも存在しない場合は、
// モバイル端末ではないものとして扱います。
return false;
}
}
/**
* iOSを検出して判別する関数です。
*
* @return bool モバイル端末がiOSの場合はtrue、そうでない場合はfalseを返します。
*/
function is_ios() {
return is_mobile() && preg_match('/iPad|iPod|iPhone/', $_SERVER['HTTP_USER_AGENT']);
}
/**
* Androidを検出して判別する関数です。
*
* @return bool モバイル端末がAndroidの場合はtrue、そうでない場合はfalseを返します。
*/
function is_android() {
return is_mobile() && preg_match('/Android/', $_SERVER['HTTP_USER_AGENT']);
}
/* iOS、Androidかどうかによって異なるコードを実行します。 */
if (is_ios()) {
// iOS環境で実行するコード
} elseif (is_android()) {
// Android環境で実行するコード
} else {
// その他の環境で実行するコード
}
上記コードで使用している主な関数です。
上記コードの処理の流れを順番に簡単に説明します。
str_contains()関数のpolyfill:
PHP 8で導入されたstr_contains()関数を、PHP 8以前のバージョンでも使用できるようにpolyfill関数を定義しています。この関数は、文字列に特定の文字列が含まれているかどうかを確認します。この関数は、モバイル端末を検出して判別する関数内で使用されています。- モバイル端末を検出して判別する関数(
is_mobile()):HTTP_SEC_CH_UA_MOBILEヘッダーを確認する、またはHTTP_USER_AGENTを解析することで、モバイル端末かどうかを判定する関数です。この関数は、モバイル端末である場合はtrueを返し、そうでない場合はfalseを返します。 - iOSとAndroidを判別する関数(
is_ios()およびis_android()):
モバイル端末が検出された場合に、その端末がiOSかAndroidかを判定する関数です。iOSの場合は、HTTP_USER_AGENTに「iPad」、「iPod」、「iPhone」などの文字列が含まれているかを確認して判定し、Androidの場合は「Android」という文字列が含まれているかを確認して判定します。 - 条件分岐を利用した環境ごとの処理:
検出された環境に応じて異なるコードを実行するために、if-elseif-else文を使用します。iOS環境が検出された場合はiOS環境で実行するコードを処理し、Android環境が検出された場合はAndroid環境で実行するコードを処理します。それ以外の場合は、その他の環境で実行するコードを処理します。この条件分岐は、開発環境や用途に応じて柔軟に変更して利用できます。
上記サンプルコードの限界点
このような処理を通じて、提供したコードはPHPでモバイル端末のiOSとAndroidを判別し、それぞれの環境に応じた動作を実行できる便利な機能を提供します。ただし、上記のサンプルコードにはいくつかの限界点があります。主な内容としては、以下のような点が挙げられます。
HTTP_USER_AGENTの限界点
ユーザーエージェント文字列を解析してモバイル端末を検出する方法は、信頼性が低い場合があります。ユーザーエージェントは、ユーザー自身がスマートフォンのブラウザでもデスクトップモードへ変更できるためです。そのため、このコードにはユーザーエージェントに依存することによる限界があります。また、クライアント側の情報をセキュリティ関連の目的で利用する場合は、追加の適切な対策が必要になります。
新しいモバイルデバイス追加への拡張性
コードでは、モバイル端末を検出するためにHTTP_USER_AGENTヘッダーを解析しています。そのため、新しいモバイルデバイスが発売されるたびに、その端末のユーザーエージェント文字列パターンを考慮してコードを更新する必要があります。これは、新しいモバイルデバイスが追加された場合に保守対応が必要になる可能性があることを意味します。
キャッシュされたユーザーエージェント値の不一致
キャッシュが適用されている場合、同じユーザーエージェント値を持つ複数のユーザーが異なるデバイスからアクセスすると、問題が発生する可能性があります。キャッシュされたユーザーエージェント値が固定されている場合、新しいデバイスやブラウザからアクセスした際に正しい結果を返せないことがあります。これは、ユーザー体験を低下させたり、誤った結果を提供する原因になる可能性があります。
そのため、キャッシュを実装する際は、ユーザーエージェント値がキャッシュされないよう注意する必要があります。代わりに、ユーザーを識別できる安定した方法を使用してキャッシュを構成する必要があります。