const () 대 const


659

PHP에서 언제 사용합니까

define('FOO', 1);

언제 사용합니까

const FOO = 1;

?

이 둘의 주요 차이점은 무엇입니까?


4
성능 (나 같은 마이크로 최적화와 시간의 낭비) 정보를 참조하십시오 이 답변 : const두 배 빠른 속도로보다 define. 페이지로드 시간 및 메모리 사용량 정보 : 이 질문이 기사를 참조 하십시오 . opcode 캐시에 대한 내용도 여기를 참조 하십시오 .
피터 크라우스

2
현재 허용 된 답변 만 보지 말고 stackoverflow.com/a/3193704/1412157 을 참조하십시오. 답변 은 반드시 답변해야합니다
LucaM

1
귀하의 의견에 대한 알림을 보았습니다. 허용되는 답변을 업데이트했습니다.
danjarvis

답변:


1039

PHP 5.3부터는 상수정의하는 두 가지 방법이 있습니다 : const키워드를 사용하거나 define()함수를 사용합니다 :

const FOO = 'BAR';
define('FOO', 'BAR');

이 두 가지 방법의 근본적인 차이점은 const컴파일 타임에 상수를 define정의하는 반면 런타임에는 상수 를 정의 한다는 것입니다. 이로 인해 대부분 const의 단점 이 발생 합니다. 몇 가지 단점 const은 다음 과 같습니다.

  • const조건부 상수를 정의하는 데 사용할 수 없습니다. 전역 상수를 정의하려면 가장 바깥 쪽 범위에서 사용해야합니다.

    if (...) {
        const FOO = 'BAR';    // Invalid
    }
    // but
    if (...) {
        define('FOO', 'BAR'); // Valid
    }

    어쨌든 왜 그렇게 하시겠습니까? 일반적인 응용 프로그램 중 하나는 상수가 이미 정의되어 있는지 확인하는 것입니다.

    if (!defined('FOO')) {
        define('FOO', 'BAR');
    }
  • const정적 스칼라 (숫자 나 문자열과 같은 다른 일정 받아 true, false, null, __FILE__), 반면에 define()임의의 표현을 취한다. PHP 5.6부터 상수 표현식도 허용됩니다 const.

    const BIT_5 = 1 << 5;    // Valid since PHP 5.6 and invalid previously
    define('BIT_5', 1 << 5); // Always valid
  • const일반 상수 이름을 사용하지만 define()모든 식을 이름으로 허용합니다. 이를 통해 다음과 같은 작업을 수행 할 수 있습니다.

    for ($i = 0; $i < 32; ++$i) {
        define('BIT_' . $i, 1 << $i);
    }
  • consts는 항상 대소 문자를 구분하지만 세 번째 인수로 define()전달 true하여 대소 문자를 구분하지 않는 상수를 정의 할 수 있습니다 (참고 : 대소 문자를 구분하지 않는 상수 정의는 PHP 7.3.0부터 더 이상 사용되지 않습니다).

    define('FOO', 'BAR', true);
    echo FOO; // BAR
    echo foo; // BAR

그래서 그것은 나쁜 것입니다. 이제 const위의 상황 중 하나가 발생하지 않는 한 개인적으로 항상 사용하는 이유를 살펴 보겠습니다 .

  • const단순히 더 잘 읽습니다. 함수 대신 언어 구성이며 클래스에서 상수를 정의하는 방법과 일치합니다.
  • const언어 구조 인,는 자동화 된 툴링으로 정적으로 분석 될 수 있습니다.
  • const현재 네임 스페이스에서 상수를 정의 define()하고 전체 네임 스페이스 이름을 전달해야합니다.

    namespace A\B\C;
    // To define the constant A\B\C\FOO:
    const FOO = 'BAR';
    define('A\B\C\FOO', 'BAR');
  • PHP 5.6 const상수도 배열이 될 define()수 있지만 아직 배열을 지원하지는 않습니다. 그러나 PHP 7에서는 두 경우 모두 배열이 지원됩니다.

    const FOO = [1, 2, 3];    // Valid in PHP 5.6
    define('FOO', [1, 2, 3]); // Invalid in PHP 5.6 and valid in PHP 7.0

마지막으로, 클래스 상수 또는 인터페이스 상수 const를 정의하기 위해 클래스 또는 인터페이스 내에서 사용될 수도 있습니다 . 이 목적으로 사용할 수 없습니다 :define

class Foo {
    const BAR = 2; // Valid
}
// But
class Baz {
    define('QUX', 2); // Invalid
}

요약

조건부 또는 표현 정의 유형이 필요하지 않은 경우 가독성을 위해 consts 대신 s를 사용 define()하십시오!


1
PHP 5.6에서 알 수 있듯이 const언어 구성 에서도 간단한 스칼라 식을 사용할 수 있습니다. wiki.php.net/rfc/const_scalar_exprs
mabe.berlin at 14:14

6
사용의 또 다른 이점 const은 인용 부호가 없다는 것입니다. 즉, IDE에서 사용되는 위치와 동일하게 형식이 지정됩니다.
rybo111

3
이것은 PHP 문서에있는 것이어야합니다. 내가 본 최고의 설명, 특히 대부분의 사람들이 잊어 버린 부분 (컴파일 대 런타임).
제임스

4
define('a', $_GET['param']);, const b = a;완벽하게 작동하고 const c = $_GET['param'];유효하지 않은 동안 값을 얻습니다 . 가 const정말 컴파일 시간은? 나는 그렇게 생각하지 않습니다 ... (PHP 7.0.7에서 테스트)
mcserep

1
wiki.php.net/rfc/case_insensitive_constant_deprecation " PHP 8.0 : 대소 문자를 구분하지 않는 상수를 선언 할 가능성을 제거하십시오. " 대소 문자 구분 과 관련하여 미래에
벤트

196

PHP 5.3까지는 const글로벌 스코프에서 사용할 수 없었습니다. 클래스 내에서만 사용할 수 있습니다. 일정 종류의 상수 옵션을 설정하거나 해당 클래스와 관련된 설정을하려는 경우에 사용해야합니다. 또는 일종의 열거 형을 만들고 싶을 수도 있습니다.

define동일한 목적으로 사용될 수 있지만 전역 범위에서만 사용할 수 있습니다. 전체 응용 프로그램에 영향을 미치는 전역 설정에만 사용해야합니다.

좋은 const사용법 의 예는 매직 넘버를 제거하는 것입니다. PDO의 상수를 살펴보십시오 . 페치 유형을 지정해야하는 경우 예를 들어을 입력합니다 PDO::FETCH_ASSOC. const가 사용되지 않으면 다음과 같이 입력 35하거나 FETCH_ASSOC정의 된 내용을 입력하게됩니다 . 독자에게는 이치에 맞지 않습니다.

좋은 define사용법 의 예는 응용 프로그램의 루트 경로 또는 라이브러리의 버전 번호를 지정하는 것입니다.


12
const네임 스페이스와 함께 사용하는 것이 좋습니다 .
salathe

31
PHP5.3은 전역 범위에서 const를 매우 많이 사용할 수 있습니다.
Gordon

5.2도 가능합니다. const 대 vs 정의의 장점은 클래스 이름을 접두사로 사용해야한다는 것입니다. 그것들을 사용하면 코드를 더 읽기 쉽고 더 예쁘게 만듭니다. 그리고 그것은 나에게 보너스입니다.
lucifurious

1
@ryeguy 그러나 PHP 5.3 이후 const는 정의처럼 전역 적으로 사용할 수 있습니까?
andho

1
@andho, 한 단계 앞으로, 한 단계 뒤로, "개선"의 춤으로 PHP 댄스에 또 다른 것을 올리십시오. 그. :)
Falken 교수 교수는

37

나는 이것이 이미 답변되었지만 현재 답변 중 어느 것도 네임 스페이스에 대해 언급하지 않으며 상수와 정의에 미치는 영향에 대해 언급하지 않습니다.

PHP 5.3부터 const와 정의는 대부분 비슷합니다. 그러나 여전히 몇 가지 중요한 차이점이 있습니다.

  • 표현식에서 상수를 정의 할 수 없습니다. const FOO = 4 * 3;작동하지 않지만 작동 define('CONST', 4 * 3);합니다.
  • 전달 된 이름 define은 해당 네임 스페이스 내에 정의 할 네임 스페이스를 포함해야합니다.

아래 코드는 차이점을 설명해야합니다.

namespace foo 
{
    const BAR = 1;
    define('BAZ', 2);
    define(__NAMESPACE__ . '\\BAZ', 3);
}

namespace {
    var_dump(get_defined_constants(true));
}

사용자 하위 배열의 내용은입니다 ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3].

=== 업데이트 ===

다가오는 PHP 5.6은와 약간의 유연성을 허용합니다 const. 이제 표현식이 다른 const 또는 리터럴로 구성된 경우 표현식 측면에서 const를 정의 할 수 있습니다. 이는 다음이 5.6부터 유효해야 함을 의미합니다.

const FOOBAR = 'foo ' . 'bar';
const FORTY_TWO = 6 * 9; // For future editors: THIS IS DELIBERATE! Read the answer comments below for more details
const ULTIMATE_ANSWER = 'The ultimate answer to life, the universe and everything is ' . FORTY_TWO;

그래도 변수 또는 함수 반환 측면에서 const를 정의 할 수는 없으므로

const RND = mt_rand();
const CONSTVAR = $var;

여전히 나갈 것입니다.


8
나는 묻는 것에 저항 할 수 없었다 : 당신은 의식적 FORTY_TWO으로 54로 정의 했습니까 ?
Punchlinern

9
"6시 9 분? 42시? 나는 항상 우주에 근본적으로 문제가 있다고 말 했어요."더 자세한 설명이 필요하다면 Douglas Adams의 작품을 확인하십시오.
GordonM

2
오. 나는 42가 대답의 삶, 우주, 그리고 모든 것을 제외하고는 여섯 부분을 아홉 부분으로 놓쳤다는 것을 알고있었습니다. 설명 주셔서 감사합니다!
Punchlinern


20

define 전역 상수에 사용합니다.

const 클래스 상수에 사용합니다.

define수업 범위에 들어갈 수 없으며 함께 const할 수 있습니다. 말할 것도없이, 당신은 사용할 수 없습니다const 교실 밖에서 .

또한을 사용 const하면 실제로 클래스의 멤버 define가되고을 사용하면 전역 범위로 푸시됩니다.


8
다른 답변에서 언급했듯이 const는 PHP 5.3 이상에서 클래스 외부에서 사용할 수 있습니다.
MrWhite

const 키워드 만이 클래스뿐만 아니라 네임 스페이스 상수를 생성하는데 사용될 수 있습니다
Alireza Rahmani Khalili

16

NikiC의 답변이 가장 좋지만 네임 스페이스를 사용할 때 분명하지 않은 경고를 추가하여 예기치 않은 동작에 걸리지 않도록합니다. 기억해야 할 것은 정의 식별자의 일부로 네임 스페이스를 명시 적으로 추가하지 않는 한, 정의는 항상 글로벌 네임 스페이스에 있다는 것 입니다. 분명하지 않은 것은 네임 스페이스 식별자가 글로벌 식별자보다 우선한다는 것입니다. 그래서 :

<?php
namespace foo
{
  // Note: when referenced in this file or namespace, the const masks the defined version
  // this may not be what you want/expect
  const BAR = 'cheers';
  define('BAR', 'wonka');

  printf("What kind of bar is a %s bar?\n", BAR);

  // To get to the define in the global namespace you need to explicitely reference it
  printf("What kind of bar is a %s bar?\n", \BAR);
}

namespace foo2
{
  // But now in another namespace (like in the default) the same syntax calls up the 
  // the defined version!
  printf("Willy %s\n", BAR);
  printf("three %s\n", \foo\BAR);  
}
?>

생산 :

What kind of bar is a cheers bar? 
What kind of bar is a wonka bar?
willy wonka 
three cheers

수십 개의 다른 언어로 된 const의 개념은 코드의 어느 위치에서나 항상 동일하고 PHP가 실제로 그것을 보장하지 않기 때문에 전체 const 개념을 불필요하게 혼란스럽게 만듭니다.


1
그래,하지만 BAR\foo\BAR단지입니다 하지 같은 상수. 나는 정말 혼란 동의하지만, 당신은 또한 네임 스페이스 지정 논리가 이런 식으로 일관되고 같은 것들을 고려하고, 어느 쪽도 있다는 경우 constdefine()는 C처럼 매크로 ( #define), 다음 PHP는 어떤 변명을 가질 수 없습니다.
Sz.

1
const 개념은 정확히 동작하는 방식입니다. 네임 스페이스에 있습니다! 네임 스페이스 식별자없이 원하는 경우 네임 스페이스 외부에서 생성합니다. 이렇게하면 다른 구문을 사용하더라도 클래스에 정의 된 const와 일치하게됩니다. 예, 정의도 다른 방식으로 일관성이 있습니다.
Gerard ONeill

12

이 답변의 대부분은 틀리거나 절반 만 이야기하고 있습니다.

  1. 네임 스페이스를 사용하여 상수 범위를 지정할 수 있습니다.
  2. 클래스 정의 외부에서 "const"키워드를 사용할 수 있습니다. 그러나 클래스에서와 마찬가지로 "const"키워드를 사용하여 지정된 값은 상수 표현식이어야합니다.

예를 들면 다음과 같습니다.

const AWESOME = 'Bob'; // Valid

나쁜 예 :

const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic) 
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)

변수 상수를 만들려면 다음과 같이 define ()을 사용하십시오.

define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid

1
PHP> = 5.6 Zend Engine Compiler에서 일부 변경이 이루어졌으며 const는 현재 다른 방식으로 처리되고 있습니다.
Ankit Vishwakarma

6

예, const는 컴파일 타임에 정의되며, nikic 상태에 define ()의 can처럼 표현식을 할당 할 수 없기 때문에. 그러나 const도 조건부로 선언 할 수 없습니다 (같은 이유로). 즉. 너는 이것을 못해:

if (/* some condition */) {
  const WHIZZ = true;  // CANNOT DO THIS!
}

define ()으로 할 수있는 반면. 따라서 실제로 개인 취향에 미치지는 않으며, 둘 다 사용하는 정확하고 잘못된 방법이 있습니다.

옆으로 ... 식에 할당 할 수있는 일종의 클래스 const, 클래스에 격리 될 수있는 일종의 define ()을보고 싶습니다.


5

NikiC의 답변을 추가하십시오. const클래스 내에서 다음과 같은 방식으로 사용할 수 있습니다.

class Foo {
    const BAR = 1;

    public function myMethod() {
        return self::BAR;
    }
}

으로이 작업을 수행 할 수 없습니다 define().


4

아무도 php-doc에 대해 아무 말도하지 않지만 나에게 그것은 또한 선호도에 대한 매우 중요한 주장입니다 const.

/**
 * My foo-bar const
 * @var string
 */
const FOO = 'BAR';

0

키워드 상수를 정의하면 대소 문자를 구분하지 않지만 const 키워드를 사용하지 않은 기능을 얻을 수 있습니다.

define("FOO", 1, true);
echo foo; //1
echo "<br/>";
echo FOO; //1
echo "<br/>";

class A {
  const FOO = 1;
}

echo A::FOO; //valid
echo "<br/>";

//but

class B {
  define FOO = 1; //syntax error, unexpected 'define'
}

echo B::FOO; //invalid
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.