web-dev-qa-db-ja.com

PHPには構造体、typedef、および/または列挙型がありますか?そうでない場合、それらの最適な実装は何ですか?

NOTICE!: This question is not a duplicate: I have provided below an alternative and highly useful enumeration method that accomplishes the desired effect - 11/13/2013

PHPにtypedefキーワードがあるので、次のようなことができます:

typedef struct {

} aStructure;

または

typedef enum {
  aType1,
  aType2,
} aType;

[〜#〜]編集[〜#〜]

私は最終的に以下の自分の質問に答えました。型定義なしで、私が求めていたものを正確に実行するカスタムenum関数を作成しました。

25
NoodleOfDeath

私は実際にPHPのために独自の列挙型を作成しました、そしてそれは私がする必要があるためにうまく機能します。typedefはありませんが、そのニース:D

関数enum($ array、$ asBitwise = false)



    /*
     * I formed another version that includes typedefs
     * but seeing how this hacky is not viewed as compliant
     * with programming standards I won't post it unless someone
     * wishes to request. I use this a lot to save me the hassle of manually
     * defining bitwise constants, but if you feel it is too pointless
     * for you I can understand. Not trying to reinvent the wheel here
     *
     */
    function enum(array $array, bool $asBitwise = false) {

        if(!is_array($array) || count($array) < 1)  return false;    // Error incorrect type

        $n = 0; // Counter variable
        foreach($array as $i) {
            if(!define($i, $n == 0 ? 0 : ($asBitwise ? 1 << ($n - 1) : $n))) return false;
            ++$n;
        } 
        return true; // Successfully defined all variables

    }

使用法(例):



    enum([
        'BrowserTypeUnknown',       // 0
        'BrowserTypeIE',            // 1
        'BrowserTypeNetscape',      // 2
        'BrowserTypeOpera',         // 3
        'BrowserTypeSafari',        // 4
        'BrowserTypeFirefox',       // 5
        'BrowserTypeChrome',        // 6
    ]); // BrowserType as an Increment

    $browser_type = BrowserTypeChrome;

    if($browser_type == BrowserTypeOpera) {
        // Make Opera Adjustments (will not execute)
    } else
    if($browser_type == BrowserTypeChrome) {
        // Make Chrome Adjustments (will execute)
    }

    enum([
        'SearchTypeUnknown',            // 0
        'SearchTypeMostRecent',         // 1 << 0
        'SearchTypePastWeek',           // 1 << 1
        'SearchTypePastMonth',          // 1 << 2
        'SearchTypeUnanswered',         // 1 << 3
        'SearchTypeMostViews',          // 1 << 4
        'SearchTypeMostActive',         // 1 << 5
    ], true); // SearchType as BitWise

    $search_type = SearchTypeMostRecent | SearchTypeMostActive;

    if($search_type & SearchTypeMostRecent) {
        // Search most recent files (will execute)
    }
    if($search_type & SearchTypePastWeek) {
        // Search files from the past will (will not execute)
    }

    if($search_type & SearchTypeMostActive) {
        // Search most active files AS WELL (will execute as well)
    }

21
NoodleOfDeath

いいえ

配列を使用するか、カスタムタイプ、クラス、オブジェクトを必要とする場合に使用する必要があります。

17
deceze

定数でも同様のことができますが、専用の列挙型とは異なります。

1
staticsan

それらは SPL_Types と呼ばれる拡張機能ですが、この拡張機能は利用可能なWebホスティングがほとんどなく、さらに もう維持されていません です。したがって、構造体にはクラスを使用するのが最適です。列挙型の定数。多分プレーン [〜#〜] spl [〜#〜] 拡張の助けを借りて、これは利用可能なほぼすべてのphp 5.Xインストールにあり、いくつかの「邪悪な汚い列挙型ハック」を構築することができます

1

PHPでタイプセーフな列挙を処理するためのgithubライブラリを次に示します。

このライブラリは、クラス生成、クラスキャッシングを処理し、タイプセーフ列挙型デザインパターンを実装します。列挙型を処理するための序数の取得や列挙型の組み合わせのためのバイナリ値の取得など、列挙型を処理するためのいくつかのヘルパーメソッドがあります。

生成されたコードは、設定も可能なプレーンな古いphpテンプレートファイルを使用するため、独自のテンプレートを提供できます。

これはphpunitでカバーされた完全なテストです。

githubのphp-enums(お気軽にforkしてください)

使用法:(@see usage.php、または詳細については単体テスト)

<?php
//require the library
require_once __DIR__ . '/src/Enum.func.php';

//if you don't have a cache directory, create one
@mkdir(__DIR__ . '/cache');
EnumGenerator::setDefaultCachedClassesDir(__DIR__ . '/cache');

//Class definition is evaluated on the fly:
Enum('FruitsEnum', array('Apple' , 'orange' , 'rasberry' , 'bannana'));

//Class definition is cached in the cache directory for later usage:
Enum('CachedFruitsEnum', array('Apple' , 'orange' , 'rasberry' , 'bannana'), '\my\company\name\space', true);

echo 'FruitsEnum::Apple() == FruitsEnum::Apple(): ';
var_dump(FruitsEnum::Apple() == FruitsEnum::Apple()) . "\n";

echo 'FruitsEnum::Apple() == FruitsEnum::ORANGE(): ';
var_dump(FruitsEnum::Apple() == FruitsEnum::ORANGE()) . "\n";

echo 'FruitsEnum::Apple() instanceof Enum: ';
var_dump(FruitsEnum::Apple() instanceof Enum) . "\n";

echo 'FruitsEnum::Apple() instanceof FruitsEnum: ';
var_dump(FruitsEnum::Apple() instanceof FruitsEnum) . "\n";

echo "->getName()\n";
foreach (FruitsEnum::iterator() as $enum)
{
  echo "  " . $enum->getName() . "\n";
}

echo "->getValue()\n";
foreach (FruitsEnum::iterator() as $enum)
{
  echo "  " . $enum->getValue() . "\n";
}

echo "->getOrdinal()\n";
foreach (CachedFruitsEnum::iterator() as $enum)
{
  echo "  " . $enum->getOrdinal() . "\n";
}

echo "->getBinary()\n";
foreach (CachedFruitsEnum::iterator() as $enum)
{
  echo "  " . $enum->getBinary() . "\n";
}

出力:

FruitsEnum::Apple() == FruitsEnum::Apple(): bool(true)
FruitsEnum::Apple() == FruitsEnum::ORANGE(): bool(false)
FruitsEnum::Apple() instanceof Enum: bool(true)
FruitsEnum::Apple() instanceof FruitsEnum: bool(true)
->getName()
  Apple
  ORANGE
  RASBERRY
  BANNANA
->getValue()
  Apple
  orange
  rasberry
  bannana
->getValue() when values have been specified
  pig
  dog
  cat
  bird
->getOrdinal()
  1
  2
  3
  4
->getBinary()
  1
  2
  4
  8
0
zanshine