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

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

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

3回答

9505閲覧

PHP7新機能・定数に配列を定義

退会済みユーザー

退会済みユーザー

総合スコア0

PHP

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

3グッド

5クリップ

投稿2016/09/16 19:33

編集2016/09/16 20:33

先日こちらのページ PHPマニュアル > 付録 > 変更履歴 を眺めていたときに、

イメージ説明

「define() に配列を定義できるようになった」と記述されており、

define

イメージ説明

実際に以下のコードで試したところ

php

1<?php 2 3define('ARRAY_SAMPLE_01', ['a', 'b', 'c']); 4 5define('ARRAY_SAMPLE_02', ['a' => 100, 'b' => 200, 'c' => 300]); 6 7var_dump(ARRAY_SAMPLE_01); 8var_dump(ARRAY_SAMPLE_01[0]); 9 10var_dump(ARRAY_SAMPLE_02); 11var_dump(ARRAY_SAMPLE_02['b']);

確かに動くのですが、いったいどんな場面で使えばいいの?というのが疑問です。
そもそも定数に定義できるのはスカラー値であるというルールのもとで利用していたので、配列を定義したいと思ったことがありません。

そこで質問なのですが、

  1. これまで定数に配列を定義したいと思ったことがありますか?
  2. また、それはどんなケースでしたか?
  3. オブジェクト定数ではなく、グローバル空間に配列を定数を定義する積極的なメリットはあるか

ちなみにこちらのコードは、PHP5.6, PHP7 両方の環境で動作しました。

php

1<?php 2 3class SAMPLE 4{ 5 6 const ARR = ['a', 'b', 'c']; 7 8} 9 10var_dump(SAMPLE::ARR[0]);
pafe.aratani, bezeklik, m.ts10806👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

PHPの定数定義の方法について、変遷を調べてみました。(参考: PHP>マニュアル>言語リファレンス>定数>構文PHP>マニュアル>関数リファレンス>その他の基本モジュール>その他>その他の関数>define)

  • 〜5.2

define: スカラー値のみ
const: 存在しない

  • 5.3〜5.5

define: スカラー値のみ
const: スカラー値のみ

  • 5.6

define: スカラー値のみ
const: スカラー値(スカラー式も可)と配列 ※ リソースも可能だが非推奨

  • 7.0〜

define: スカラー値と配列 ※ リソースも可能だが非推奨
const: スカラー値(スカラー式も可)と配列 ※ リソースも可能だが非推奨

defineは関数式、constは代入式という書き方の違いがあります。defineはそもそも関数として扱われるため、値の部分に任意の式を書くことができます。7.0からdefineで配列も可能にしたのは、単にconstにあわせていったと思われます。

なお、(Cを除く)他の言語の定数は、再代入できない(言語によっては警告を出すだけや、慣習としてそうするというのもある)ただの変数として扱う場合が多いです。そのため、

  1. 定義は代入式
  2. 任意のデータ(オブジェクト)を扱える

という場合がほとんどです。初期のPHPは関数式のdefineだけで、しかもスカラー値のみであり、他の言語とは大きくかけ離れていました。それをバージョンアップの度に徐々にあわせていったと考えられます。


では、上を踏まえて、質問の回答です。

  1. これまで定数に配列を定義したいと思ったことがありますか?

あまりPHPを書かないのでPHPでそうしたいと思ったことは無いのですが、PHP以外の言語では普通に使っています。

  1. また、それはどんなケースでしたか?

指定フォルダ内のファイルを処理するスクリプトで、除外するファイル一覧として['System Volume Information', '$RECYCLE.BIN', 'Desktop.ini', ...]みたいなのを作った事があります。そのプログラムで変わることが無いような、サポート済み形式とか、定義済みの名前とか、そういった物の一覧を初めから用意したいときに使っています。たとえば、HTML5を処理するようなプログラムで使用できる要素名一覧を定数配列に入れておくとかです。

  1. オブジェクト定数ではなく、グローバル空間に配列を定数を定義する積極的なメリットはあるか

constもグローバル空間に使用できます。まずは、クラス内とクラス外という比較で言えば、

  1. クラス内だと名前空間が分かれるため、名前の衝突防止等が期待できます。(大規模開発では必須)
  2. クラス内だとそのクラスに関連する定数だと一目でわかります。

と言う違いがあります。クラスを意識した作りにするのであればクラス内で書くべきでしょう。ただ、オブジェクト指向を使わないようなフラットなPHPにおいて、そのためだけにクラスを作るのはあまり意味が無いと思います。

では、グローバル空間において、constdefineですが、違いは代入式と関数式というところです。

  1. constの代入式の方が、変数の代入と書き方が同じになるため、わかりやすいような気がします。
  2. defineは関数式なので、値部分を任意の式にできます。constの右辺はスカラー式しか許されていません

特に2.の違いが重要です。

PHP

1define("HOGE", array_merge([1, 2], [8, 9]));

と書くことができますが、

PHP

1const HOGE = array_merge([1, 2], [8, 9]);

と書くことはできません。関数等を用いて配列を作り上げたい(他にもたとえばrange(1, 10)など)ときはdefineを使うしかないようです。

投稿2016/09/17 00:38

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/09/18 05:35

回答ありがとうございます。 やはり、オブジェクト指向での設計においては、あまり出番はなさそうだな、という印象ですね。 アプリケーションのメンテナンスコストを考えると、多用するのは避けた方が良さそうだな…と感じています。
guest

0

普段ほとんどdefine自体使わないので、興味深くちょっと調べてみたところ、以下のような例を見つけました。

php

1define('ALLOWED_IMAGE_EXTENSIONS', ['jpg', 'jpeg', 'gif', 'png']);

元ネタ

投稿2016/09/16 21:49

編集2016/09/16 22:04
popobot

総合スコア6586

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/09/18 05:39

あげて頂いた例はちょうど想像していたような例です。アプリケーション全体の設定など、めったに変更されないようなものでないと使いどころはないし、オブジェクト指向設計においては、画像クラスのオブジェクト定数(またはプロパティ)に持つべきかと思われます。 軽量のアプリケーションなど、全体の見通しがしやすいもので利用しないといけないな、との印象ですね。
guest

0

詳しい説明はraccyさんが網羅してるので、
配列として定数を定義できるメリットに絞って考えてみました。

僕が考えついた所としては、

  • プログラム内で割と使う回すけど属性、値の組
  • クラス化とかするほど大層なものではない
  • だけど値は書き換えられたらまずいので不変の性質は持たせたい(イミュータブルなクラスみたいに)

上記要件に当てはまる場合はさっくり書けるようになりますよ、というのがdefineで配列を扱えるようにしたしたメリットかなと個人的に思ってます。

またここからは想像のお話なので、
興味なければ読み飛ばして下さい。

defineで配列が定義できるようになりましたの延長で、
いずれかはクラスなどのオブジェクトも定義できるようになりましたなるかもしれないし、ならないかもしれません。

もしクラスのインスタンス自体を定数持ちさせることが可能になれば、
とあるオブジェクトを特定の値で初期化し、
それを定数のように使い回したいというかとが出来るようになってきそうです
(C#.NETのstaticとreadonlyキーワードの合わせ技みたいな役割。ただ参照保持した定数なんでインスタンスの上書きは禁止できても、内部状態の変化は禁止できなかったはず^^;)

質問内容とは全く関係ありませんが、
参考までにC#の定数内訳で参考となるページを貼り逃げしときます。
【C#の定数】const と static readonly の使い分け

投稿2016/09/17 03:48

Panzer_vor

総合スコア1636

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/09/18 05:32

回答ありがとうございます。 やはり、オブジェクト指向での設計においては、あまり出番はなさそうですよね。 関連クラスにオブジェクト定数として定義する方が、メンテナンスコストが低くなると思いますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問