определить () против const

Вот как я использую Apache BOMInputStream, он использует блок try-with-resources. Аргумент «false» указывает объекту игнорировать следующие спецификации (мы используем текстовые файлы «Без спецификации» по соображениям безопасности, ха-ха):

try( BufferedReader br = new BufferedReader( 
    new InputStreamReader( new BOMInputStream( new FileInputStream(
       file), false, ByteOrderMark.UTF_8,
        ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE,
        ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE ) ) ) )
{
    // use br here

} catch( Exception e)

}
630
задан Peter Mortensen 14 July 2019 в 10:48
поделиться

5 ответов

Начиная с PHP 5.3 существует два способа определения констант : либо с помощью ключевого слова const , либо с помощью define () function:

const FOO = 'BAR';
define('FOO', 'BAR');

Фундаментальное различие между этими двумя способами состоит в том, что const определяет константы во время компиляции, тогда как define определяет их во время выполнения. Это вызывает большинство недостатков const . Некоторые недостатки const :

  • const не может использоваться для условного определения констант. Чтобы определить глобальную константу, ее нужно использовать во внешней области видимости:

     if (...) {
    const FOO = 'БАР'; // Неверный
    }
    // но
    если (...) {
    определить ('FOO', 'BAR'); // Действительный
    }
    

    Зачем вам вообще это нужно? Одно из распространенных приложений - проверить, определена ли уже константа:

     if (! Defined ('FOO')) {
    определить ('FOO', 'BAR');
    }
    
  • const принимает статический скаляр (число, строка или другая константа, например true , false , null , __ FILE __ ), тогда как define () принимает любое выражение. Поскольку в PHP 5.6 разрешены постоянные выражения и в const :

     const BIT_5 = 1 << 5; // Действителен с PHP 5.6 и недействителен ранее
    определить ('BIT_5', 1 << 5); // Всегда действителен
    
  • const принимает простое имя константы, тогда как define () принимает любое выражение в качестве имени. Это позволяет делать такие вещи:

     for ($ i = 0; $ i <32; ++ $ i) {
    define ('BIT_'. $ i, 1 << $ i);
    }
    
  • const всегда чувствительны к регистру, тогда как define () позволяет вам определять нечувствительные к регистру константы, передавая true в качестве третьего аргумента:

     define (' FOO ',' BAR ', правда);
    эхо FOO; // БАР
    эхо фу; // БАР
    

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

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

     пространство имен A \ B \ C;
    // Чтобы определить константу A \ B \ C \ FOO:
    const FOO = 'БАР';
    определить ('A \ B \ C \ FOO', 'BAR');
    
  • Начиная с PHP 5.6, константы const также могут быть массивами, а define () еще не поддерживает массивы. Однако массивы будут поддерживаться в обоих случаях в PHP 7.

     const FOO = [1, 2, 3]; // Действителен в PHP 5.6
    определить ('FOO', [1, 2, 3]); // Недействительно в PHP 5.6 и допустимо в PHP 7.0
    

Наконец, обратите внимание, что const также может использоваться в классе или интерфейсе для определения константы класса или константы интерфейса. define не может использоваться для этой цели:

class Foo {
    const BAR = 2; // Valid
}
// But
class Baz {
    define('QUX', 2); // Invalid
}

Summary

Если вам не нужен какой-либо тип условного или экспрессионного определения, используйте const s вместо define () s - просто для читабельности!

1016
ответ дан 22 November 2019 в 21:49
поделиться

До PHP 5.3 const нельзя было использовать в глобальной области видимости. Вы можете использовать это только внутри класса. Это следует использовать, если вы хотите установить какую-либо постоянную опцию или настройку, относящуюся к этому классу. Или, может быть, вы хотите создать какое-то перечисление.

define может использоваться для той же цели, но может использоваться только в глобальной области. Его следует использовать только для глобальных настроек, которые влияют на все приложение.

Пример правильного использования const - избавиться от магических чисел. Взгляните на константы PDO . Когда вам нужно указать тип выборки, вы должны ввести, например, PDO :: FETCH_ASSOC . Если бы константы не использовались, вы бы набрали что-то вроде 35 (или как там FETCH_ASSOC определяется как). Для читателя это не имеет смысла.

Примером правильного использования define может быть указание корневого пути вашего приложения или номера версии библиотеки.

196
ответ дан 22 November 2019 в 21:49
поделиться

define Я использую для глобальных констант.

const Я использую для констант класса.

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

Кроме того, с const он фактически становится членом класса, а с define он будет перемещен в глобальную область видимости.

20
ответ дан 22 November 2019 в 21:49
поделиться

Я считаю, что начиная с PHP 5.3, вы можете использовать const вне классов, как показано во втором примере:

http://www.php.net/manual/en/language.constants.syntax.php

<?php
// Works as of PHP 5.3.0
const CONSTANT = 'Hello World';

echo CONSTANT;
?>
22
ответ дан 22 November 2019 в 21:49
поделиться

Да, const определяются во время компиляции и, как утверждает nikic, не могут быть присвоены выражению, как могут define(). Но также const не могут быть условно объявлены (по той же причине). т.е. вы не можете сделать это:

if (/* some condition */) {
  const WHIZZ = true;  // CANNOT DO THIS!
}

В то время как вы можете сделать это с define(). Таким образом, это не сводится к личным предпочтениям, есть правильный и неправильный способ использования обоих.

В качестве отступления... Я бы хотел увидеть что-то вроде class const, которому можно присвоить выражение, своего рода define(), который можно изолировать от классов?

.
6
ответ дан 22 November 2019 в 21:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: