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 validconst일반 상수 이름을 사용하지만 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()하십시오!
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 캐시에 대한 내용도 여기를 참조 하십시오 .