質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • PHP

    20838questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

PHP データの検索

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 595

mahomaho

score 39

下記のような情報をPHPで参照するにはどのような手法がよいでしょうか。
一般的な方法がわからず困っています。

アラビア語・・・ar,ar-sa,ar-ae,ar-bh,ar-dz,ar-eg,ar-iq,ar-jo,ar-kw,ar-lb,ar-ly,ar-ma,ar-om,ar-qa,ar-sy,ar-tn,ar-ye
アフリカーンス語・・・af,af-za
アルバニア語・・・sq,sq-al
(以下略)

<やりたいこと>
例:
arという文字列渡すと、アラビア語と返す。
sq-alと渡すとアルバニア語と返す。
・・・

<思いつく方法と考え>

  1. DBに格納する
    速度も落ちるしデータ自体が不変のためよくない気がする・・・

  2. 配列データに変換(シリアライズ化して外部化)
    例:'ar'=>'アラビア語','ar-sa'=>'アラビア語'・・・
    これが一番よさそうな気がする・・・

  3. 正規表現を使う
    例:if(preg_match(/ar|ar-sa|ar-ae/・・・){
    return 'アラビア語';
    }
    重そうだしコードが・・・

  4. if、スイッチ
    if(== 'ar') return 'アラビア語';
    if(== 'ar-sa') return 'アラビア語';

処理的には一番早そうだけどコード的に微妙・・・

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+2

2と4で悩みどころですね.2はハッシュが衝突しない限り処理時間が一律になりますが,配列を用意する時間がかかってしまいます.4は先頭のほうは非常に高速ですが,後ろのほうになると遅くなってしまいます.(といっても配列作ってる2より速い?)なお,4はswitch文のフォールスルーを使ってもう少し見やすく書けます.

総合的に判断すると4かな?

function language_name($language_code)
{
    switch($language_code) {
        case 'ar':
        case 'ar-sa': case 'ar-ae': case 'ar-bh': case 'ar-dz':
        case 'ar-eg': case 'ar-iq': case 'ar-jo': case 'ar-kw':
        case 'ar-lb': case 'ar-ly': case 'ar-ma': case 'ar-om':
        case 'ar-qa': case 'ar-sy': case 'ar-tn': case 'ar-ye':
            return 'アラビア語';

        case 'af':
        case 'af-za':
            return 'アフリカーンス語';

        case 'sq':
        case 'sq-al':
            return 'アルバニア語';

        default:
            throw new \UnexpectedValueException;
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/12 04:25 編集

    実行速度について言及しましたが、この関数を1リクエスト中に何回も実行しない場合は微々たるコストにしかならないので、あまり気にしなくていいです。

    他の用途に活用する可能性がある場合はngyukiさんの回答、この用途だけで完結し変更も少ない場合は私の回答を推奨しておきます。

    キャンセル

  • 2016/04/12 09:20

    なお,X-YのYの部分を無視してもいい場合はswitch文を使うよりも連想配列の定義のほうがよいでしょう.複数対ひとつの関係を連想配列は定義できないためこちらを使っているだけです.

    キャンセル

+2

わたしなら用途によって「1.DBに格納する」か「2.配列データに変換」を使います。

ただ、

array(
    'ar' => 'アラビア語',
    'ar-sa' => 'アラビア語',
    :
);

とかよりも、

array(
    'ar' => 'ar',
    'ar-sa' => 'ar',
    :
);
array(
    'ar' => 'アラビア語',
    :
);

のように2つに分けるほうがよいかもしれません(そもそも1つめのは必要??)。

「1.DBに格納する」については、もしその値をRDBに格納することがあるのであれば(人物テーブルの言語フィールド、みたいに)、言語テーブルも同じくRDBに格納し外部キー制約を貼る必要があるかもしれないからです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

実行速度は気にせず、可読性と保守性(※)の観点から、ご自身がもっとも優れていると思う方法を採用すればよいかと思います。
※データの追加・修正があった際の変更のしやすさ

なぜなら、よほどシビアな性能を求められているのではない限り、アプリケーション全体の実行コストに対するこのコードの実行コストの割合は微々たるもののはずだからです。

ちなみに私なら、-以降は無視して

$languages = array(
    'ar' => 'アラビア語',
    'af' => 'アフリカーンス語',
    'sq' => 'アルバニア語',
    ...
);

function get_language_name($arg) {
    $code = explode('-', $arg, 2);

    return $languages[$code[0]];
}

とやりますw

もしくは、言語コード-国コードの一覧に他の用途が想定されるなら、以下のようなテーブル構造のDBに格納してしまうかと思います。

CREATE TABLE languages (
    code char(2) PRIMARY KEY,
    name varchar(128) NOT NULL
);

INSERT INTO languages VALUES
    ('ar', 'アラビア語'),
    ('af', 'アフリカーンス語'),
    ('sq', 'アルバニア語'),
    ...;


CREATE TABLE countries (
    code char(2) PRIMARY KEY,
    name varchar(128) NOT NULL
);

INSERT INTO countries VALUES
    ('sa', 'サウジアラビア王国'),
    ('za', '南アフリカ共和国'),
    ('al', 'アルバニア共和国'),
    ...;


CREATE TABLE language_country (
    language_code char(2), 
    country_code char(2), 
    PRIMARY KEY (language_code, country_code),
    FOREIGN KEY (language_code) REFERENCES languages(code),
    FOREIGN KEY (country_code) REFERENCES  countries(code)
);

INSERT INTO language_country VALUES
    ('ar', 'sa'),
    ('af', 'za'),
    ('sq', 'al'),
    ...

これなら、DBの一意制約やリレーションを利用できるためにデータの管理が容易になるのと、
例えば
「国コードから、その国で使われている言語を取得する」
など、他の用途にも利用しやすくなるからです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

再利用や綺麗さを考えるとどれもイマイチですね。
1はDBというシステムと密結合、マイグレーションファイルで管理すればいいので△
2はPHP言語と密結合、いろんな可能性を考えた時の最適解に近そうなので○
3と4は保守し難いので論外…ただしコンパイル後としてはアリか?

あるべき姿で考えてDBサーバーに突っ込むのが嫌なら、JSONやSQLiteを利用する案もあります。

{
  ar: "アラビア語",
  af: "アフリカーンス語",
  ...
}

しかしJSONファイルをPHPで都度読み込んでデコードし始めると速度はあってないようなもの。
速度を求めるなら自力でクイックソートのコードを書いたりする必要がありそうです。

速度と綺麗さを求めるのであれば、コンパイル用のNode.jsバッチを作成して…
JSONファイルから下記のようなPHPコードに変換してみてはいかがでしょう?
作ってみたら微妙なコードになっちゃいましたが、PHP7なら純粋な配列になるのでそこそこ速そうです。

<?php
function jp_lang_of($prefix) {
  $codes = ['af','ar'...]; // 予め昇順に
  $langs = ['アフリカーンス','アラビア'...]; // こちらもindex値を揃える

  $index = 0; // クイックソートでindexを探す
  return $langs[$index];
}

ひらめきました。

function lang() {
  return 'アラビア語';
}

config/langディレクトリの中にar.phpのようなファイルを生成して、includeで呼び出せばいいのです。
1回きりの処理なら間違いなしで最速です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

関連した質問

同じタグがついた質問を見る

  • PHP

    20838questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。