Інтернет Windows Android

Php глобальні константи. Константи в PHP

(PHP 5\u003e \u003d 5.3.0, PHP 7)

Цей список питань розділений на дві частини: загальні питання і деякі особливості реалізації, які корисні для більш повного розуміння.

Спершу, загальні питання.

  1. Якщо я не використовую простору імен, чи слід вважати що-небудь з цього важливим?
  2. Як мені використовувати внутрішні або глобальні класи в просторі імен?
  3. Як мені використовувати функції класів в просторах імен, або константи в їх власному просторі імен?
  4. Як таке ім'я як \\ My \\ name або \\ name перетвориться?
  5. Як таке ім'я, як my \\ name перетвориться?
  6. Як неповне ім'я класу таке як name перетвориться?
  7. Як неповне ім'я функції або неповне ім'я константи таке як name перетвориться?

Деякі деталі реалізації просторів імен, які корисно розуміти.

  1. Імпортовані імена не можуть конфліктувати з класами, визначеними в тому ж файлі.
  2. Ані функції, ані константи не можуть бути заімпортіровани за допомогою оператора use.
  3. Динамічні імена просторів імен (ідентифікатори, взяті в лапки) повинні екранувати символ зворотного слеша.
  4. Посилатися на невизначені константи, використовуючи зворотний слеш, не можна. Виводиться фатальна помилка
  5. Неможливо перевизначити спеціальні константи, такі як NULL, TRUE, FALSE, ZEND_THREAD_SAFE або ZEND_DEBUG_BUILD

Якщо я не використовую простору імен, чи слід вважати що-небудь з цього важливим?

Ні. Простору імен не мають жодного впливу ні на який існуючий код ні в якому вигляді або на будь-який написаний код, який не містить просторів імен. Ви можете написати такий код, якщо бажаєте:

Приклад # 1 Доступ до глобальних класів поза простором імен

$ A \u003d new \\ stdClass;
?>

Це функціонально еквівалентно наступному:

Приклад # 2 Доступ до глобальних класів поза простором імен

$ A \u003d new stdClass;
?>

Як мені використовувати внутрішні або глобальні класи в просторі імен?

Приклад # 3 Доступ до внутрішніх класів в просторах імен

namespace foo;
$ A \u003d new \\ stdClass;

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

$ A \u003d \\ DirectoryIterator :: CURRENT_AS_FILEINFO;

// розширення внутрішнього або глобального класу
class MyException extends \\ Exception ()
?>

Як мені використовувати функції класів в просторах імен або константи в їх власному просторі імен?

Приклад # 4 Доступ до внутрішніх класів, функцій або констант в просторах імен

namespace foo;

class MyClass ()

// використання класу з поточного простору імен
function test (MyClass $ typehintexample \u003d null) ()
// інший спосіб використовувати клас з поточного простору імен
function test (\\ foo \\ MyClass $ typehintexample \u003d null) ()

// розширення класу з поточного простору імен
class Extended extends MyClass ()

// доступ до глобальної функції
$ A \u003d \\ globalfunc ();

// доступ до глобальної константі
$ B \u003d \\ INI_ALL;
?>

Як таке ім'я як \\ My \\ name або \\ name перетвориться?

Імена, які починаються з \ завжди перетворюються на той як вони виглядають, тобто \\ My \\ name - це насправді my \\ name, і \\ Exception - це Exception.

Приклад № 5 Абсолютні імена

namespace foo;
$ A \u003d new \\ my \\ name (); // створює екземпляр класу "my \\ name"
echo \\ strlen ( "hi"); // викликає функцію "strlen"
$ A \u003d \\ INI_ALL; // змінної $ a присвоюється значення константи "INI_ALL"
?>

Як таке ім'я, як my \\ name перетвориться?

Імена, які містять зворотний слеш, але не починаються з нього, такі як my \\ name

my іншого імені, то цей синонім застосовується до my в my \\ name.

my \\ name.

Приклад # 6 Повні імена

namespace foo;
use blah \\ blah as foo;

$ A \u003d new my \\ name (); // створює екземпляр класу "foo \\ my \\ name"
foo \\ bar :: name (); // викликає статичний метод "name" в класі "blah \\ blah \\ bar"
my \\ bar (); // викликає функцію "foo \\ my \\ bar"
$ A \u003d my \\ BAR; // привласнює змінної $ a значення константи "foo \\ my \\ BAR"
?>

Як неповне ім'я класу таке як name перетвориться?

Імена класів, які не містять зворотний слеш, такі як name можуть бути перетворені двома різними способами.

Якщо присутній імпортує вираз, яке створює синонім name іншого імені, то застосовується цей синонім.

В іншому випадку, поточне ім'я простору імен стає префіксом до my \\ name.

Приклад # 7 Неповні імена класів

namespace foo;
use blah \\ blah as foo;

$ A \u003d new name (); // створює екземпляр класу "foo \\ name"
foo :: name (); // викликає статичний метод "name" в класі "blah \\ blah"
?>

Як неповне ім'я функції або неповне ім'я константи таке як name перетвориться?

Імена функцій або констант, які не містять зворотного слеша, такі як name можуть бути перетворені двома різними способами.

Спершу, поточне ім'я простору імен стає префіксом до name.

Потім, якщо константа або функція name не існує в поточному просторі імен, використовується глобальна константа або функція name, Якщо вона існує.

Приклад # 8 Неповні імена функцій або констант

namespace foo;
use blah \\ blah as foo;

const FOO \u003d 1;

function my () ()
function foo () ()
function sort (& $ a)
{
\\ Sort ($ a); // викликає глобальну функцію "sort"
$ A \u003d array_flip ($ a);
return $ a;
}

My (); // викликає "foo \\ my"
$ A \u003d strlen ( "hi"); // викликає глобальну функцію "strlen", тому що "foo \\ strlen" не існує
$ Arr \u003d array (1, 3, 2);
$ B \u003d sort ($ arr); // викликає функцію "foo \\ sort"
$ C \u003d foo (); // викликає функцію "foo \\ foo" - імпорт не застосовується

$ A \u003d FOO; // привласнює змінної $ a значення константи "foo \\ FOO" - імпорт не застосовується
$ B \u003d INI_ALL; // привласнює змінної $ b значення глобальної константи "INI_ALL"
?>

Імпортовані імена не можуть конфліктувати з класами, визначеними в тому ж файлі.

Наступні комбінації скриптів допустимі:

namespace my \\ stuff;
class MyClass ()
?>

namespace another;
class thing ()
?>

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


$ A \u003d new MyClass; // створює екземпляр класу "thing" з простору імен "another"
?>

Конфлікт імен відсутня навіть незважаючи на те, що клас MyClass існує всередині простору імен my \\ stuff, Тому що визначення MyClass знаходиться в окремому файлі. Однак такий приклад призводить до фатальної помилки з конфліктом імен, тому що клас MyClass визначено в тому ж файлі, де знаходиться оператор use.

namespace my \\ stuff;
use another \\ thing as MyClass;
class MyClass () // фатальна помилка: MyClass конфліктує з виразом імпорту
$ A \u003d new MyClass;
?>

Вкладені простору імен неприпустимі.

PHP не дозволяє вкладення просторів імен одне в інше

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

Однак, зімітувати вкладені простору імен так:

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

До PHP 5.6 ні функції, ні константи не могли бути імпортовані за допомогою оператора use.

До PHP 5.6 єдині елементи, які схильні до дії оператора use - це простору імен і імена класів. Для скорочення довгих імен констант або функцій, заімпортіруйте їх вміст в простір імен.

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

$ A \u003d name \\ CONSTANT;
name \\ func ();
?>

Починаючи з PHP 5.6 стало можливим імпортування та створення пседонімов для функцій та імен констант.

Динамічні імена просторів імен (ідентифікатори, взяті в лапки) повинні екранувати символ зворотного слеша.

Дуже важливо представляти це, тому що зворотний слеш використовується як екранує символ всередині рядків. Він завжди повинен бути продубльований, коли використовується всередині рядка, інакше з'являється ризик виникнення ненавмисних наслідків:

Приклад # 9 Підводні камені при використанні імені простору імен всередині рядка з подвійними лапками

$ A \u003d "dangerous \\ name"; // \\ n - це перехід на новий рядок всередині рядка з подвійними лапками!
$ Obj \u003d new $ a;

$ A \u003d "not \\ at \\ all \\ dangerous"; // а тут немає проблем.
$ Obj \u003d new $ a;
?>

Усередині рядків, укладених в одинарні лапки, зворотний слеш як роздільник більш безпечний, але як і раніше рекомендована практика екранування зворотного слеша у всіх рядках є найкращим варіантом.

Посилатися на невизначені константи, використовуючи зворотний слеш, не можна. Виводиться фатальна помилка

Будь-яка невизначена константа, що є неповним ім'ям, як FOO, Буде приводити до висновку повідомлення про те, що PHP припустив, що FOO було значення константи. Будь-яка константа, з повним або абсолютним ім'ям, яка містить символ зворотного слеша буде приводити до фатальної помилки, якщо не буде знайдена.

Приклад # 10 Невизначені константи

namespace bar;
$ A \u003d FOO; // виводить попередження: undefined constants "FOO" assumed "FOO";
$ A \u003d \\ FOO; // фатальна помилка: undefined namespace constant FOO
$ A \u003d Bar \\ FOO; // фатальна помилка: undefined namespace constant bar \\ Bar \\ FOO
$ A \u003d \\ Bar \\ FOO; // фатальна помилка: undefined namespace constant Bar \\ FOO
?>

Неможливо перевизначити спеціальні константи, такі як NULL, TRUE, FALSE, ZEND_THREAD_SAFE або ZEND_DEBUG_BUILD

Будь-яка спроба визначити константу простору імен, яка збігається з назвами спеціальних вбудованих констант, призведе до фатальної помилки.

Приклад # 11 Невизначені константи

namespace bar;
const NULL \u003d 0; // Фатальна помилка;
const true \u003d "stupid"; // також фатальна помилка;
// і т.д.
?>

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 CAN NOT 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 \u003d "Foo \\ Bar";
var_dump ($ bar :: test ()); // string (7) "Foo \\ Bar"

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

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

Для кожного виконуваного скрипта. Багато з цих констант визначаються різними модулями і будуть присутні тільки в тому випадку, якщо ці модулі доступні в результаті динамічного завантаження або в результаті статичної збірки.

Є дев'ять магічних констант, які змінюють своє значення в залежності від контексту, в якому вони використовуються. Наприклад, значення __LINE__ залежить від рядка в скрипті, на якій ця константа вказана. Всі магічні константи вирішуються під час компіляції, на відміну від звичайних констант, які вирішуються під час виконання. Спеціальні константи нечутливі до регістру і їх список наведено нижче:

Деякі магічні константи PHP
ім'я опис
__LINE__ Поточний номер рядка у файлі.
__FILE__ Повний шлях і ім'я поточного файлу з розгорнутими симлінк. Якщо використовується всередині підключається файлу, то повертається ім'я даного файлу.
__DIR__ Директорія файлу. Якщо використовується всередині підключається файлу, то повертається директорія цього файлу. Це еквівалентно виклику dirname (__ FILE__). Що повертається ім'я директор не закінчується на слеш, за винятком кореневої директорії.
__FUNCTION__ Ім'я функції або (Closure) в разі анонімної функції.
__CLASS__ Ім'я класу. Це ім'я містить назву простору імен, в якому клас був оголошений (наприклад, Foo \\ Bar). Зверніть увагу, що починаючи з PHP 5.4 __CLASS__ також працює в трейтах. При використанні в методах трейтов __CLASS__ є ім'ям класу, в якому ці методи використовується.
__TRAIT__ Ім'я трейта. Це ім'я містить назву простору імен, в якому трейт був оголошений (наприклад, Foo \\ Bar).
__METHOD__ Ім'я методу класу.
__NAMESPACE__ Ім'я поточного простору імен.
ClassName :: class Повне ім'я класу (із зазначенням простору імен). Див. також :: class.

Дивіться також get_class () , get_object_vars () , file_exists () і function_exists () .

список змін

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 \u003d new trick ();
$ Obj-\u003e doit ();
output will be ---- doit
$ Obj-\u003e 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 \u003d new derived_class ();

$ Obj_b -\u003e say_a ();
echo "
" ;
$ Obj_b -\u003e 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 can not define magic constants is valid, but stating that defining __DIR__ is not useless, is not!

7 years ago

You can not 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

Зустрічаються випадки, коли змінні досить незручно використовувати для постійного зберігання будь-яких певних значень, які не змінюються протягом роботи програми. Такими значеннями можуть бути математичні константи, шляхи до файлів, різноманітні паролі і.т.д. Якраз для цих цілей в PHP передбачена така конструкція, як.

називається іменована величина, яка не змінюється в процесі виконання програми (скрипта).

У РНР константи визначаються функцією define () . Ця функція має такий вигляд:

define ($ name, $ value, $ case_sen), Де:

$ name - ім'я константи;
$ value - значення константи;
$ case_sen - необов'язковий параметр логічного типу,
вказує, чи слід враховувати регістр букв (true) чи ні (false).

Приклад визначення і використання констант в PHP:


echo pi;
// Виводить 3.14
?>

якщо параметр $ case_sen дорівнює true, То інтерпретатор буде враховувати регістр символів при роботі з константою. Зверніть увагу, що константи використовуються без передує знаку $ .

Відмінності між константами і змінними:

    У констант немає приставки у вигляді знака долара ( $ );

    Константи можна визначити тільки за допомогою функції define () , А не привласненням значення;

    Константи можуть бути визначені і доступні в будь-якому місці без урахування області видимості;

    Константи не можуть бути визначені або анульовані після первинного оголошення;

    Константи можуть мати лише скалярні значення.

Перевірка існування констант

Для перевірки існування константи можна використовувати функцію defined () . Ця функція повертає true, Якщо константа оголошена. Наведемо приклад:

// Оголошуємо константу pi
define ( "pi", 3.14, true);
if (defined ( "pi") \u003d\u003d true) echo "Константа pi оголошена!";
// Скрипт виведе "Константа pi оголошена!"
?>

Зумовлені константи PHP

У PHP існують наступні зумовлені константи:

PHP надає великий список зумовлених констант для кожного виконуваного скрипта. Багато з цих констант визначаються різними модулями і будуть присутні тільки в тому випадку, якщо ці модулі доступні в результаті динамічного завантаження або в результаті статичної збірки.

Є п'ять зумовлених констант, які змінюють своє значення в залежності від контексту, в якому вони використовуються. Наприклад, константа __LINE__ залежить від рядка в скрипті, на якій ця константа вказана. Спеціальні константи нечутливі до регістру і їх список наведено нижче:

ім'я опис
__LINE__ Поточний рядок в файлі.
__FILE__ Повний шлях і ім'я поточного файлу.
__DIR__ The directory of the file. If used inside an include, the directory of the included file is returned. This is equivalent to dirname (__ FILE__). This directory name does not have a trailing slash unless it is the root directory.
__FUNCTION__ Ім'я функції. (Додано в PHP 4.3.0.)
__CLASS__ Ім'я класу. (Додано в PHP 4.3.0.)
__TRAIT__ The trait name. The trait name includes the namespace it was declared in (e.g. Foo \\ Bar).
__METHOD__ Ім'я методу класу. (Додано в PHP 5.0.0)
__NAMESPACE__ The name of the current namespace.

додатково

Останнє оновлення: 1.11.2015

Константи, як і змінні зберігають певне значення, тільки на відміну від змінних значення констант може бути встановлено тільки один раз, і далі ми вже не можемо його змінити. Наприклад, визначимо числову константу:

Для визначення константи використовується оператор define, який має наступну форму: define (string $ name, string $ value, bool $ case_sen \u003d false). Параметр $ name передає назва константи, а параметр $ value - її значення. Третій необов'язковий параметр приймає логічне значення true або false. Якщо значення дорівнює false, то при використанні константи буде враховуватися її регістр, якщо true - регістр не враховується. У нашому випадку третій параметр не використаний, тому він за замовчуванням дорівнює false.

Після визначення константи ми можемо її використовувати також, як і звичайну змінну. Єдиний виняток - ми не зможемо змінити її значення. Інша відмінність від змінної - не треба використовувати знак $. Тобто вираз NUMBER \u003d 33; працювати не буде.

зумовлені константи

Крім створюваних програмістом констант в PHP є ще кілька вбудованих констант:

    FILE__: зберігає повний шлях і ім'я поточного файлу

    LINE__: зберігає поточний номер рядка, яку обробляє інтерпретатор

    DIR__: зберігає каталог поточного файлу

    FUNCTION__: назва оброблюваної функції

    CLASS__: назва поточного класу

    METHOD__: назва оброблюваного методу

    NAMESPACE__: назва поточного простору імен

Наприклад, виведемо поточну виконувану рядок і назва файлу:

Перевірка існування константи

Щоб перевірити, чи визначена константи, ми можемо використовувати функцію bool defined (string $ name). Якщо константа $ name визначена, то функція буде повертати значення true