PHP: Can an array have an array as a key in a key-value pair?

I'm getting an "Illegal offset type" for this array:

public static $CATS_AND_TYPES = array(

        // Statement Administration
        array( self::CAT_STATEMENT_ADMIN => "Document Administration" ) => array(
            self::TYPE_STATEMENTS_LOADED => "Documents Loaded",
            self::TYPE_STATEMENTS_REMOVED => "Documents Removed"
        ),

        // Cron Jobs
        array( self::CAT_CRON_JOBS => "Cron Jobs" ) => array(
            self::TYPE_CRON_BULLETIN_RUN => "Bulletin Cron Job Ran",
            self::TYPE_CRON_EMAILER_RUN => "Emailer Cron Job Ran",
            self::TYPE_CRON_SURVEY_RUN => "Survey Cron Job Ran",
            self::TYPE_CRON_JOURNEY_RUN => "Journey Cron Job Ran",
            self::TYPE_CRON_DOCUMENT_RUN => "Document Cron Job Ran"
        ),

        // Global Administration
        array( self::CAT_GLOBAL_ADMIN => "Global Administration" ) => array(
            self::TYPE_GLOBAL_MAINTENANCE => "Global Maintenance",
            self::TYPE_GLOBAL_EMAIL_SENDING => "Email Sending"
        ),

        // Email Administration
        array( self::CAT_EMAIL_ADMIN => "Email Administration" ) => array(
            self::TYPE_EMAIL_SENT => "Email Sent",
            self::TYPE_EMAIL_RESENT => "Email Resent",
            self::TYPE_EMAIL_REMOVED => "Email Removed"
        ),

        // DCVs Administration
        array( self::CAT_DCVS_ADMIN => "DCVs Administration" ) => array(
            self::TYPE_DCVS_FLEX_UPDATED => "Flexible Variables Updated",
            self::TYPE_DCVS_GLOBAL_UPDATED => "Global Variables Updated"
        ),

        // Video Administration
        array( self::CAT_VIDEO_ADMIN => "Video Administration" ) => array(
            self::TYPE_VIDEO_ADDED => "Video Added",
            self::TYPE_VIDEO_EDITED => "Video Edited",
            self::TYPE_VIDEO_REMOVED => "Video Removed"
        ),

        // Bulletin Board Administration
        array( self::CAT_BULLETIN_BOARD => "Bulletin Board Administration" ) => array(
            self::TYPE_BULLETIN_DELETED => "Message Deleted",
            self::TYPE_BULLETIN_EDITED => "Message Edited",
            self::TYPE_BULLETIN_ADDED => "Message Added"
        ),

        // User Administration
        array( self::CAT_USER_ADMIN => "User Administration" ) => array(
            self::TYPE_USER_ADDED => "User Added",
            self::TYPE_USER_ADDED_MULTI => "Multiple Users Added",
            self::TYPE_USER_REMOVED => "User Removed",
            self::TYPE_USER_REMOVED_MULTI => "Multiple Users Removed",
            self::TYPE_USER_UPDATED => "User Updated"
        ),

        // Survey Administration
        array( self::CAT_SURVEY_ADMIN => "Survey Administration" ) => array(
            self::TYPE_SURVEY_ADDED => "Survey Added",
            self::TYPE_SURVEY_UPDATED => "Survey Updated",
            self::TYPE_SURVEY_REMOVED => "Survey Removed",
            self::TYPE_SURVEY_REMOVED_MULTI => "Multiple Surveys Removed"
        )
    );

it's kind of annoying to make another array just to define what is being defined in the keys here, so i was wondering if that was my problem. if it is, i guess i'll have to make a key-value array for the categories ids and string values.

thanks!

9
задан Garrett 17 August 2010 в 05:30
поделиться

3 ответа

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

Ключ может быть целым или строковым. Если ключ является стандартным представлением целого числа, он будет интерпретироваться как таковой (т.е. «8» будет интерпретироваться как 8, а «08» будет интерпретироваться как «08»). Плавающие в ключе усекаются до целого числа.

Поскольку self :: CAT_CRON_JOBS et al. кажется, что они в любом случае должны быть константами, почему бы просто не определить их так, чтобы их значение было текстом описания, а затем вы могли бы просто указать свой массив, например

const CAT_STATEMENT_ADMIN = "Document Administration";

public static $CATS_AND_TYPES = array(

  // Statement Administration
  self::CAT_STATEMENT_ADMIN => array(
    self::TYPE_STATEMENTS_LOADED => "Documents Loaded",
    self::TYPE_STATEMENTS_REMOVED => "Documents Removed"
  ),

  // etc.
)

А затем вы могли бы использовать либо $ CATS_AND_TYPES [self :: CAT_STATEMENT_ADMIN ] (внутри класса, конечно) или $ CATS_AND_TYPES ['Document Administration'] , чтобы получить тот же элемент массива.

8
ответ дан 3 November 2019 в 00:57
поделиться

В качестве ключей массивы могут иметь только целые числа и строки.

Вы можете моделировать массивы и использовать объекты в качестве ключей с помощью SplObjectStorage . Но никаких массивов.

2
ответ дан 3 November 2019 в 00:57
поделиться

Я думаю, это ваша проблема: P

Я бы подошел к проблеме следующим образом

public static $CATS_AND_TYPES = array(

    self::CAT_STATEMENT_ADMIN => array(
        self::TYPE_STATEMENTS_LOADED,
        self::TYPE_STATEMENTS_REMOVED
    ),

    // ...
);

public static $TRANSLATIONS = array(
    self::CAT_STATEMENT_ADMIN => 'Email Administration',
    self::TYPE_STATEMENTS_LOADED = "Documents Loaded",
// ...

Я полагаю, что в основном это то, что вы имели в виду под «создать другой массив». Это правильный подход к проблеме, потому что он разделяет перевод и иерархическую информацию.

Представьте, что вы хотите перевести свой проект на другой язык. Если вы наняли переводчика, ему не нужно знать иерархическую структуру вашего проекта, потому что он должен только переводить. Вы также можете извлечь $ TRANSLATIONS в другой файл, чтобы вы могли распространить этот файл среди 99 переводчиков, и ваш проект стал многоязычным за один день!

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

// Untested
public static $CATS_AND_TYPES = array(
    serialize(array(self::CAT_STATEMENT_ADMIN=>"Documents and Administration")) => array(
        self::TYPE_STATEMENTS_LOADED => "Documents Loaded"
        // ...
    )
);

// You can later get back the values
foreach(self::CATS_AND_TYPES as $k=>$v)
{
    $title = unserialize($k);
    displayTitle($title[0]);

    foreacH($v as $bar) displaySubtitle($bar);
}
1
ответ дан 3 November 2019 в 00:57
поделиться
Другие вопросы по тегам:

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