PHP-Konstanten mit Arrays?

407

Dies schlug fehl:

 define('DEFAULT_ROLES', array('guy', 'development team'));

Anscheinend können Konstanten keine Arrays enthalten. Was ist der beste Weg, um dies zu umgehen?

define('DEFAULT_ROLES', 'guy|development team');

//...

$default = explode('|', DEFAULT_ROLES);

Dies scheint unnötiger Aufwand zu sein.

Nick Heiner
quelle
17
PHP 5.6 unterstützt konstante Arrays, siehe meine Antwort unten.
Andrea
1
Wann müssten Sie ein Array als Konstante verwenden, versuchen Sie eine Aufzählung durchzuführen? Wenn ja, dann verwenden Sie SplEnum: php.net/manual/en/class.splenum.php
ziGi
2
@ziGi Kam heute auf dieses Problem, haben verschiedene Arten von Bildern zu speichern, die bestimmte Dimensionen erfordern, es wurde nützlich, diese Dimensionen als konstante Arrays anstelle von einem für die Breite und einem für die Höhe zu speichern.
Matt K

Antworten:

498

HINWEIS: Obwohl dies die akzeptierte Antwort ist, ist es erwähnenswert, dass Sie in PHP 5.6+ konstante Arrays haben können - siehe Andrea Faulds Antwort unten .

Sie können Ihr Array auch serialisieren und dann in die Konstante einfügen:

# define constant, serialize array
define ("FRUITS", serialize (array ("apple", "cherry", "banana")));

# use it
$my_fruits = unserialize (FRUITS);
Gemeinschaft
quelle
40
Ich möchte nur sagen, dass ich diese Lösung liebe :)
GateKiller
16
Nett. Der schlechte Punkt ist jedoch, dass Sie auf diese Weise keine Klassenkonstante definieren können.
Gregoire
19
Halten Sie sich besser an statische Variablen in einer Klasse.
Jürgen Paul
5
Schade, dass Sie nicht tun können:$fruit = FRUITS[0];
Sophivorus
20
Dieser Code ist elegant, aber ziemlich langsam. Es ist weitaus besser, eine öffentliche statische Klassenmethode zu verwenden, die das Array zurückgibt.
Nomen
844

Seit PHP 5.6 können Sie eine Array-Konstante deklarieren mit const:

<?php
const DEFAULT_ROLES = array('guy', 'development team');

Die kurze Syntax funktioniert auch wie erwartet:

<?php
const DEFAULT_ROLES = ['guy', 'development team'];

Wenn Sie PHP 7 haben, können Sie es endlich verwenden define(), so wie Sie es zuerst versucht hatten:

<?php
define('DEFAULT_ROLES', array('guy', 'development team'));
Andrea
quelle
41
Dies muss positiv bewertet werden, da alle anderen Antworten veraltet sind oder nur von falsch informierten Benutzern geschrieben wurden.
Andreas Bergström
Ist das die einzige Syntax? Können Sie die alte Definitionsfunktion verwenden? define ('ARRAY_CONSTANT', Array ('item1', 'item2', 'item3'));
Jack
5
@JackNicholsonn Leider können Sie define()hier in PHP 5.6 nicht verwenden , aber dies wurde für PHP 7.0 behoben . :)
Andrea
@ AndreasBergström Nein, diese Frage ist zu neu. Diese Frage wurde 2009 gestellt! Diese Syntax wird heutzutage für die meisten Benutzer nahezu nutzlos sein. Fast jeder hat PHP 5.6 auf seinen Servern. Die anderen Antworten sind vollkommen in Ordnung, da sie auch Alternativen bieten. Die akzeptierte Antwort ist der einzig praktikable Weg, wenn Sie keine Klassen verwenden möchten.
Ismael Miguel
@IsmaelMiguel nicht so sicher sein, dass sie alle 5.6 haben. Jeder, der gerade einen Windows Server hat, hat vor ungefähr einem Monat die 5.6 SQL Server-Treiber von Microsoft erhalten.
MH
141

Sie können sie als statische Variablen einer Klasse speichern:

class Constants {
    public static $array = array('guy', 'development team');
}
# Warning: array can be changed lateron, so this is not a real constant value:
Constants::$array[] = 'newValue';

Wenn Ihnen die Idee nicht gefällt, dass das Array von anderen geändert werden kann, kann ein Getter hilfreich sein:

class Constants {
    private static $array = array('guy', 'development team');
    public static function getArray() {
        return self::$array;
    }
}
$constantArray = Constants::getArray();

BEARBEITEN

Seit PHP5.4 ist es sogar möglich, auf Array-Werte zuzugreifen, ohne dass Zwischenvariablen erforderlich sind, dh Folgendes funktioniert:

$x = Constants::getArray()['index'];
Soulmerge
quelle
1
+1. Ich werde dies seit Jahren const AtomicValue =42; public static $fooArray = ('how','di')
tun
9
Während es mir lächerlich erscheint, dass wir keine unveränderlichen Arrays in PHP erstellen können, bietet dies eine anständige Problemumgehung.
Akoi Meexx
Wenn Sie die Konstante häufig verwenden, würde ich einen Funktionsaufruf definitiv vermeiden, sie sind ziemlich teuer. Statisch ist der richtige Weg.
Chris Seufert
1
Diese Lösung war weitaus beeindruckender als ich erwartet hatte: Ich brauchte nur einen Teil der Werte des Arrays. Statt einfach das Array abzurufen, habe ich einige Parameter in der Funktion verwendet. In meinem Fall erhält ich mit Constants :: getRelatedIDs ($ myID) ein inneres Array mit genau den Werten, die ich benötige (ich führe auch eine ID-Validierung innerhalb dieser Funktion durch). @cseufert das ganze Array zu bekommen und für jeden Fall zu filtern wäre für mich viel teurer ...
Armfoot
1
Eine Funktion (getArray) mit einem privaten statischen Element zu haben, ist die beste Darstellung für Konstanten, da sie Änderungen sein können.
Kamaldeep singh Bhatia
41

Wenn Sie PHP 5.6 oder höher verwenden, verwenden Sie Andrea Faulds Antwort

Ich benutze es so. Ich hoffe, es wird anderen helfen.

config.php

class app{
    private static $options = array(
        'app_id' => 'hello',
    );
    public static function config($key){
        return self::$options[$key];
    }
}

In Datei, wo ich Konstanten brauche.

require('config.php');
print_r(app::config('app_id'));
Jashwant
quelle
Ich habe das Gleiche getan wie du. Also suchte ich nach Leistungsoptimierung, ob dies gut ist oder etwas anderes, wenn es besser ist.
NullPointer
Ja, ich stimme dieser Lösung zu. Da es einfach und leicht zu verstehen ist ...
Faris Rayhan
12

Das benutze ich. Es ähnelt dem Beispiel von soulmerge, aber auf diese Weise können Sie das vollständige Array oder nur einen einzelnen Wert im Array erhalten.

class Constants {
    private static $array = array(0 => 'apple', 1 => 'orange');

    public static function getArray($index = false) {
        return $index !== false ? self::$array[$index] : self::$array;
    }
}

Verwenden Sie es so:

Constants::getArray(); // Full array
// OR 
Constants::getArray(1); // Value of 1 which is 'orange'
Syclone
quelle
10

Sie können es als JSON-Zeichenfolge in einer Konstante speichern. Aus Anwendungssicht kann JSON in anderen Fällen nützlich sein.

define ("FRUITS", json_encode(array ("apple", "cherry", "banana")));    
$fruits = json_decode (FRUITS);    
var_dump($fruits);
Mahesh Talpade
quelle
Genau das habe ich mir gedacht. Ist das nicht eine rechtmäßig gute Antwort?
Con Antonakos
Dies funktioniert sehr gut mit AngularJS, da es JSON verbraucht. Ich denke, das ist viel besser als die Antwort auf die Serialisierung, aber gibt es einen Grund, warum die Serialisierung besser ist? Ist es vielleicht schneller?
Drellgor
Ja, Serialisieren ist technisch schneller. Für kleine Sets, was meistens benötigt wird, bevorzuge ich diese Methode, da sie sicherer ist. Wenn Sie unserialisieren, wird möglicherweise Code ausgeführt. Auch wenn dies in diesem Fall ein sehr geringes Risiko ist, sollten wir die Verwendung oder unserialisieren nur für Extremfälle reservieren.
Mario Awad
9

Ab PHP 5.6 können Sie konstante Arrays mit dem folgenden constSchlüsselwort definieren

const DEFAULT_ROLES = ['test', 'development', 'team'];

Auf verschiedene Elemente kann wie folgt zugegriffen werden:

echo DEFAULT_ROLES[1]; 
....

Ab PHP 7 können konstante Arrays wie folgt definiert werden define:

define('DEFAULT_ROLES', [
    'test',
    'development',
    'team'
]);

Auf verschiedene Elemente kann wie zuvor zugegriffen werden.

Altaf Hussain
quelle
3

Ich weiß, dass es eine etwas alte Frage ist, aber hier ist meine Lösung:

<?php
class Constant {

    private $data = [];

    public function define($constant, $value) {
        if (!isset($this->data[$constant])) {
            $this->data[$constant] = $value;
        } else {
            trigger_error("Cannot redefine constant $constant", E_USER_WARNING);
        }
    }

    public function __get($constant) {
        if (isset($this->data[$constant])) {
            return $this->data[$constant];
        } else {
            trigger_error("Use of undefined constant $constant - assumed '$constant'", E_USER_NOTICE);
            return $constant;
        }
    }

    public function __set($constant,$value) {
        $this->define($constant, $value);
    }

}
$const = new Constant;

Ich habe es definiert, weil ich Objekte und Arrays in Konstanten speichern musste, also habe ich auch Runkit auf PHP installiert, damit ich die Variable $ const superglobal machen kann.

Sie können es als $const->define("my_constant",array("my","values"));oder nur verwenden$const->my_constant = array("my","values");

Um den Wert zu erhalten, rufen Sie einfach an $const->my_constant;

Rikudou Sennin
quelle
Wow, ich habe so etwas nicht erwartet ... ich wusste nicht einmal davon __getund __set... ich muss sagen, dass diese Methode großartig ist.
RedClover
Diese werden als magische Methoden bezeichnet. Überprüfen Sie die PHP-Dokumentation.
Rikudou_Sennin
3

PHP 7+

Ab PHP 7 können Sie einfach die Funktion define () verwenden, um ein konstantes Array zu definieren:

define('ANIMALS', [
    'dog',
    'cat',
    'bird'
]);

echo ANIMALS[1]; // outputs "cat"
Rabin Lama Dong
quelle
3

Kann sogar mit assoziativen Arrays arbeiten .. zum Beispiel in einer Klasse.

class Test {

    const 
        CAN = [
            "can bark", "can meow", "can fly"
        ],
        ANIMALS = [
            self::CAN[0] => "dog",
            self::CAN[1] => "cat",
            self::CAN[2] => "bird"
        ];

    static function noParameter() {
        return self::ANIMALS[self::CAN[0]];
    }

    static function withParameter($which, $animal) {
        return "who {$which}? a {$animal}.";
    }

}

echo Test::noParameter() . "s " . Test::CAN[0] . ".<br>";
echo Test::withParameter(
    array_keys(Test::ANIMALS)[2], Test::ANIMALS["can fly"]
);

// dogs can bark.
// who can fly? a bird.
Thielicious
quelle
2

Mit der Explosions- und Implodierfunktion können wir eine Lösung improvisieren:

$array = array('lastname', 'email', 'phone');
define('DEFAULT_ROLES', implode (',' , $array));
echo explode(',' ,DEFAULT_ROLES ) [1]; 

Dies wird widerhallen email.

Wenn Sie möchten, dass es weiter optimiert wird, können Sie zwei Funktionen definieren, um die sich wiederholenden Dinge für Sie wie folgt zu erledigen:

//function to define constant
function custom_define ($const , $array) {
    define($const, implode (',' , $array));
}

//function to access constant  
function return_by_index ($index,$const = DEFAULT_ROLES) {
            $explodedResult = explode(',' ,$const ) [$index];
    if (isset ($explodedResult))
        return explode(',' ,$const ) [$index] ;
}

Ich hoffe, das hilft . Viel Spaß beim Codieren.

MD. Sahib Bin Mahboob
quelle
Sie können das zweimalige Explodieren verhindern, indem Sie Folgendes tun: $ explodeResult = explode (',', $ const); if (isset ($ explodeResult) [$ index]) {return $ explodeResult [$ index];}
Saeed
@ Saae yup das ist ein schöner Punkt. Ich werde meine Antwort entsprechend aktualisieren
MD. Sahib Bin Mahboob
2

Es scheint hässlich, eine Art Ser / Deser- oder Codierungs- / Decodierungs-Trick auszuführen, und Sie müssen sich daran erinnern, was genau Sie getan haben, als Sie versucht haben, die Konstante zu verwenden. Ich denke, die private statische Variable der Klasse mit Accessor ist eine anständige Lösung, aber ich werde Ihnen eine bessere machen. Verwenden Sie einfach eine öffentliche statische Getter-Methode, die die Definition des konstanten Arrays zurückgibt. Dies erfordert ein Minimum an zusätzlichem Code und die Array-Definition kann nicht versehentlich geändert werden.

class UserRoles {
    public static function getDefaultRoles() {
        return array('guy', 'development team');
    }
}

initMyRoles( UserRoles::getDefaultRoles() );

Wenn Sie es wirklich wie eine definierte Konstante aussehen lassen möchten, können Sie ihm einen Namen mit Großbuchstaben geben. Dann wäre es verwirrend, daran zu denken, die Klammern '()' nach dem Namen einzufügen.

class UserRoles {
    public static function DEFAULT_ROLES() { return array('guy', 'development team'); }
}

//but, then the extra () looks weird...
initMyRoles( UserRoles::DEFAULT_ROLES() );

Ich nehme an, Sie könnten die Methode global machen, um näher an der von Ihnen gewünschten define () -Funktionalität zu sein, aber Sie sollten den konstanten Namen trotzdem auf jeden Fall festlegen und globale Werte vermeiden.

Daniel Skarbek
quelle
2

Sie können so definieren

define('GENERIC_DOMAIN',json_encode(array(
    'gmail.com','gmail.co.in','yahoo.com'
)));

$domains = json_decode(GENERIC_DOMAIN);
var_dump($domains);
Fawwad
quelle
2

Ja, Sie können ein Array als konstant definieren. Ab PHP 5.6 ist es möglich, eine Konstante als skalaren Ausdruck zu definieren , und es ist auch möglich, eine Array-Konstante zu definieren . Es ist möglich, Konstanten als Ressource zu definieren, dies sollte jedoch vermieden werden, da dies zu unerwarteten Ergebnissen führen kann.

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

    // Works as of PHP 5.6.0
    const ANOTHER_CONST = CONSTANT.'; Goodbye World';
    echo ANOTHER_CONST;

    const ANIMALS = array('dog', 'cat', 'bird');
    echo ANIMALS[1]; // outputs "cat"

    // Works as of PHP 7
    define('ANIMALS', array(
        'dog',
        'cat',
        'bird'
    ));
    echo ANIMALS[1]; // outputs "cat"
?>

Mit dem Verweis auf diesen Link

Viel Spaß beim Codieren.

Sahil Patel
quelle
1

Wenn Sie dies ab 2009 suchen und AbstractSingletonFactoryGenerators nicht mögen, finden Sie hier einige andere Optionen.

Denken Sie daran, dass Arrays bei der Zuweisung "kopiert" oder in diesem Fall zurückgegeben werden, sodass Sie praktisch jedes Mal das gleiche Array erhalten. (Siehe Copy-on-Write-Verhalten von Arrays in PHP.)

function FRUITS_ARRAY(){
  return array('chicken', 'mushroom', 'dirt');
}

function FRUITS_ARRAY(){
  static $array = array('chicken', 'mushroom', 'dirt');
  return $array;
}

function WHAT_ANIMAL( $key ){
  static $array = (
    'Merrick' => 'Elephant',
    'Sprague' => 'Skeleton',
    'Shaun'   => 'Sheep',
  );
  return $array[ $key ];
}

function ANIMAL( $key = null ){
  static $array = (
    'Merrick' => 'Elephant',
    'Sprague' => 'Skeleton',
    'Shaun'   => 'Sheep',
  );
  return $key !== null ? $array[ $key ] : $array;
}
biziclop
quelle
Wir sind seit vielen Jahren in der Lage, Arrays als Konstanten zu definieren. Ich glaube, es gibt nicht mehr viel Wert, um Problemumgehungen zu umgehen.
Miken32
1
@ miken32 Während true, ist die bereitgestellte Lösung interessant, wurde von niemand anderem bereitgestellt und kann bei Bedarf konzeptionell auf andere Sprachen angewendet werden (fügen Sie sie Ihrer
Toolbox hinzu
1

Wenn Sie PHP 7 & 7+ verwenden, können Sie auch Fetch wie folgt verwenden

define('TEAM', ['guy', 'development team']);
echo TEAM[0]; 
// output from system will be "guy"
Mac Rathod
quelle
0

Konstanten können nur skalare Werte enthalten. Ich schlage vor, Sie speichern die Serialisierung (oder JSON-codierte Darstellung) des Arrays.

Alix Axel
quelle
1
Dies fügt der akzeptierten Antwort nichts hinzu. Vielleicht sollte sie gelöscht werden?
Ian Dunn
4
@IanDunn: Ich würde argumentieren, dass die akzeptierte Antwort nicht erklärt, warum oder dass sie meiner Antwort nichts hinzufügt, aber ... Sie können jederzeit abstimmen, um sie zu löschen.
Alix Axel
1
Ich sehe nicht wirklich den Sinn einer Zeichenfolgendarstellung des gewünschten Arrays.
Tomáš Zato - Wiedereinsetzung Monica