Часто задаваемые вопросы (FAQ): вещи, которые вам необходимо знать о пространствах имен. Волшебные константы Php константы file

(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

Последнее обновление: 1.11.2015

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

Для определения константы используется оператор define , который имеет следующую форму: define(string $name, string $value, bool $case_sen=false) . Параметр $name передает название константы, а параметр $value - ее значение. Третий необязательный параметр принимает логическое значение true или false . Если значение равно false, то при использовании константы будет учитываться ее регистр, если true - регистр не учитывается. В нашем случае третий параметр не использован, поэтому он по умолчанию равен false.

После определения константы мы можем ее использовать также, как и обычную переменную. Единственное исключение - мы не сможем изменить ее значение. Другое отличие от переменной - не надо использовать знак $ . То есть выражение NUMBER=33; работать не будет.

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

Кроме создаваемых программистом констант в PHP имеется еще несколько встроенных констант:

    FILE__ : хранит полный путь и имя текущего файла

    LINE__ : хранит текущий номер строки, которую обрабатывает интерпретатор

    DIR__ : хранит каталог текущего файла

    FUNCTION__ : название обрабатываемой функции

    CLASS__ : название текущего класса

    METHOD__ : название обрабатываемого метода

    NAMESPACE__ : название текущего пространства имен

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

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

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

Константа - это идентификатор (имя) для простого значения. Как следует из названия, их значение не может изменится в ходе выполнения скрипта (кроме магических констант , которые на самом деле не являются константами). Имена констант по умолчанию чувствительны к регистру. По принятому соглашению, имена констант всегда пишутся в верхнем регистре.

Имя константы должно соответствовать тем же правилам именования, что и другие имена в PHP. Правильное имя начинается с буквы или символа подчеркивания, за которым следует любое количество букв, цифр и символов подчеркивания. Регулярное выражение для проверки правильности имени константы выглядит так: ^*$

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

Пример #1 Правильные и неправильные имена констант

// Правильные имена констант
define ("FOO" , "что-то" );
define ("FOO2" , "что-то ещё" );
define ("FOO_BAR" , "что-то большее" );

// Неправильные имена констант
define ("2FOO" , "что-то" );

// Это верное объявление, но лучше его не использовать:
// PHP однажды может зарегистрировать волшебную константу,
// которая нарушит работу скрипта
define ("__FOO__" , "что-то" );

?>

Замечание : Понятие "буквы" здесь - это символы a-z, A-Z, и другие символы с ASCII-кодами от 128 до 255 (0x80-0xff).

2 years ago

Performance of constants. PHP 7.1.10 32 bits (Opcache active, windows 10 i7-64bits) but apparently the trends is the same with the 5.x

using a constant declared by DEFINE("CNS",value) : 0.63575601577759s
using a constant declared by const CNS=value: 0.61372208595276s
using a variable declared by $v=value: 0.51184010505676s

In average, the use of DEFINE and CONST is around the same with some sightly better performance of CONST instead of DEFINE. However, using a variable is around 10-50% better than to use a constant. So, for a performance intensive task, constant is not the best option.

$p1=microtime(true);
$x=0;
for($i=0;$i<50000000;$i++) {
$x+=CNS;
}
$p2=microtime(true);

14 years ago

An undefined constant evaluates as true when not used correctly. Say for example you had something like this:

settings.php
// Debug mode
define ("DEBUG" , false );
?>

test.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
// Debug mode
define ("DEBUG" , 0 );
?>

test.php
include("settings.php" );

if (DEBUG == 1 ) {
// echo some sensitive data.
}
?>

Now it works correctly.

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

Привет. Сегодня решил написать о константах в PHP. Расскажу как константы работают, какие чаще всего применяются и бывают.

Что такое константы в контексте PHP?

Константы — это по сути переменные у которых нельзя переопределить значение. Т.е после указания их значения вы больше не сможете его менять по ходу выполнения скрипта. Они как правило пишутся в верхнем регистре и в названии конкретно отражают хранимую в них информацию.

В PHP существует 2 разновидности констант:

  1. Обычные (задаются программистом)
  2. Предопределенные (задаются интерпретатором)

Обычные константы

Такой тип констант обычно используются как правило для служебных целей и создаются программистом в процессе написание кода.
Синтаксис создания обычной константы:

Define("PI",3.1415);

Создание константы происходит с помощью встроенной конструкции define ("Имя константы","Значение константы").

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

Для того чтобы проверить существование константы в языке предусмотрена функция defined («CONST_NAME»).

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

Предопределенные константы отличаются от обычных способом создания. Они устанавливаются самим интерпретатором и меняют свое значение в контексте выполнения программы. Так же они не чувствительны к регистру, __CLASS__ или __class__ будут прекрасно выполнены интерпретатором.

Вот самые часто используемые предопределенные константы:

  • __FILE__ — хранит имя выполняемого на данный момент скрипта.
  • __FUNCTUIN__ — имя текущей функции.
  • __CLASS__ — имя текущего класса.
  • PHP_VERSION — содержит версию интерпретатора PHP.
  • TRUE , FALSE , NULL — содержат в себе значения соответствующие своему названию.

Для примера работы таких констант посмотрим на использование одной из них — __FUNCTION__ :

Как можно видеть из примера константа __function__ вернула имя функции в которой она была первоначально вызвана — abc () .

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

На этом все, желаю успешной практики и хорошего настроения. До скорого.

сайт Права на контент защищены.

Последние материалы раздела:

Установка кастомного рекавери и получение рут-прав С помощью Kingroot на ПК
Установка кастомного рекавери и получение рут-прав С помощью Kingroot на ПК

Инструкция по установке кастомного рекавери и получении прав суперпользователя на Samsung Galaxy J7 (SM-J700F, SM-J700H, SM-J700M) под управлением...

Какой поиск лучше — Яндекс или Гугл
Какой поиск лучше — Яндекс или Гугл

https://www.google.com/drive/ популярное облачное хранилище с возможностью загружать данные и, при необходимости, делиться ими с другими. Важная...

Группа или ресурс не находятся в нужном состоянии для выполнения требуемой операции
Группа или ресурс не находятся в нужном состоянии для выполнения требуемой операции

Пользователи, желающие создать раздачу беспроводной сети c помощью Wi-Fi модуля своего ноутбука или компьютера, могут столкнуться с довольно...