23.07.2020

Frequently Asked Questions (FAQ): Things you need to know about namespaces. Constants Creating php constants


This post will focus on constants. As usual, let's deal with the very concept of constants in programming languages ​​and see how they are declared and used constants in PHP.

Understanding Constants and Constants in PHP

The word constant should be familiar to you from mathematics:

“Mathematical constant- a value whose value does not change. "

It's the same in PHP. Constant in PHP- This is an identifier that serves to designate a simple value (string, number, whatever), which cannot be changed during the execution of the code.

To declare a constant (assign a value to it), use the function define... An example of declaring a constant:

Constant names in PHP are case sensitive (uppercase and lowercase letters are different), so you need to be careful. There is also a convention that constant names are always uppercase.

A constant name must start with a letter or underscore “_” and can be composed of letters, numbers, and underscores.

Let's look at a simple example of using a constant:

In this example, we declared a constant and used it in the program.

What are constants used for and isn't it easier to use variables?

As already mentioned, constants cannot change their value during program execution. Constants usually store constant site parameters, such as database access credentials (host, username and password, database name), site location on disk, and many other settings.

If we use variables, then the script can accidentally (in case of an error) change the value of the variable and will not work as you intended.

The use of constants ensures that the value you specified when declaring the constant remains unchanged.

Constants are values ​​that do not change over time. Even from school, you probably know many constants, for example, the number P, number e, acceleration of free fall and others. And, of course, when programming, it is also very often necessary to enter constants... And how create and use constants in PHP, we will talk in this article.

Let's go with you create a constant the numbers P:

define (PI, 3.1415926);
echo PI;
?>

Operator define creates constant PI and assigns a value to it 3.1415926 ... Then we output this constant through the operator echo... Everything is very simple, however, there is one recommendation that I advise you to always follow. Be sure to write constants in capital letters. Not that it is necessary, but highly desirable. And this is accepted not only in PHP, but in other languages ​​too.

Of course, subsequently change constant PI will not be possible (that's why it constant).

Now let's analyze one function that checks: " Is the given constant defined". Let's write a script like this:

if (! defined ("PI")) define (PI, 3.1415926);
echo PI;
?>

Here the existence of a constant is checked PI... And if it doesn't exist (i.e. define () function returned false), then we initialize this constant. Then we just display it.

As you can see, create and use your constants in PHP- it's very simple.

And, finally, I want to talk about already PHP built-in constants... Let's write a simple script with you:

phpinfo ();
?>

Towards the end there is a section " PHP Variable". Actually, this is not quite constants however, they are constants when executing this script. Of course, when another script is executed, they will already have different values ​​(not all, of course). Let's bring out a couple with you constants, so that you understand how to work with them, because they are used insanely often:

echo $ _SERVER ["REMOTE_ADDR"];
echo "
";
echo $ _SERVER ["QUERY_STRING"];
?>

In this script, we output User's IP address that launched the script, and on the next line display the query string (for example, " index.php? id = 7"). Running a little ahead, I say that here we are working with a global array $ _SERVER... We will get acquainted with arrays later, but I think that those who have worked with arrays in other programming languages ​​will learn the syntax without any problems. As for the others constants, then work with them is similar.

In this post, we'll figure out what is the difference between declaring PHP constants using the const keyword and the define () function.

Constants in PHP are "constants" whose values ​​are specified only once and then cannot be changed. When you try to change the value, it will not change and a PHP note will appear: "Constant already defined":

Define ("FOO", "val"); define ("FOO", "val2"); // Notice: Constant already defined echo FOO; //> val

There are two ways to declare constants in PHP:

// 1 define ("NAME", "VALUE"); // 2 const NAME = "VALUE";

Each method has its own characteristics, in order to understand them, let's look at everything in stages, how and what has changed with each version of PHP.

How to create constants

PHP less than 5.3

Prior to 5.3 in PHP, constants could only be defined through define (). The const keyword has been introduced since version 5.3.

Constants can only store scalars. Scalar variables are integer, float, string, and boolean types. The array, object, and resource types are not scalar.

// scalars define ("FOO", 10); define ("FOO", 10.9); define ("FOO", "val"); define ("FOO", true); // not scalars define ("FOO", array (1)); // the constant is not set and we get Warning define ("FOO", (object) array (1)); // constant not set and get Warning

Since PHP 5.3

Appeared keyword const and now a constant can also be defined using it.

However, you cannot specify a variable, function or some kind of expression in const, but you need to pass a scalar "directly":

Const FOO = "val"; // no errors const FOO = $ var; // Parse error const FOO = home_url (); // Parse error const FOO = 5 + 10; // Parse error const FOO = "foo". "Bar"; // Parse error

Whereas for define () there are no such restrictions ...

Define ("FOO", "val"); // no errors define ("FOO", $ var); // no errors define ("FOO", home_url ()); // no errors define ("FOO", 5 + 10); // no errors define ("FOO", "foo". "bar"); // no mistakes

PHP 5.6

It became possible to specify primitive PHP expressions (expressions from scalars) into const values:

Const FOO = 1 + 2; const FOO = "foo". "bar";

It became possible to store arrays in constants:

Const FOO =; // works define ("FOO",); // PHP 5.6 doesn't work, works in PHP 7.0

Difference between define () and const

# 1 const must be declared in the top scope

Unlike define (), const must be declared at the very top of the scope because they are defined when the script is compiled. This means that they cannot be declared inside functions / loops / if statements or try / catch blocks.

If (1) (const NAME = "VALUE"; // doesn't work) // but if (1) (define ("NAME", "VALUE"); // works)

# 2 const is always case sensitive

const is always case-sensitive, while define () allows for case-insensitive constants:

Define ("NAME", "VALUE", true); echo NAME; // VALUE echo name; // VALUE

# 3 const understands only scalars

This is only valid for PHP 5.6 and below ...

const cannot be passed variables, functions, expressions, and define () can be:

Const FOO = $ var; // Parse error const FOO = home_url (); // Parse error define ("FOO", $ var); // no errors define ("FOO", home_url ()); // no mistakes

# 4 const can store arrays as of PHP 5.6 and define as of PHP 7.0

const FOO =; // works in PHP 5.6 define ("FOO",); // PHP 5.6 doesn't work, works in PHP 7.0
Comparison results

It is almost always better to define a constant using define (), because there are more options and fewer options to "catch" an error ... An exception is when you have PHP 5.6 and you need to save an array to a constant, const will help here.

PHP class constants

Declared using const only. The rules for them are as described above: they only accept scalars, they don't understand PHP variables, functions, expressions ...

Constant classes are always public - there is no private or protected status.

The declared constant belongs to the class, it does not belong to any object and is common to all objects (instances) of the class.

Class My_Class (const NAME = "VALUE"; // since PHP 5.6 you can use mathematical expressions const SEC_PER_DAY = 60 * 60 * 24; function print_name () (// access to the class constant inside the method via self (the class itself) echo self :: NAME;)) // accessing a constant outside the class // can be called from the global scope without initializing an instance of the class echo My_Class :: NAME;

Constants for classes are very similar to static properties of a class.

Class My_Class (const NAME = "VALUE"; static $ name = "VALUE" ;;) echo My_Class :: NAME; echo My_Class :: $ name;

"Magic" constants

Finally, let's remember the special PHP constants ...

PHP has nine magic constants that change their meaning depending on the context in which they are used. For example, the value of __LINE__ depends on the line in the script where this constant is specified. All magic constants are resolved at compile time, as opposed to normal constants, which are resolved at run time. The special constants are case insensitive and are listed below:

Constant Description
__LINE__ The current line number in the file.
__FILE__ The full path and name of the current file in which the constant is called.
__DIR__ PHP 5.3.0. The directory of the file in which the constant is used. Same as dirname (__ FILE__). Has no trailing slash other than the root directory.
__FUNCTION__ Function name.
__CLASS__ The name of the class. This name contains the name of the namespace in which the class was declared (for example, Foo \ Bar). Also works in traits. When used in methods of traits, is the name of the class in which these methods are used.
__TRAIT__ PHP 5.4.0. The name of the trait. This name contains the name of the namespace in which the trait was declared (for example, Foo \ Bar).
__METHOD__ The name of the class method.
__NAMESPACE__ PHP 5.3.0. The name of the current namespace.
ClassName :: class PHP 5.5.0. Fully qualified class name (including namespace). Also see :: class.

(PHP 5> = 5.3.0, PHP 7)

This list of questions is divided into two parts: general questions and some implementation specifics that are useful for a more complete understanding.

First, general questions.

  1. If I am not using namespaces, should any of this be considered important?
  2. How do I use inner or global classes in a namespace?
  3. How do I use class functions in namespaces, or constants in their own namespace?
  4. How is a name like \ my \ name or \ name converted?
  5. How is a name like my \ name converted?
  6. As an incomplete class name such as name converted?
  7. As an incomplete function name or an incomplete constant name such as name converted?

Some details of the implementation of namespaces that are useful to understand.

  1. Imported names cannot conflict with classes defined in the same file.
  2. Neither functions nor constants can be imported using the operator use.
  3. Dynamic namespace names (quoted identifiers) must escape the backslash character.
  4. You cannot refer to undefined constants using a backslash. Fatal error is displayed
  5. Can't override special constants like NULL, TRUE, FALSE, ZEND_THREAD_SAFE or ZEND_DEBUG_BUILD

If I am not using namespaces, should any of this be considered important?

No. Namespaces have no effect on any existing code in any way, or on any written code that does not contain namespaces. You can write code like this if you like:

Example # 1 Accessing global classes outside the namespace

$ a = new \ stdClass;
?>

This is functionally equivalent to the following:

Example # 2 Accessing global classes outside the namespace

$ a = new stdClass;
?>

How do I use inner or global classes in a namespace?

Example # 3 Accessing inner classes in namespaces

namespace foo;
$ a = new \ stdClass;

function test (\ ArrayObject $ typehintexample = null) ()

$ a = \ DirectoryIterator :: CURRENT_AS_FILEINFO;

// extending an inner or global class
class MyException extends \ Exception ()
?>

How do I use class functions in namespaces or constants in their own namespace?

Example # 4 Accessing inner classes, functions, or constants in namespaces

namespace foo;

class MyClass ()

// use the class from the current namespace
function test (MyClass $ typehintexample = null) ()
// another way to use the class from the current namespace
function test (\ foo \ MyClass $ typehintexample = null) ()

// extending the class from the current namespace
class Extended extends MyClass ()

// access to the global function
$ a = \ globalfunc ();

// access to the global constant
$ b = \ INI_ALL;
?>

How is a name like \ my \ name or \ name converted?

Names that start with \ are always converted to what they look like, i.e. \ my \ name- it really is my \ name, and \ Exception- it Exception.

Example # 5 Absolute names

namespace foo;
$ a = new \ my \ name (); // creates an instance of the class "my \ name"
echo \ strlen ("hi"); // calls the "strlen" function
$ a = \ INI_ALL; // variable $ a is assigned the value of the constant "INI_ALL"
?>

How is a name like my \ name converted?

Names that contain but do not start with a backslash, such as my \ name

my another name, then this synonym applies to my v my \ name.

my \ name.

Example # 6 Fully qualified names

namespace foo;
use blah \ blah as foo;

$ a = new my \ name (); // creates an instance of the class "foo \ my \ name"
foo \ bar :: name (); // calls the static method "name" in the class "blah \ blah \ bar"
my \ bar (); // calls the function "foo \ my \ bar"
$ a = my \ BAR; // assigns the variable $ a the value of the constant "foo \ my \ BAR"
?>

As an incomplete class name such as name converted?

Class names that do not contain a backslash, such as name can be converted in two different ways.

If an importing expression is present that creates a synonym name other name, this synonym applies.

Otherwise, the current namespace name is prefixed to my \ name.

Example # 7 Unqualified class names

namespace foo;
use blah \ blah as foo;

$ a = new name (); // creates an instance of the class "foo \ name"
foo :: name (); // calls the static method "name" in the class "blah \ blah"
?>

As an incomplete function name or an incomplete constant name such as name converted?

Function or constant names that do not contain a backslash, such as name can be converted in two different ways.

First, the current namespace name is prefixed to name.

Then if a constant or a function name does not exist in the current namespace, in use global constant or function name if it exists.

Example # 8 Unqualified function or constant names

namespace foo;
use blah \ blah as foo;

const FOO = 1;

function my () ()
function foo () ()
function sort (& $ a)
{
\ sort ($ a); // calls the global function "sort"
$ a = array_flip ($ a);
return $ a;
}

My (); // calls "foo \ my"
$ a = strlen ("hi"); // calls the global function "strlen" because "foo \ strlen" does not exist
$ arr = array (1, 3, 2);
$ b = sort ($ arr); // calls the function "foo \ sort"
$ c = foo (); // calls the function "foo \ foo" - no import is applied

$ a = FOO; // assigns the variable $ a the value of the constant "foo \ FOO" - no import is applied
$ b = INI_ALL; // assigns the value of the global constant "INI_ALL" to the variable $ b
?>

Imported names cannot conflict with classes defined in the same file.

The following script combinations are valid:

namespace my \ stuff;
class MyClass ()
?>

namespace another;
class thing ()
?>

namespace my \ stuff;
include "file1.php";
include "another.php";


$ a = new MyClass; // creates an instance of the class "thing" from the namespace "another"
?>

There is no name conflict even though the class MyClass exists inside the namespace my \ stuff because the definition of MyClass is in a separate file. However, the following example results in a fatal naming collision error because the MyClass class is defined in the same file as the use statement.

namespace my \ stuff;
use another \ thing as MyClass;
class MyClass () // fatal error: MyClass conflicts with import expression
$ a = new MyClass;
?>

Nested namespaces are not valid.

PHP does not allow nesting namespaces into one another

namespace my \ stuff (
namespace nested (
class foo ()
}
}
?>

However, simulate nested namespaces like this:

namespace my \ stuff \ nested (
class foo ()
}
?>

Prior to PHP 5.6, neither functions nor constants could be imported using the operator use.

Prior to PHP 5.6, the only items affected by the operator use are namespaces and class names. To shorten long constant or function names, import their contents into the namespace.

namespace mine;
use ultra \ long \ ns \ name;

$ a = name \ CONSTANT;
name \ func ();
?>

Since PHP 5.6 it has become possible to import and create pseudonyms for functions and constant names.

Dynamic namespace names (quoted identifiers) must escape the backslash character.

It is very important to represent this because the backslash is used as an escape character within strings. It must always be duplicated when used inside a string, otherwise there is a risk of unintended consequences:

Example # 9 Pitfalls when using a namespace name inside a double-quoted string

$ a = "dangerous \ name"; // \ n is a newline within a double quoted string!
$ obj = new $ a;

$ a = "not \ at \ all \ dangerous"; // no problem here.
$ obj = new $ a;
?>

Inside single quoted strings, backslash delimiters are safer, but it is still the recommended practice of escaping backslashes in all strings is the best practice.

You cannot refer to undefined constants using a backslash. Fatal error is displayed

Any undefined constant that is an incomplete name, such as FOO, will output a message that PHP assumed that FOO was the value of the constant. Any constant, fully or fully named, that contains a backslash character will result in a fatal error if not found.

Example # 10 Undefined constants

namespace bar;
$ a = FOO; // displays a warning: undefined constants "FOO" assumed "FOO";
$ a = \ FOO; // fatal error: undefined namespace constant FOO
$ a = Bar \ FOO; // fatal error: undefined namespace constant bar \ Bar \ FOO
$ a = \ Bar \ FOO; // fatal error: undefined namespace constant Bar \ FOO
?>

Can't override special constants like NULL, TRUE, FALSE, ZEND_THREAD_SAFE or ZEND_DEBUG_BUILD

Any attempt to define a namespace constant that matches the names of special built-in constants will result in a fatal error.

Example # 11 Undefined constants

namespace bar;
const NULL = 0; // Fatal error;
const true = "stupid"; // also fatal error;
// etc.
?>

7 years ago

There is a way to define a namespaced constant that is a special, built-in constant, using define function and setting the third parameter case_insensitive to false:

namespace foo;
define (__NAMESPACE__. "\ NULL", 10); // defines the constant NULL in the current namespace


?>

No need to specify the namespace in your call to define (), like it happens usually
namespace foo;
define (INI_ALL, "bar"); // produces notice - Constant INI_ALL already defined. But:

Define (__NAMESPACE__. "\ INI_ALL", "bar"); // defines the constant INI_ALL in the current namespace
var_dump (INI_ALL); // will show string (3) "bar". Nothing unespected so far. But:

Define ("NULL", 10); // defines the constant NULL in the current namespace ...
var_dump (NULL); // will show 10
var_dump (null); // will show NULL
?>

If the parameter case_insensitive is set to true
namespace foo;
define (__NAMESPACE__. "\ NULL", 10, true); // produces notice - Constant null already defined
?>

3 years ago

When creating classes or calling static methods from within namespaces using variables, you need to keep in mind that they require the full namespace in order for the appropriate class to be used; you CANNOT use an alias or short name, even if it is called within the same namespace. Neglecting to take this into account can cause your code to use the wrong class, throw a fatal missing class exception, or throw errors or warnings.

In these cases, you can use the magic constant __NAMESPACE__, or specify the full namespace and class name directly. The function class_exists also requires the full namespace and class name, and can be used to ensure that a fatal error won "t be thrown due to missing classes.

Namespace Foo;
class Bar (
public static function test () (
return get_called_class ();
}
}

namespace Foo \ Foo;
class Bar extends \ Foo \ Bar (
}

Var_dump (Bar :: test ()); // string (11) "Foo \ Foo \ Bar"

$ bar = "Foo \ Bar";
var_dump ($ bar :: test ()); // string (7) "Foo \ Bar"

$ bar = __NAMESPACE__. "\ Bar";
var_dump ($ bar :: test ()); // string (11) "Foo \ Foo \ Bar"

$ bar = "Bar";
var_dump ($ bar :: test ()); // FATAL ERROR: Class "Bar" not found or Incorrect class \ Bar used

For every script that is executed. Many of these constants are defined by various modules and will only be present if the modules are available dynamically loaded or statically built.

There are nine magic constants that change their meaning depending on the context in which they are used. For example, the value __LINE__ depends on the line in the script where this constant is specified. All magic constants are resolved at compile time, in contrast to normal constants, which are resolved at run time. The special constants are case insensitive and are listed below:

Some magic PHP constants
Name Description
__LINE__ The current line number in the file.
__FILE__ Full path and name of the current file with expanded symlinks. If used inside an include file, the name of the given file is returned.
__DIR__ File directory. If used inside an include file, then the directory of that file is returned. This is equivalent to calling dirname (__ FILE__)... The returned directory name does not end with a slash, except for the root directory.
__FUNCTION__ Function name or (closure) in the case of an anonymous function.
__CLASS__ The name of the class. This name contains the name of the namespace in which the class was declared (for example, Foo \ Bar). Note that since PHP 5.4, __CLASS__ also works in traits. When used in methods of traits, __CLASS__ is the name of the class in which these methods are used.
__TRAIT__ The name of the trait. This name contains the name of the namespace in which the trait was declared (for example, Foo \ Bar).
__METHOD__ The name of the class method.
__NAMESPACE__ The name of the current namespace.
ClassName :: class Fully qualified class name (including namespace). See also :: class.

see also get_class (), get_object_vars (), file_exists () and function_exists ().

List of changes

14 years ago

The difference between
__FUNCTION__ and __METHOD__ as in PHP 5.0.4 is that

FUNCTION__ returns only the name of the function

while as __METHOD__ returns the name of the class alongwith the name of the function

class trick
{
function doit ()
{
echo __FUNCTION__;
}
function doitagain ()
{
echo __METHOD__;
}
}
$ obj = new trick ();
$ obj-> doit ();
output will be ---- doit
$ obj-> doitagain ();
output will be ----- trick :: doitagain

13 years ago

The __CLASS__ magic constant nicely complements the get_class () function.

Sometimes you need to know both:
- name of the inherited class
- name of the class actually executed

Here "s an example that shows the possible solution:

Class base_class
{
function say_a ()
{

" ;
}

Function say_b ()
{

" ;
}

class derived_class extends base_class
{
function say_a ()
{
parent :: say_a ();
echo "" a "- said the". __CLASS__. "
" ;
}

Function say_b ()
{
parent :: say_b ();
echo "" b "- said the". get_class ($ this). "
" ;
}
}

$ obj_b = new derived_class ();

$ obj_b -> say_a ();
echo "
" ;
$ obj_b -> say_b ();

?>

The output should look roughly like this:

"a" - said the base_class
"a" - said the derived_class

"b" - said the derived_class
"b" - said the derived_class

3 years ago

Note a small inconsistency when using __CLASS__ and __METHOD__ in traits (stand php 7.0.4): While __CLASS__ is working as advertized and returns dynamically the name of the class the trait is being used in, __METHOD__ will actually prepend the trait name instead of the class name!

8 years ago

There is no way to implement a backwards compatible __DIR__ in versions prior to 5.3.0.

The only thing that you can do is to perform a recursive search and replace to dirname (__ FILE__):
find. -type f -print0 | xargs -0 sed -i "s / __ DIR __ / dirname (__ FILE __) /"

5 years ago

A lot of notes here concern defining the __DIR__ magic constant for PHP versions not supporting the feature. Of course you can define this magic constant for PHP versions not yet having this constant, but it will defeat its purpose as soon as you are using the constant in an included file, which may be in a different directory then the file defining the __DIR__ constant ... As such, the constant has lost its * magic *, and would be rather useless unless you assure yourself to have all of your includes in the same directory.

Concluding: eye catchup at gmail dot com "s note regarding whether you can or cannot define magic constants is valid, but stating that defining __DIR__ is not useless, is not!

7 years ago

You cannot check if a magic constant is defined. This means there is no point in checking if __DIR__ is defined then defining it. `defined (" __ DIR __ ")` always returns false. Defining __DIR__ will silently fail in PHP 5.3+. This could cause compatibility issues if your script includes other scripts.

echo (defined ("__DIR__")? "__DIR__ is defined": "__DIR__ is NOT defined". PHP_EOL);
echo (defined ("__FILE__")? "__FILE__ is defined": "__FILE__ is NOT defined". PHP_EOL);
echo (defined ("PHP_VERSION")? "PHP_VERSION is defined": "PHP_VERSION is NOT defined"). PHP_EOL;
echo "PHP Version:". PHP_VERSION. PHP_EOL;
?>
Output:
__DIR__ is NOT defined
__FILE__ is NOT defined
PHP_VERSION is defined
PHP Version: 5.3.6


2022
maccase.ru - Android. Brands. Iron. news