PHP эквивалент enum в пространстве имен [C / C ++]

0

Я бы хотел аккуратно организовать мои константы.

В C++ я бы поместил перечисления или переменные в пространство имен (или больше):

namespace foo
{
    namespace bar
    {
        enum herp { derp, sherp, sheep };
    }

    namespace Family
    {
        const string mom  = "Anita";
        const string son  = "Bob";
        const string daughter = "Alice";
    }
}

Это даст мне возможность получить к ним доступ, как

int x = foo::bar::derp;
string nameOfMom = foo::Family::mom;
string nameOfSon = foo::Family::son;

Как я могу реализовать это в PHP?

  • 0
    возможный дубликат PHP и перечислений
  • 0
    Не думай, что это ...
Теги:
namespaces
enums
constants

1 ответ

2
Лучший ответ

Что касается перечисления: в PHP нет перечисления. Вы можете написать массив (на самом деле это HashTable внизу), или вам придется использовать (отдельное) пространство имен и/или определять класс для этого, учитывая, что перечисление ближе к классу, я бы, вероятно, выбрал для последнего и идти вперед и писать:

class FakeEnum
{
    const DERP = 0;
    const SHERP = 1;
    const SHEEP = 2;
}

jycr753 уже связал этот вопрос, и он показывает, как вы можете эмулировать перечисления в PHP, но если вы спросите меня, это просто слишком мало. Использование ReflectionClass просто для эмуляции отсутствующей конструкции подобно изменению вашего автомобиля, чтобы он мог удвоиться как мотоцикл.

В именах:
Пространства имен в PHP относительно "новые", и они не на 100% эквивалентны пространствам имен C++. Во-первых, они не могут быть вложены так, как вы пытаетесь. Для этого вам придётся прибегать к объявлению классов внутри определенного пространства имен и принимать это только для 1 дополнительного уровня.
Все понимают, я так понимаю, вы ищете что-то вроде этого:

namespace Foo
{
    const FOOBAR = 123;
}
namespace Bar
{
    const FOOBAR = 456;
}
namespace Work
{
    const FOOBAR = __NAMESPACE__;
    include 'global_const.php';
    echo 'Global FOOBAR const is: ', \FOOBAR, PHP_EOL,
        'Foo::FOOBAR is: ', \Foo\FOOBAR, PHP_EOL,
        'Bar::FOOBAR is: ', \Bar\FOOBAR, PHP_EOL,
        'Work::FOOBAR is: ', FOOBAR, PHP_EOL;
}

Если файл global_const.php определяет глобальную константу:

define('FOOBAR', 'global');//just to be consistent ;-P

Результат:

Global FOOBAR const is: global
Foo::FOOBAR is: 123
Bar::FOOBAR is: 456
Work::FOOBAR is: Work

Конечно, на самом деле ваш код будет распределен по нескольким файлам, и чаще всего вы будете использовать только одно пространство имен для этого файла и use другие пространства имен (≃ using в C++):

namespace My\Core\Components\Output;
use Foo,
    Bar,
    My\Core\Components\Input as CoreInput;
use External\Component\Input as HelperInput;

Несоответствия в системе имен имен PHP хорошо документированы (google search them). Но чтобы привести вам пример, если я запустил свой файл с приведенными выше инструкциями, следующий оператор:

$myVar = Foo\SOME_CONSTANT;

решает

global namespace (\ for short)
    ->Foo namespace
        -> SOME_CONSTANT

Но если бы я удалил use Foo, то такое же утверждение разрешит:

\
  -> My
     -> Core
         -> Components
             -> Output
                -> Foo
                   -> SOME_CONSTANT

Теперь это может показаться совершенно разумным, но одно и то же правило не относится к основным функциям: \str_replace или str_replace разрешены правильно, единственное отличие состоит в том, что последний сначала выполнит поиск функции str_replace в текущем пространстве имен, затем вернуться к глобальному пространству имен.
Хорошо, с некоторой "доброй волей" вы можете утверждать, что это тоже довольно предсказуемое поведение. К сожалению, странно или злонамеренно PHP не ведет себя так же, когда использует свои основные объекты (например, DateTime, stdClass, Exception или PDO...).
Возьмите расширение mysqli_*, например: вы можете использовать его процедурный API на всех ваших пространствах имен и быть счастливым кемпером, но если вы предпочитаете API OO, вам придется use операторы use или добавлять обратную косую черту всякий раз, когда вы написать new \mysqli().

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

  • 0
    Спасибо, я думаю, мне придется иметь дело с тем фактом, что я не могу заставить его выглядеть так же, как в C ++, и вынужден прибегать к чему-то другому. Но большое спасибо за этот пост, это все равно очень помогло (:

Ещё вопросы

Сообщество Overcoder
Наверх
Меню