배열을 포함하는 PHP 상수?


407

실패했습니다 :

 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

답변:


498

참고 : 이것은 정답이지만 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

16
좋은. 그러나 나쁜 점은 이런 식으로 클래스 상수를 정의 할 수 없다는 것입니다.
Gregoire

19
클래스의 정적 변수를 고수하는 것이 좋습니다.
Jürgen Paul

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
다른 모든 답변이 구식이거나 잘못 알고있는 사용자가 작성 했으므로이 기능을 상향 조정해야합니다.
Andreas Bergström

이것이 유일한 구문입니까? 이전 정의 기능을 사용할 수 있습니까? define ( 'ARRAY_CONSTANT', array ( 'item1', 'item2', 'item3'));
Jack

5
@JackNicholsonn 불행히도 define()PHP 5.6에서는 사용할 수 없지만 PHP 7.0에서 수정되었습니다 . :)
Andrea

@ AndreasBergström 아니오,이 질문은 너무 새로운 것입니다. 이 질문은 2009 년에 이루어졌습니다! 이 구문은 오늘날 대부분의 사용자에게 거의 쓸모가 없습니다. 거의 모든 사람이 서버에 PHP 5.6을 가지고 있습니다. 다른 답변은 대안을 제공하기 때문에 완벽하게 좋습니다. 수업을 사용하지 않으려면 지금까지 허용되는 답변이 유일하게 가능한 방법입니다.
Ismael Miguel

@IsmaelMiguel은 모두 5.6을 가지고 있는지 확인하지 마십시오. Windows 서버의 모든 사용자는 이제 약 한 달 전에 Microsoft의 5.6 SQL Server 드라이버를 얻었습니다.
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';

다른 사람이 배열을 변경할 수 있다는 생각이 마음에 들지 않으면 getter가 도움이 될 수 있습니다.

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')
Frank Nocke

9
우리가 PHP에서 불변 배열을 만들 수 없다는 것이 우스운 것처럼 보이지만 이것은 적절한 해결 방법을 제공합니다.
Akoi Meexx

상수를 많이 사용하는 경우 함수 호출을 피할 수 있으며 상당히 비쌉니다. 정적은 갈 길입니다.
Chris Seufert

1
이 솔루션은 예상보다 훨씬 훌륭했습니다. 배열 값의 일부만 필요했기 때문에 단순히 배열을 얻는 대신 함수에 일부 매개 변수를 사용했습니다. 필자의 경우 Constants :: getRelatedIDs ($ myID)는 필요한 값으로 내부 배열을 얻습니다 (이 함수 내에서 ID 유효성 검사도 수행합니다). @cseufert는 전체 배열을 가져오고 각 경우에 대해 필터링하는 것이 훨씬 비쌉니다 ...
Armfoot

1
개인 정적 멤버가있는 함수 (getArray)를 갖는 것은 상수가 변경 될 수 있으므로 상수를 나타내는 것이 가장 좋습니다 👍🏻
Kamaldeep singh Bhatia

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

나중에이 솔루션에 동의합니다. 그것은 간단하고 쉬운 ... 이해 될 것처럼
패리스 Rayhan을

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

AngularJS는 JSON을 소비하기 때문에 실제로 잘 작동합니다. 나는 이것이 직렬화 대답보다 훨씬 낫다고 생각하지만 직렬화가 더 좋은 이유가 있습니까? 아마도 더 빠를까요?
Drellgor

예, 직렬화가 기술적으로 더 빠릅니다. 그러나 주로 필요한 작은 세트의 경우이 방법이 더 안전하므로 선호합니다. 직렬화를 해제하면 코드가 실행될 수 있습니다. 이 경우 위험이 매우 낮더라도 극단적 인 경우에만 사용을 예약하거나 직렬화 해제해야한다고 생각합니다.
Mario Awad

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;

객체와 배열을 상수로 저장해야했기 때문에 $ const 변수를 superglobal으로 만들 수 있도록 php에 runkit을 설치했기 때문에 정의했습니다.

그대로 $const->define("my_constant",array("my","values"));또는 그대로 사용할 수 있습니다$const->my_constant = array("my","values");

값을 얻으려면 단순히 전화하십시오. $const->my_constant;


와우, 나는 그런 방법을 기대하지 않았다 ... 내가도에 대해 알고하지 않았다 __get그리고 __set나는이 방법이 좋은 것을 말해야한다 ....
RedClover

이것을 매직 메소드라고합니다. PHP 문서를 확인하십시오.
Rikudou_Sennin

3

PHP 7 이상

PHP 7부터 define () 함수를 사용하여 상수 배열을 정의 할 수 있습니다.

define('ANIMALS', [
    'dog',
    'cat',
    'bird'
]);

echo ANIMALS[1]; // outputs "cat"

3

예를 들어 클래스에서 Associative Arrays와 함께 사용할 수도 있습니다.

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); if (isset ($ explodeResult) [$ index]) {return $ explodeResult [$ index];}
Saeed

@Saeed yup 좋은 지적입니다. 이에 따라 답변을 업데이트하겠습니다
MD. Sahib Bin Mahboob

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 사실이지만, 제공된 솔루션은 흥미롭고 다른 사람이 제공하지 않았으며 필요에 따라 개념적으로 다른 언어에 적용 할 수 있습니다 (도구 상자에 추가)
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
원하는 배열의 문자열 표현의 요점을 실제로 보지 못합니다.
Tomáš Zato-복직 모니카
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.