Константы в php. Волшебные константы. Как такое имя как \my\name или \name преобразуется

(PHP 5 >= 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 = new \ stdClass ;
?>

Это функционально эквивалентно следующему:

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

$a = new stdClass ;
?>

Как мне использовать внутренние или глобальные классы в пространстве имен?

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

namespace foo ;
$a = new \ stdClass ;

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

$a = \ DirectoryIterator :: CURRENT_AS_FILEINFO ;

// расширение внутреннего или глобального класса
class MyException extends \ Exception {}
?>

Как мне использовать функции классов в пространствах имен или константы в их собственном пространстве имен?

Пример #4 Доступ ко внутренним классам, функциям или константам в пространствах имен

namespace foo ;

class MyClass {}

// использование класса из текущего пространства имен
function test (MyClass $typehintexample = null ) {}
// другой способ использовать класс из текущего пространства имен
function test (\ foo \ MyClass $typehintexample = null ) {}

// расширение класса из текущего пространства имен
class Extended extends MyClass {}

// доступ к глобальной функции
$a = \ globalfunc ();

// доступ к глобальной константе
$b = \ INI_ALL ;
?>

Как такое имя как \my\name или \name преобразуется?

Имена, которые начинаются с \ всегда преобразуются к тому как они выглядят, т.е. \my\name - это на самом деле my\name , и \Exception - это Exception .

Пример #5 Абсолютные имена

namespace foo ;
$a = new \ my \ name (); // создает экземпляр класса "my\name"
echo \ strlen ("hi" ); // вызывает функцию "strlen"
$a = \ INI_ALL ; // переменной $a присваивается значение константы "INI_ALL"
?>

Как такое имя, как my\name преобразуется?

Имена, которые содержат обратный слеш, но не начинаются с него, такие как my\name

my другого имени, то этот синоним применяется к my в my\name .

my\name .

Пример #6 Полные имена

namespace foo ;
use blah \ blah as foo ;

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

Как неполное имя класса такое как name преобразуется?

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

Если присутствует импортирующее выражение, которое создает синоним name другого имени, то применяется этот синоним.

В ином случае, текущее имя пространства имен становится префиксом к my\name .

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

namespace foo ;
use blah \ blah as foo ;

$a = new name (); // создает экземпляр класса "foo\name"
foo :: name (); // вызывает статический метод "name" в классе "blah\blah"
?>

Как неполное имя функции или неполное имя константы такое как name преобразуется?

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

Сперва, текущее имя пространства имен становится префиксом к name .

Затем, если константа или функция name не существует в текущем пространстве имен, используется глобальная константа или функция name , если она существует.

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

namespace foo ;
use blah \ blah as foo ;

const FOO = 1 ;

function my () {}
function foo () {}
function sort (& $a )
{
\ sort ($a ); // вызывает глобальную функцию "sort"
$a = array_flip ($a );
return $a ;
}

My (); // вызывает "foo\my"
$a = strlen ("hi" ); // вызывает глобальную функцию "strlen", потому что "foo\strlen" не существует
$arr = array(1 , 3 , 2 );
$b = sort ($arr ); // вызывает функцию "foo\sort"
$c = foo (); // вызывает функцию "foo\foo" - импорт не применяется

$a = FOO ; // присваивает переменной $a значение константы "foo\FOO" - импорт не применяется
$b = INI_ALL ; // присваивает переменной $b значение глобальной константы "INI_ALL"
?>

Импортируемые имена не могут конфликтовать с классами, определенными в том же файле.

Следующие комбинации скриптов допустимы:

namespace my \ stuff ;
class MyClass {}
?>

namespace another ;
class thing {}
?>

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


$a = new MyClass ; // создает экземпляр класса "thing" из пространства имен "another"
?>

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

namespace my \ stuff ;
use another \ thing as MyClass ;
class MyClass {} // фатальная ошибка: MyClass конфликтует с выражением импорта
$a = 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 = name \ CONSTANT ;
name \ func ();
?>

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

Динамические имена пространств имен (идентификаторы, взятые в кавычки) должны экранировать символ обратного слеша.

Очень важно представлять это, потому что обратный слеш используется как экранирующий символ внутри строк. Он всегда должен быть продублирован, когда используется внутри строки, иначе появляется риск возникновения неумышленных последствий:

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

$a = "dangerous\name" ; // \n - это переход на новую строку внутри строки с двойными кавычками!
$obj = new $a ;

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

Внутри строк, заключенных в одинарные кавычки, обратный слеш в качестве разделителя более безопасен, но по-прежнему рекомендуемая практика экранирования обратного слеша во всех строках является наилучшим вариантом.

Ссылаться на неопределенные константы, используя обратный слеш, нельзя. Выводится фатальная ошибка

Любая неопределенная константа, являющаяся неполным именем, как FOO , будет приводить к выводу сообщения о том, что PHP предположил, что FOO было значение константы. Любая константа, с полным или абсолютным именем, которая содержит символ обратного слеша будет приводить к фатальной ошибке, если не будет найдена.

Пример #10 Неопределенные константы

namespace bar ;
$a = FOO ; // выводит предупреждение: undefined constants "FOO" assumed "FOO";
$a = \ FOO ; // фатальная ошибка: undefined namespace constant FOO
$a = Bar \ FOO ; // фатальная ошибка: undefined namespace constant bar\Bar\FOO
$a = \ Bar \ FOO ; // фатальная ошибка: undefined namespace constant Bar\FOO
?>

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

Любая попытка определить константу пространства имен, которая совпадает с названиями специальных встроенных констант, приведет к фатальной ошибке.

Пример #11 Неопределенные константы

namespace bar ;
const NULL = 0 ; // Фатальная ошибка;
const true = "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 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

Константы - это значения, которые не изменяются со временем. Ещё из школы Вы, наверняка, знаете многие константы, например, число п , число e , ускорение свободного падения и другие. И, разумеется, при программировании тоже очень часто возникает необходимость ввода констант . И о том, как создавать и использовать константы в PHP , мы и поговорим в этой статье.

Давайте с Вами создадим константу числа п :

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

Оператор define создаёт константу PI и присваивает ей значение 3.1415926 . Дальше мы выводим эту константу через оператор echo . Всё очень просто, однако, есть одна рекомендация, которую я советую Вам всегда соблюдать. Обязательно пишите константы заглавными буквами. Не то, чтобы это было обязательно, но крайне желательно. И так принято не только в PHP , но и в других языках тоже.

Разумеется, впоследствии изменить константу PI будет нельзя (на то она и константа ).

Теперь разберём одну функцию, которая проверяет: "Определена ли заданная константа ". Давайте напишем такой скрипт:

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

Здесь проверяется существование константы PI . И если она не существует (то есть функция define() вернула false ), то тогда инициализируем эту константу. Затем просто выводим её.

Как видите, создавать и использовать свои константы в PHP - это очень просто.

И, напоследок, хочется рассказать об уже встроенных константах PHP . Давайте с Вами напишем простой скрипт:

phpinfo();
?>

Ближе к концу есть раздел "PHP Variable ". Собственно, это не совсем константы , однако, они являются константами при выполнении данного скрипта. Разумеется, при выполнении другого скрипта они уже будут иметь другие значения (не все, разумеется). Давайте с Вами выведем пару констант , чтобы Вы поняли, как с ними работать, ведь они используются безумно часто:

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

В данном скрипте мы выводим IP-адрес пользователя , запустившего скрипт, а на следующей строке выводим строку запроса (например, "index.php?id=7 "). Забегая немного вперёд, говорю, что здесь мы работаем с глобальным массивом $_SERVER . С массивами мы ещё познакомимся, но, думаю, что те, кто работал с массивами в других языках программирования, без проблем узнают синтаксис. Что же касается других констант , то с ними работа происходит аналогично.

Всем доброго времени суток. На связи Алексей Гулынин. В прошлой статье мы разобрали оператор эквивалентности в PHP . В данной статье я бы хотел рассказать о константах в PHP . В школе вы не раз встречали константы, например "число PI" или из физики универсальная газовая постоянная (R). Константы один раз определяют и они уже не меняются . Тоже самое касается констант в программировании, т.е. мы один раз определяем константу и она больше не меняется в коде программы. Константами могут быть различные математические величины, пути до файлов.

Чем константа отличается от переменной:

1) Её определяют один раз и нигде больше нельзя присвоить значение,
2) Чтобы к ней обратиться, не нужно ставить знак "$" перед ней (здесь есть минус — теперь мы не можем использовать имя константы в текстовой строке).
Давайте выведем константу "PI":

Константы бывают двух типов: определяемые интерпретатором и определяемые пользователем :

Примеры констант, определяемых интерпретатором:

1) __FILE__ — хранит имя файла, в котором находится тот код, который сейчас выполняется,
2) PHP_VERSION — версия интерпретатора PHP,
3) PHP_OS — версия операционной системы, под которой работает PHP.

Наберите следующий код и посмотрите, какие константы ещё бывают:

Можно определять свои собственные константы, делается это с помощью оператора define . Давайте определим 2 константы:

"; echo Const2; ?>

В данном случае у нас выведутся значения данных констант.

По умолчанию регистр символов в имени константы учитывается, его можно отключить с помощью необязательного третьего параметра, например так:

"; echo neW1; ?>

Вы увидите, что всё работает (в предыдущем примере работать не будет, так как там учитывается регистр букв).

Обратите внимание на кавычки, в которых пишется имя константы. Это обязательно нужно делать. Также нельзя создавать константы с одинаковыми именами.

В PHP можно проверить существует константа или нет с помощью функции defined(имя константы) . Давайте разберем на примере, чтобы стало понятно:

Наберите данный пример и посмотрите, что будет.

Встречаются случаи, когда переменные довольно неудобно использовать для постоянного хранения каких либо определенных значений, которые не меняются в течение работы программы. Такими значениями могут быть математические константы, пути к файлам, разнообразные пароли и.т.д. Как раз для этих целей в 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" )== 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.

Дополнительно

В PHP имеется набор специальных предопределенных констант и магических методов для ваших проектов. В отличие от обычных констант, которые можно устанавливать с помощью define() , значение предопределенных констант зависит от того, где они используются, и является информацией только для чтения о коде и PHP системе. Магические методы можно использовать в ваших классах для получения доступа к специальному функционалу PHP.

В данном уроке мы рассмотрим несколько полезных предопределенных констант и магических методов с примерами использования в коде.

Предопределенные константы

Предопределённые константы используются для получения информации о вашем коде. Имя такой константы пишется заглавными буквами между сдвоенными подчеркиваниями, например, __LINE__ и __FILE__ . Вот несколько полезных предопределённых констант, доступных в PHP:

  • __LINE__ возвращает номер строки в исходном файле, где используется константа:

  • __FILE__ представляет имя файла, включая полный путь:

  • __DIR__ представляет только путь к файлу:

  • __CLASS__ представляет имя текущего класса:

  • __FUNCTION__ представляет имя текущей функции:

  • __METHOD__ представляет имя текущего метода:

  • __NAMESPACE__ представляет имя текущего пространства имен:

Магические методы

Магические методы представляют крючки для специального функционала PHP. Их имена пишутся маленькими буквами с двумя предшествующими подчеркиваниями, например, __construct() и __destruct() .

Construct() - магический метод, который PHP вызывает для создания экземпляра вашего класса. Он принимает любое количество аргументов.

Destruct()- магический метод, который вызывается, когда объект уничтожается коллектором PHP. Данный метод не принимает аргументов и обычно используется для выполнения специальных операций, например, для закрытия соединения с базой данных.

Следующие несколько магических методов предназначены для манипуляций со свойствами, и представляют способ для PHP обработать обращения ко свойствам и методам, которые не были определены (или недоступны).

PHP вызывает метод __get() в получающем контексте, если свойство не определено (или недоступно). Метод принимает один аргумент - имя свойства. Он должен вернуть значение, которое будет обрабатываться как значение свойства.

Метод __set() вызывается для неопределенного свойства в задающем контексте. Данный метод принимает два аргумента, имя свойства и значение.

myAarray[$prop] = $value; } public function __get($prop) { return $this->myArray[$prop]; } public function __isset($prop) { return isset($this->myArray[$prop]); } public function __unset($prop) { unset($this->myArray[$prop]); } public function __toString() { return __CLASS__ . ":" . $this->name; } } $obj = new MySample(); if (!isset($obj->name)) { $obj->name = "Alireza"; } echo $obj->name; // Alireza echo $obj; // MySample:Alireza

В выше приведенном коде свойство name не определено в классе. В коде предпринимается попытка назначить данному свойству значение “Alireza” и PHP вызывает магический метод __set() . Он получает “name” в качестве аргумента $prop и “Alireza” как $value , и сохраняет значение в частном массиве $myArray . Метод __get() работает в схожей манере. При выводе $obj->name вызывается метод __get() и ему передается значение “name” как аргумент $prop .

Есть и другие магические методы, которые помогают манипулировать недоступными свойствами, как в приведенном примере: __isset() , __unset() и __toString() . Оба метода __isset() и __unset() запускаются функциями с такими же именами, но без подчеркиваний в PHP.

Isset() проверяет, установлено свойство или нет. Данный метод принимает один аргумент - свойство, которое надо проверить. Метод __unset() принимает один аргумент, имя свойства, которое нужно сбросить.

Во многих случаях удобно представление объекта как строки, например, для вывода пользователю или другому процессу. Обычно PHP представляет объект как идентификатор в памяти, что плохо для таких функций. Метод __toString() помогает представить объект как строку. Метод запускается во многих ситуациях, где объект используется как строка, например, echo "Hello $obj" . Также его можно вызвать непосредственно, как любой другой публичный метод.





error: Контент защищен !!