PHP에서 언제 사용합니까
define('FOO', 1);
언제 사용합니까
const FOO = 1;
?
이 둘의 주요 차이점은 무엇입니까?
PHP에서 언제 사용합니까
define('FOO', 1);
언제 사용합니까
const FOO = 1;
?
이 둘의 주요 차이점은 무엇입니까?
답변:
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);
}
const
s는 항상 대소 문자를 구분하지만 세 번째 인수로 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
}
요약
조건부 또는 표현 정의 유형이 필요하지 않은 경우 가독성을 위해 const
s 대신 s를 사용 define()
하십시오!
const
언어 구성 에서도 간단한 스칼라 식을 사용할 수 있습니다. wiki.php.net/rfc/const_scalar_exprs
const
은 인용 부호가 없다는 것입니다. 즉, IDE에서 사용되는 위치와 동일하게 형식이 지정됩니다.
define('a', $_GET['param']);
, const b = a;
완벽하게 작동하고 const c = $_GET['param'];
유효하지 않은 동안 값을 얻습니다 . 가 const
정말 컴파일 시간은? 나는 그렇게 생각하지 않습니다 ... (PHP 7.0.7에서 테스트)
PHP 5.3까지는 const
글로벌 스코프에서 사용할 수 없었습니다. 클래스 내에서만 사용할 수 있습니다. 일정 종류의 상수 옵션을 설정하거나 해당 클래스와 관련된 설정을하려는 경우에 사용해야합니다. 또는 일종의 열거 형을 만들고 싶을 수도 있습니다.
define
동일한 목적으로 사용될 수 있지만 전역 범위에서만 사용할 수 있습니다. 전체 응용 프로그램에 영향을 미치는 전역 설정에만 사용해야합니다.
좋은 const
사용법 의 예는 매직 넘버를 제거하는 것입니다. PDO의 상수를 살펴보십시오 . 페치 유형을 지정해야하는 경우 예를 들어을 입력합니다 PDO::FETCH_ASSOC
. const가 사용되지 않으면 다음과 같이 입력 35
하거나 FETCH_ASSOC
정의 된 내용을 입력하게됩니다 . 독자에게는 이치에 맞지 않습니다.
좋은 define
사용법 의 예는 응용 프로그램의 루트 경로 또는 라이브러리의 버전 번호를 지정하는 것입니다.
const
네임 스페이스와 함께 사용하는 것이 좋습니다 .
나는 이것이 이미 답변되었지만 현재 답변 중 어느 것도 네임 스페이스에 대해 언급하지 않으며 상수와 정의에 미치는 영향에 대해 언급하지 않습니다.
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;
여전히 나갈 것입니다.
FORTY_TWO
으로 54로 정의 했습니까 ?
PHP 5.3부터 const
두 번째 예제에서 볼 수 있듯이 클래스 외부에서 사용할 수 있다고 생각합니다 .
http://www.php.net/manual/en/language.constants.syntax.php
<?php
// Works as of PHP 5.3.0
const CONSTANT = 'Hello World';
echo CONSTANT;
?>
define
전역 상수에 사용합니다.
const
클래스 상수에 사용합니다.
define
수업 범위에 들어갈 수 없으며 함께 const
할 수 있습니다. 말할 것도없이, 당신은 사용할 수 없습니다const
교실 밖에서 .
또한을 사용 const
하면 실제로 클래스의 멤버 define
가되고을 사용하면 전역 범위로 푸시됩니다.
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 개념을 불필요하게 혼란스럽게 만듭니다.
BAR
및 \foo\BAR
단지입니다 하지 같은 상수. 나는 정말 혼란 동의하지만, 당신은 또한 네임 스페이스 지정 논리가 이런 식으로 일관되고 같은 것들을 고려하고, 어느 쪽도 있다는 경우 const
도 define()
는 C처럼 매크로 ( #define
), 다음 PHP는 어떤 변명을 가질 수 없습니다.
이 답변의 대부분은 틀리거나 절반 만 이야기하고 있습니다.
예를 들면 다음과 같습니다.
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
예, const는 컴파일 타임에 정의되며, nikic 상태에 define ()의 can처럼 표현식을 할당 할 수 없기 때문에. 그러나 const도 조건부로 선언 할 수 없습니다 (같은 이유로). 즉. 너는 이것을 못해:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
define ()으로 할 수있는 반면. 따라서 실제로 개인 취향에 미치지는 않으며, 둘 다 사용하는 정확하고 잘못된 방법이 있습니다.
옆으로 ... 식에 할당 할 수있는 일종의 클래스 const, 클래스에 격리 될 수있는 일종의 define ()을보고 싶습니다.
아무도 php-doc에 대해 아무 말도하지 않지만 나에게 그것은 또한 선호도에 대한 매우 중요한 주장입니다 const
.
/**
* My foo-bar const
* @var string
*/
const FOO = 'BAR';
키워드 상수를 정의하면 대소 문자를 구분하지 않지만 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
const
두 배 빠른 속도로보다define
. 페이지로드 시간 및 메모리 사용량 정보 : 이 질문 및 이 기사를 참조 하십시오 . opcode 캐시에 대한 내용도 여기를 참조 하십시오 .