配列を含むPHP定数?


408

これは失敗しました:

 define('DEFAULT_ROLES', array('guy', 'development team'));

どうやら、定数は配列を保持できません。これを回避する最良の方法は何ですか?

define('DEFAULT_ROLES', 'guy|development team');

//...

$default = explode('|', DEFAULT_ROLES);

これは不必要な努力のようです。


17
PHP 5.6は定数配列をサポートしています。以下の私の回答を参照してください。
Andrea

1
配列を定数として使用する必要がある場合、列挙を実行しようとしていますか?その場合は、SplEnumを使用してください:php.net/manual/en/class.splenum.php
ziGi

2
@ziGi今日この問題に出くわし、特定の次元を必要とするさまざまなタイプの画像を保存する必要があり、これらの次元を幅と高さの代わりに定数配列として保存すると便利になりました。
Matt K

回答:


499

注:これは受け入れられる回答ですが、PHP 5.6以降ではconst配列を使用できることに注意してください以下のAndrea Fauldsの回答を参照してください

配列をシリアル化して定数に入れることもできます:

# define constant, serialize array
define ("FRUITS", serialize (array ("apple", "cherry", "banana")));

# use it
$my_fruits = unserialize (FRUITS);

40
私はこのソリューションが大好きだと言いたいだけです:)
GateKiller '25年

16
いいね。しかし悪い点は、この方法ではクラス定数を定義できないことです。
グレゴワール2011

19
クラスの静的変数に固執する。
ユルゲンポール

5
あなたが行うことはできませんあまりにも悪い:$fruit = FRUITS[0];
Sophivorus

20
このコードはエレガントですがかなり遅いです。配列を返す静的なパブリッククラスメソッドを使用する方がはるかに優れています。
名詞

844

PHP 5.6以降では、配列定数をconst次のように宣言できます。

<?php
const DEFAULT_ROLES = array('guy', 'development team');

短い構文も期待どおりに機能します。

<?php
const DEFAULT_ROLES = ['guy', 'development team'];

PHP 7を使用define()している場合は、最初に試したように、ようやくを使用できます。

<?php
define('DEFAULT_ROLES', array('guy', 'development team'));

41
他のすべての回答は時代遅れであるか、誤解されたユーザーによって書かれただけなので、これは賛成する必要があります。
AndreasBergström2014

それが唯一の構文ですか?古い定義関数を使用できますか?define( 'ARRAY_CONSTANT'、array( 'item1'、 'item2'、 'item3'));
Jack

5
@JackNicholsonn残念ながらdefine()、ここではPHP 5.6では使用できませんが、これはPHP 7.0では修正されています。:)
Andrea 14

@AndreasBergströmいいえ、この質問はあまりにも新しいものです。この質問は2009年に行われました。この構文は、現在ほとんどのユーザーにとってほとんど役に立たないでしょう。ほとんどの人がサーバーにPHP 5.6をインストールしています。他の回答も選択肢を提供するので、完全に問題ありません。クラスを使用したくない場合、これまで受け入れられた答えが唯一の実行可能な方法です。
Ismael Miguel

@IsmaelMiguelが5.6であることを確認してください。Windowsサーバーの誰もがちょうど今、約1か月前にMicrosoftから5.6 SQLサーバードライバーを取得しました。
MH

141

それらをクラスの静的変数として保存できます。

class Constants {
    public static $array = array('guy', 'development team');
}
# Warning: array can be changed lateron, so this is not a real constant value:
Constants::$array[] = 'newValue';

配列を他の人が変更できるという考えが気に入らない場合は、ゲッターが役立ちます。

class Constants {
    private static $array = array('guy', 'development team');
    public static function getArray() {
        return self::$array;
    }
}
$constantArray = Constants::getArray();

編集

PHP5.4以降、中間変数を必要とせずに配列値にアクセスすることも可能です。つまり、次のように動作します。

$x = Constants::getArray()['index'];

1
+1。私はこれを何年も続けます:const AtomicValue =42; public static $fooArray = ('how','di')
フランク・ノッケ

9
PHPで不変の配列を作成できないことは私にはばかげているように思えますが、これは適切な回避策を提供します。
Akoi Meexx

定数をたくさん使用している場合は、関数呼び出しは絶対に避けます。非常に高価です。静的な方法です。
Chris Seufert、2014年

1
このソリューションは予想よりもはるかに優れていました。配列の値の一部しか必要ないため、単に配列を取得する代わりに、関数でいくつかのパラメーターを使用しました。私の場合、Constants :: getRelatedIDs($ myID)は、必要な値のみを含む内部配列を取得します(この関数内でID検証も行います)。@cseufertは、配列全体を取得し、それぞれのケースでフィルタリングする方がはるかにコストがかかります...
Armfoot

1
彼らは変更👍🏻ことができるようにプライベート静的メンバーと機能(のgetArray)を有することは、定数のための最高の表現である
Kamaldeepシンバティア

41

PHP 5.6以上を使用している場合は、Andrea Fauldsの回答を使用してください

このように使っています。他の人の役に立つことを願っています。

config.php

class app{
    private static $options = array(
        'app_id' => 'hello',
    );
    public static function config($key){
        return self::$options[$key];
    }
}

ファイルでは、定数が必要です。

require('config.php');
print_r(app::config('app_id'));

私はあなたがしたように同じことをしました。したがって、これが良いかどうかにかかわらず、パフォーマンスの最適化を探していました。
NullPointer 2017年

このソリューションに同意します。シンプルで理解しやすいので...
ファリスレイハン10/16

12

これは私が使用するものです。これはsoulmergeが提供する例に似ていますが、この方法で配列全体または配列内の単一の値を取得できます。

class Constants {
    private static $array = array(0 => 'apple', 1 => 'orange');

    public static function getArray($index = false) {
        return $index !== false ? self::$array[$index] : self::$array;
    }
}

次のように使用します。

Constants::getArray(); // Full array
// OR 
Constants::getArray(1); // Value of 1 which is 'orange'

10

JSON文字列として定数に格納できます。アプリケーションの観点から、JSONは他の場合にも役立ちます。

define ("FRUITS", json_encode(array ("apple", "cherry", "banana")));    
$fruits = json_decode (FRUITS);    
var_dump($fruits);

これはまさに私が考えていたものです。これは合法的に良い答えではありませんか?
Con Antonakos 14

これはJSONを使用するため、AngularJSで非常にうまく機能します。これはシリアライズの答えよりもはるかに優れていると思いますが、シリアライズの方が優れている理由はありますか?多分それより速いですか?
Drellgor '19

はい、シリアライズは技術的に高速です。ただし、ほとんどの場合に必要となる小さなセットの場合は、この方法の方が安全であるため、この方法を使用します。シリアル化を解除すると、コードが実行される可能性があります。この場合、これは非常に低いリスクですが、極端な場合にのみ使用を予約するか、シリアル化を解除する必要があります。
Mario Awad 2014

9

PHP 5.6以降では、const以下のようなキーワードを使用して定数配列を定義できます

const DEFAULT_ROLES = ['test', 'development', 'team'];

さまざまな要素に以下のようにアクセスできます。

echo DEFAULT_ROLES[1]; 
....

PHP 7以降、定数配列は次のように定義できdefineます。

define('DEFAULT_ROLES', [
    'test',
    'development',
    'team'
]);

以前と同じ方法でさまざまな要素にアクセスできます。


3

私はそれが少し古い質問であることを知っていますが、これが私の解決策です:

<?php
class Constant {

    private $data = [];

    public function define($constant, $value) {
        if (!isset($this->data[$constant])) {
            $this->data[$constant] = $value;
        } else {
            trigger_error("Cannot redefine constant $constant", E_USER_WARNING);
        }
    }

    public function __get($constant) {
        if (isset($this->data[$constant])) {
            return $this->data[$constant];
        } else {
            trigger_error("Use of undefined constant $constant - assumed '$constant'", E_USER_NOTICE);
            return $constant;
        }
    }

    public function __set($constant,$value) {
        $this->define($constant, $value);
    }

}
$const = new Constant;

オブジェクトと配列を定数に格納する必要があるので、それを定義したので、runkitもphpにインストールして、$ const変数をスーパーグローバルにできるようにしました。

そのままでも$const->define("my_constant",array("my","values"));、そのままでも使えます$const->my_constant = array("my","values");

値を取得するには、単に呼び出すだけです $const->my_constant;


わあ、そんなことは期待していませんでした...知らなかったし__get__set...この方法は素晴らしいと言わざるを得ません。
RedClover 2017年

これらはマジックメソッドと呼ばれます。それらについては、phpのドキュメントを確認してください。
Rikudou_Sennin 2017年


3

連想配列でも動作します。たとえば、クラスで。

class Test {

    const 
        CAN = [
            "can bark", "can meow", "can fly"
        ],
        ANIMALS = [
            self::CAN[0] => "dog",
            self::CAN[1] => "cat",
            self::CAN[2] => "bird"
        ];

    static function noParameter() {
        return self::ANIMALS[self::CAN[0]];
    }

    static function withParameter($which, $animal) {
        return "who {$which}? a {$animal}.";
    }

}

echo Test::noParameter() . "s " . Test::CAN[0] . ".<br>";
echo Test::withParameter(
    array_keys(Test::ANIMALS)[2], Test::ANIMALS["can fly"]
);

// dogs can bark.
// who can fly? a bird.

2

explode関数とimplode関数を使用して、ソリューションを即興で作成できます。

$array = array('lastname', 'email', 'phone');
define('DEFAULT_ROLES', implode (',' , $array));
echo explode(',' ,DEFAULT_ROLES ) [1]; 

これはエコーしemailます。

さらに最適化したい場合は、2つの関数を定義して、次のように繰り返し行うことができます。

//function to define constant
function custom_define ($const , $array) {
    define($const, implode (',' , $array));
}

//function to access constant  
function return_by_index ($index,$const = DEFAULT_ROLES) {
            $explodedResult = explode(',' ,$const ) [$index];
    if (isset ($explodedResult))
        return explode(',' ,$const ) [$index] ;
}

お役に立てば幸いです。幸せなコーディング。


$ explodeResult = explode( '、'、$ const);を実行すると、2回の爆発を防ぐことができます。if(isset($ explodeResult)[$ index]){return $ explodeResult [$ index];}
サイード

@Saeed yupいい点ですね。私はそれに応じて私の答えを更新します
MD。サヒブビンマブーブ2013

2

ある種のser / deserやencode / decodeのトリックを行うのは見苦しく、定数を使用しようとしたときに正確に何をしたかを覚えておく必要があります。アクセサー付きのクラスのプライベート静的変数はまともな解決策だと思いますが、私はあなたのためにもっとよくします。定数配列の定義を返すパブリックな静的ゲッターメソッドがあるだけです。これには最低限の追加コードが必要であり、配列定義を誤って変更することはできません。

class UserRoles {
    public static function getDefaultRoles() {
        return array('guy', 'development team');
    }
}

initMyRoles( UserRoles::getDefaultRoles() );

定義済み定数のように見せたい場合は、すべて大文字の名前を付けることができますが、名前の後に '()'括弧を追加することを覚えておくと混乱を招きます。

class UserRoles {
    public static function DEFAULT_ROLES() { return array('guy', 'development team'); }
}

//but, then the extra () looks weird...
initMyRoles( UserRoles::DEFAULT_ROLES() );

メソッドをグローバルにして、求めていたdefine()機能に近づけることができると思いますが、実際には定数名のスコープを設定し、グローバルを回避する必要があります。


2

このように定義できます

define('GENERIC_DOMAIN',json_encode(array(
    'gmail.com','gmail.co.in','yahoo.com'
)));

$domains = json_decode(GENERIC_DOMAIN);
var_dump($domains);

2

はい、配列を定数として定義できます。以降PHP 5.6は、スカラー式として定数を定義することが可能であり、そしてまた、ある配列定数を定義することができます。定数をリソースとして定義することは可能ですが、予期しない結果を引き起こす可能性があるため、避けてください。

<?php
    // Works as of PHP 5.3.0
    const CONSTANT = 'Hello World';
    echo CONSTANT;

    // Works as of PHP 5.6.0
    const ANOTHER_CONST = CONSTANT.'; Goodbye World';
    echo ANOTHER_CONST;

    const ANIMALS = array('dog', 'cat', 'bird');
    echo ANIMALS[1]; // outputs "cat"

    // Works as of PHP 7
    define('ANIMALS', array(
        'dog',
        'cat',
        'bird'
    ));
    echo ANIMALS[1]; // outputs "cat"
?>

このリンクを参考に

幸せなコーディングをしてください。


1

2009年からこれを探していて、AbstractSingletonFactoryGeneratorsが気に入らない場合は、他にいくつかのオプションがあります。

配列は割り当て時、またはこの場合は返されるときに「コピー」されるので、毎回同じ配列を取得していることに注意してください。(PHPの配列のコピーオンライト動作を参照してください。)

function FRUITS_ARRAY(){
  return array('chicken', 'mushroom', 'dirt');
}

function FRUITS_ARRAY(){
  static $array = array('chicken', 'mushroom', 'dirt');
  return $array;
}

function WHAT_ANIMAL( $key ){
  static $array = (
    'Merrick' => 'Elephant',
    'Sprague' => 'Skeleton',
    'Shaun'   => 'Sheep',
  );
  return $array[ $key ];
}

function ANIMAL( $key = null ){
  static $array = (
    'Merrick' => 'Elephant',
    'Sprague' => 'Skeleton',
    'Shaun'   => 'Sheep',
  );
  return $key !== null ? $array[ $key ] : $array;
}

私たちは長年、配列を定数として定義することができましたが、回避策を鈍らせる価値はあまりないと思います。
miken32

1
@ miken32はtrueですが、提供されたソリューションは興味深いものであり、他のユーザーから提供されたものではなく、必要に応じて概念的に他の言語に適用できます(ツールボックスに追加)
puiu

1

PHP 7&7+を使用している場合は、次のようにフェッチを使用することもできます

define('TEAM', ['guy', 'development team']);
echo TEAM[0]; 
// output from system will be "guy"

0

定数にはスカラー値のみを含めることができます。配列のシリアル化(またはJSONエンコードされた表現)を保存することをお勧めします。


1
これは受け入れられた回答に何も追加しないので、おそらく削除する必要がありますか?
Ian Dunn

4
@IanDunn:受け入れられた回答が理由を説明していない、または私の回答に何も追加されていないと主張しますが...削除するために投票してください。
Alix Axel

1
目的の配列の文字列表現の要点は本当にわかりません。
トマーシュZato -復活モニカ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.