In response to tudor at tudorholton dot com
10-Jul-2007 02:15
The error message does not give incorrect information.
The error indeed is that you did not quote the constant name and PHP tries therefore to use it as a constant.
Since it is not defined, PHP assumes that you meant to quote it and evaluates it as a string.
While this is invalid :
<?php
define( MY_CONST, 'blah');
?>
This will work :
<?php
define( 'CONST_NAME', 'MY_CONST' );
define( CONST_NAME, 'blah');
var_dump( CONST_NAME ); // output : string(8) "MY_CONST"
var_dump( MY_CONST ); // output : string(4) "blah"
?>
상수
Table of Contents
상수는 단순한 값을 위한 식별자(이름)이다. 이름이 제시하는것과 같이, 이 값은 스크립트 실행중에는 변경될수 없다. (실질적으로 상수가 아닌 magic constants 을 제외하고) 상수는 기본적으로 대소문자를 구별한다. 관례상, 상수 식별자는 항상 대문자이다.
PHP에서 상수명은 같은 규칙을 따른다. 유효한 상수명은 문자나 밑줄(underscore) 로 시작하고 다른 문자나 숫자, 밑줄이 뒤를 따른다. 정규식으로는 다음처럼 표현할수 있다: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
Note: 여기서 문자는 a-z, A-Z와 아스키(ASCII)문자 127에서 255까지이다 (0x7f-0xff).
superglobals처럼 상수의 유효범위(scope)는 전역적이다. 유효범위에 상관없이 스크립트의 어느곳에서도 상수를 참조할수 있다. 상수에 관한 더 자세한 정보를 위해 변수 유효범위(variable scope) 매뉴얼 섹션을 참고합니다.
문법
define()함수를 써서 상수를 정의(define)할수 있다. 상수는 한번 정의되면 절대 변경하거나 해제(undefine)할수 없다.
스칼라 데이터(boolean, integer, float 과 string)만 상수의 값으로 쓸수있다.
단순히 상수명을 써서 상수값을 얻을 수 있다. 변수와는 달리 $가 상수명 앞으로 오면 안된다 동적으로 상수명을 취하려한다면 constant()함수로 상수값을 가져올수 있다. 정의된 모든 상수 목록을 구하려면 get_defined_constants() 함수를 쓴다.
Note: 상수와 (전역)변수는 서로 다른 네임스페이스(namespace)상에 있다. 이말의 의미는 예를 들면 TRUE와 $TRUE은 일반적으로 다르다는것이다.
해제된 상수를 사용한다면, PHP는 상수명 자체를 쓴것이라고 가정할것이다 즉,string으로 인식할것이다. (CONSTANT vs "CONSTANT") E_NOTICE로 이런 일이 발생했는지 알수 있다. 왜 $foo[bar]가 잘못됐는지 (bar를 상수로 define() 하지않았다면) 매뉴얼을 참고한다. 단순히 상수가 설정되었는지만 확인하려 한다면 defined()함수를 쓰면 됩니다.
다음은 상수와 변수의 차이점이다:
- 상수는 이름 앞에 달러표시($)가 없다.
- 상수는 단순 지정(assingment)이 아니라 define() 함수로만 정의될수 있다.
- 상수는 변수의 유효범위 규칙과는 상관없이 어느곳에서든 정의되거나 값을 취할수 있다.
- 상수는 한번 설정되면 재정의하거나 해제할수 없을것이다; 그리고
- 상수는 스칼라 값만 쓸수 있다.
Example#1 상수 정의하기
<?php
define("CONSTANT", "Hello world.");
echo CONSTANT; // "Hello world."을 출력한다
echo Constant; // "Constant"를 출력하고 경고가 뜬다.
?>
상수
22-Apr-2008 04:25
27-Nov-2007 03:14
I recently found I needed a way of retrieving the value of a constant dynamically - e.g. trying to find the value of FOO_BAR by passing 'FOO_' . $someVariableWithValueBAR. I came up with the following solution:
<?php
define('FOO_BAR','It works!');
define('FOO_FOO_BAR','It works again!');
// prints 'It works!'
$changing_variable = 'bar';
echo constant('FOO_' . strtoupper($changing_variable));
// prints 'It works again!'
$changing_variable = 'foo_bar';
echo constant('FOO_' . strtoupper($changing_variable));
?>
Note the use of strtoupper() as constants should be defined in uppercase for good practice - feel free to remove if you have constants defined in lowercase or you can set $changing_variable as uppercase.
Might be of some use to someone!
30-Jul-2007 11:39
Ah, I forgot to point that out in my previous note:
> "Constants may only evaluate to scalar values."
Currently, resources are "abstract datatypes based on integers".
Though this may change in the future, and is_scalar() rejects resources as non-scalar, you can define resource constants, like
<?php define('DB', mysql_connect());?>
(think of STDIN, STDOUT and STDERR).
Resource constants will still remain resources; try var_dump().
19-Jul-2007 12:27
> "A valid constant name starts with a letter or underscore, followed by any number of letters, numbers, or underscores."
This rules only applies when using constants like <?php echo CONSTANT;?> to not confuse the parser - PHP will be happy with any string for a constant name (define).
<?php
define('Red herring!', '<°)))><');
#echo Red herring!;
// The above example will not work, the parser will get
// angry seeing a whitespace where it shouldn’t be.
// Let’s have that with constant():
echo constant('Red herring!'); // <°)))><
?>
You could go on with newlines, tabs and stuff... that is, however, crude coding style.
09-Jul-2007 05:15
Note that constant name must always be quoted when defined.
e.g.
define('MY_CONST','blah') - correct
define(MY_CONST,'blah') - incorrect
The following error message also indicates this fact:
Notice: Use of undefined constant MY_CONST - assumed 'MY_CONST' in included_script.php on line 5
Note the error message gives you some incorrect information. 'MY_CONST' (with quotes) doesn't actually exist anywhere in your code. The error _is_ that you didn't quote the constant when you defined it in the 'assumed' file.
30-Apr-2007 07:19
If you are looking for predefined constants like
* PHP_OS (to show the operating system, PHP was compiled for; php_uname('s') might be more suitable),
* DIRECTORY_SEPARATOR ("\\" on Win, '/' Linux,...)
* PATH_SEPARATOR (';' on Win, ':' on Linux,...)
they are buried in 'Predefined Constants' under 'List of Reserved Words' in the appendix:
http://www.php.net/manual/en/reserved.constants.php
while the latter two are also mentioned in 'Directory Functions'
http://www.php.net/manual/en/ref.dir.php
18-Feb-2007 09:46
Note that constants can also be used as default argument values
so the following code:
define('TEST_CONSTANT','Works!');
function testThis($var=TEST_CONSTANT) {
echo "Passing constants as default values $var";
}
testThis();
will produce :
Passing constants as default values Works!
(I tried this in both PHP 4 and 5)
05-Sep-2006 04:02
1) Constants are invaluable when you want to be sure that *nobody* changes your important piece of data through lifetime of script -- especially when you're developing in team -- as this can cause strange, hard to track bugs.
2) Using constants is prefered over ``magic values'', as it leads to self-documenting code. Also saves you from scanning and tweaking tens of files should the value ever change.
Consider example: <?php
if ( $headers['code'] = 505 ) { //wth is 505? What do following code do? ?>
versus: <?php
if ( $headers['code'] = HTTP_VERSION_NOT_SUPPORTED ) {
$this->useHttp = '1.0'; ?>
In response to ``kencomer'':
3) Why not to use <?php
define( 'DEBUG', FALSE );
define( 'DEBUG', TRUE ); ?>
and comment one of them out as needed when developing/deploying?
That'd save a lot of ugly ``if ( defined( 'DEBUG' ) && DEBUG ) {}''.
4) For debugging toggled on/off you pretty often want to use assert() anyway. You're free to turn it on/off at any moment (thou you better do it only once ;) ). assert() gives some nice details upon failed assertion, like file/line/function and context (that's invaluable!)
23-Feb-2006 02:24
I find variables much more flexible than constants because variables can be used inside quotes and heredocs etc. Especially for language systems, this is nice.
As stated in one of the previous notes, there is no speed penalty by using variables. However, one issue is that you risc name collision with existing variables. When implementing a language system I simply found that adding a prefix to all the variables was the way to go, for example:
$LNG_myvar1 = "my value";
That is easier and performs faster than using arrays like
$LNG['myvar'] = "my value";
As a final note, implementing a new superglobal in PHP would make using constants much more beneficial. Then it could be used in qoutes like this:
"The constant myconst has the value $CONSTANTS[myconst] !"
20-Dec-2005 08:42
It is possible to define constants that have the same name as a built-in PHP keyword, although subsequent attempts to actually use these constants will cause a parse error. For example in PHP 5.1.1, this code
<?php
define("PUBLIC", "Hello, world!");
echo PUBLIC;
?>
gives the error
Parse error: syntax error, unexpected T_PUBLIC in test.php on line 3
This is a problem to be aware of when converting PHP4 applications to PHP5, since that release introduced several new keywords that used to be legal names for constants.
14-Sep-2005 05:38
Being a belt and suspenders person, when I use a constant to do flow control (i.e., using constants to determine which version of a section of the program should be used), I always use something like:
if ( defined('DEBUG') && TRUE===DEBUG )
If you accidentally use DEBUG somewhere before it is defined, PHP will create a new constant called DEBUG with the value 'DEBUG'. Adding the second comparison will prevent the expression from being TRUE when you did not intentionally create the constant. For the constant DEBUG, this would rarely be a problem, but if you had (e.g.) a constant used to determine whether a function was created using case-sensitive comparisons, an accidental creation of the constant IGNORE_CASE having the value 'IGNORE_CASE' could drive you up the wall trying to find out what went wrong, particularly if you had warnings turned off.
In almost all code I write, I put this function definition in my configuration section:
if (!function_exists("debug_print")) {
if ( defined('DEBUG') && TRUE===DEBUG ) {
function debug_print($string,$flag=NULL) {
/* if second argument is absent or TRUE, print */
if ( !(FALSE===$flag) )
print 'DEBUG: '.$string . "\n";
}
} else {
function debug_print($string,$flag=NULL) {
}
}
}
Then, in my code, I'll sprinkle liberal doses of debug code like :
define("DEBUG_TRACK_EXAMPLE_CREATION",FALSE);
class Example extends Something {
__construct($whatever) {
debug_print( "new instance of Example created with '$whatever'\n",DEBUG_TRACK_EXAMPLE_CREATION);
}
}
and :
debug_print("finished init.\n")
In the first case, I would not want to see that message every time I went into DEBUG mode, so I made it a special case. The second case is always printed in DEBUG mode. If I decide to turn everything on, special cases and all, all I have to do is comment out the "if" line in debug_print() and presto magicko! It costs a little and gains a lot.
As another belt-and-suspenders aside, notice that, unlike most people, I put the language constant (e.g.,TRUE, "string", etc.) on the left side of the comparison. By doing that, you can never accidentally do something like
if ( $hard_to_find_error="here" )
because you always write it as
if ( "here"==$no_error )
or, if you got it wrong,
if ( "here"=$easy_to_find_parse_error )
01-Sep-2005 02:11
It took me almost 30 minutes to find out what was wrong in my code. I thought I had defined all constants correctly: correct quotes, and whatnot.
The problem: I am a C programmer and I used #define with the preprocessor hash sign! No effect, naturally.
So if you happen to come from C world and you program PHP, *DO NOT* use the preprocessor hash as you're used to in C.
25-Jul-2005 12:39
It is so easy to create a constant that the php novice might do so accidently while attempting to call a function with no arguments. For example:
<?php
function LogoutUser(){
// destroy the session, the cookie, and the session ID
blah blah blah;
return true;
}
function SessionCheck(){
blah blah blah;
// check for session timeout
...
if ($timeout) LogoutUser; // should be LogoutUser();
}
?>
OOPS! I don't notice my typo, the SessionCheck function
doesn't work, and it takes me all afternoon to figure out why not!
<?php
LogoutUser;
print "new constant LogoutUser is " . LogoutUser;
?>
27-May-2005 07:23
Re: Storm.
I ran that code (in PHP4)
<?php
if (DEBUG) {
// echo some sensitive data.
}
?>
and saw this warning:
"Use of undefined constant DEBUG - assumed 'DEBUG'"
A clearer workaround is to use
<?php
if (defined('DEBUG')) {
// echo some sensitive data.
}
?>
Thanks for pointing out this big gotcha.
Another reason to turn on warnings during testing. Good web servers are set up to suppress warning and error output to the browser, so this is handy:
<?php
if (defined('DEBUG')) {
error_reporting(E_ALL);
set_error_handler('debug_ErrorHandler');
}
function debug_ErrorHandler($errno, $errstr, $errfile, $errline) {
print("PHP Error [$errno] [$errstr] at $errline in $errfile.<br>");
}
?>
21-Apr-2005 02:09
PHP Modules also define constants. Make sure to avoid constant name collisions. There are two ways to do this that I can think of.
First: in your code make sure that the constant name is not already used. ex. <?php if (! defined("CONSTANT_NAME")) { Define("CONSTANT_NAME","Some Value"); } ?> This can get messy when you start thinking about collision handling, and the implications of this.
Second: Use some off prepend to all your constant names without exception ex. <?php Define("SITE_CONSTANT_NAME","Some Value"); ?>
Perhaps the developers or documentation maintainers could recommend a good prepend and ask module writers to avoid that prepend in modules.
18-Apr-2005 09:54
An undefined constant evaluates as true when not used correctly. Say for example you had something like this:
settings.php
<?php
// Debug mode
define('DEBUG',false);
?>
test.php
<?php
include('settings.php');
if (DEBUG) {
// echo some sensitive data.
}
?>
If for some reason settings.php doesn't get included and the DEBUG constant is not set, PHP will STILL print the sensitive data. The solution is to evaluate it. Like so:
settings.php
<?php
// Debug mode
define('DEBUG',0);
?>
test.php
<?php
include('settings.php');
if (DEBUG == 1) {
// echo some sensitive data.
}
?>
Now it works correctly.
12-Jan-2005 01:50
To clarify from the previous post:
When you define a constant, it becomes fixed at that point and is immutable. You can add variables - but the constant becomes the contents of that variable when the define is evaluated. If you try:
define( "_A_TEXT" , "The value is " . $arr[$i] );
It would be evaluated ONCE with the current value of the $i index of array $arr. As the post pointed out, this is probably not what you want. You can easily create:
define( "_A_TEXT" , "The value is ");
....
echo _A_TEXT . $arr[$i];
Which would give you what you wanted: the constant string with the contents of the array appended.
24-Jun-2004 01:42
I'm currently working on a site that has got to have two languages, and I wanted to use define's in functions to make everything simpler.
However, I ran into a problem. PHP doesn't recognize the variable in:
define("constantName", "This is an array variable - {$array[$i][2]}");
I can't use that in a for cycle, like I wanted to:
for ($i = 0; $i < count($array); $i++) {
echo constantName . "<br />"
}
The method I found (I think it's been mentioned before) is to:
define("constantName", "This is an array variable - %s");
And then:
for ($i = 0; $i < count($array); $i++) {
printf(constantName, $array[$i][2]);
}
25-Oct-2003 05:59
before embarking on creating a language system I wanted to see if there was any speed advantage to defining language strings as constants vs. variables or array items. It is more logical to define language strings as constants but you have more flexibility using variables or arrays in your code (i.e. they can be accessed directly, concatenated, used in quotes, used in heredocs whereas constants can only be accessed directly or concatenated).
Results of the test:
declaring as $Variable is fastest
declaring with define() is second fastest
declaring as $Array['Item'] is slowest
=======================================
the test was done using PHP 4.3.2, Apache 1.3.27, and the ab (apache bench) tool.
100 requests (1 concurrent) were sent to one php file that includes 15 php files each containing 100 unique declarations of a language string.
Example of each declaration ("Variable" numbered 1 - 1500):
<?php
$GLOBALS['Variable1'] = "A whole lot of text for this variable as if it were a language string containing a whole lot of text";
?>
<?php
define('Variable1' , "A whole lot of text for this variable as if it were a language string containing a whole lot of text");
?>
<?php
$GLOBALS['CP_Lang']['Variable1'] = "A whole lot of text for this variable as if it were a language string containing a whole lot of text";
?>
Here are the exact averages of each ab run of 100 requests (averages based on 6 runs):
variable (24.956 secs)
constant (25.426 secs)
array (28.141)
(not huge differences but good to know that using variables won't take a huge performance hit)
18-Aug-2003 06:30
I find using the concatenation operator helps disambiguate value assignments with constants. For example, setting constants in a global configuration file:
define('LOCATOR', "/locator");
define('CLASSES', LOCATOR."/code/classes");
define('FUNCTIONS', LOCATOR."/code/functions");
define('USERDIR', LOCATOR."/user");
Later, I can use the same convention when invoking a constant's value for static constructs such as require() calls:
require_once(FUNCTIONS."/database.fnc");
require_once(FUNCTIONS."/randchar.fnc");
as well as dynamic constructs, typical of value assignment to variables:
$userid = randchar(8,'anc','u');
$usermap = USERDIR."/".$userid.".png";
The above convention works for me, and helps produce self-documenting code.
-- Erich
24-Jul-2003 07:04
Late reply to fmmarzoa at gmx dot net: You're better off using sprintf format and defining your strings like this:
define('strArticleDescr', 'Published by %1$s on %2$s in %2$s');
It's more standard than what you're doing. Then instead of outputting it using an eval, do this:
echo sprintf(strArticleDescr, $article_author, $article_date, $article_lang_name');
And even better for i18n and l10n, don't use defines; use gettext. See the PHP manual section on gettext and the GNU gettext website. Gettext requires some modification of the way you think about strings but I find it worthwhile to make that adjustment.
24-Mar-2003 08:46
In response to the notes above about variable references in constants, double quotes isn't a proper solution because it parses the variable at the time the constant is defined. The desired behavior is to have the variables parsed at the time the constant is referenced, and this behavior can really only be achieved by using eval(), as described above.
05-Nov-2002 08:08
fmmarzoa: In PHP 4.2.2/CLI, I had no problem setting define()'s to the contents of variables:
<?
$foo = "PHP";
define( "bar", "$foo is a good thing." );
print bar;
?>
Will print "PHP is a good thing.".
A notable difference, however, between my example and yours is your use of single-quotes. Strings in single quotes (') will not be expanded:
print '$foo';
Will print '$foo', not the contents of $foo.
http://www.php.net/manual/en/language.types.string.php
--gv
23-Mar-2002 09:08
The __FILE__ constant in 4.2rc1 (CLI) will return the location of script specified to be run, rather than the absolute file.
eg. /usr/bin/phpmole (a softlink to /usr/lib/php/phpmole/phpmole.php)
started like this
bash#/usr/bin/phpmole
the line echo __FILE__ in phpmole.php will output /usr/bin/phpmole - in the CGI it would have returned /usr/lib/php/phpmole/phpmole.php
the workaround is to check for links!!
$f = __FILE__;
if (is_link($f)) $f = readlink($f);
25-Feb-2002 11:53
Warning, constants used within the heredoc syntax (http://www.php.net/manual/en/language.types.string.php) are not interpreted!
Editor's Note: This is true. PHP has no way of recognizing the constant from any other string of characters within the heredoc block.
10-Jun-2001 10:42
The pre-defined constant '__FILE__' does not work in same way at every version of PHP.
Some version of PHP has the relative path, and some other has the absolute path on __FILE__ constant..
Please be carefull in use..
[PS]
I have not tested at all versions of PHP but the version of 4.04pl.. and 4.05 are certainly not working in same way.. If you want to see that bug(?), I can show you an example.
23-Jan-2001 05:54
It may be useful to note that, in php4 (what version this started I don't know, but it didn't do it before we upgraded to php4) __FILE__ will follow symlinks to the origional file.
04-Aug-2000 05:44
To get a full path (the equivalent of something like "__PATH__") use
dirname($SCRIPT_FILENAME)
to get the directory name of the called script and
dirname(__FILE__)
to get the directory name of the include file.
