Constantes PHP contenant des tableaux?

408

Cela a échoué:

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

Apparemment, les constantes ne peuvent pas contenir de tableaux. Quelle est la meilleure façon de contourner cela?

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

//...

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

Cela semble être un effort inutile.

Nick Heiner
la source
17
PHP 5.6 prend en charge les tableaux constants, voir ma réponse ci-dessous.
Andrea
1
Quand auriez-vous besoin d'utiliser un tableau comme constante, essayez-vous de faire une énumération? Si oui, alors utilisez SplEnum: php.net/manual/en/class.splenum.php
ziGi
2
@ziGi est venu sur ce problème aujourd'hui, a différents types d'images à stocker qui nécessitent des dimensions spécifiques, il est devenu utile de stocker ces dimensions sous forme de tableaux constants au lieu d'un pour la largeur et un pour la hauteur.
Matt K

Réponses:

499

REMARQUE: bien qu'il s'agisse de la réponse acceptée, il convient de noter qu'en PHP 5.6+, vous pouvez avoir des tableaux const - voir la réponse d'Andrea Faulds ci-dessous .

Vous pouvez également sérialiser votre baie puis la mettre dans la constante:

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

# use it
$my_fruits = unserialize (FRUITS);
Communauté
la source
40
Je veux juste dire que j'aime cette solution :)
GateKiller
16
Agréable. Mais le mauvais point est que vous ne pouvez pas définir une constante de classe de cette façon.
Gregoire
19
mieux s'en tenir aux variables statiques dans une classe.
Jürgen Paul
5
Dommage que vous ne puissiez pas faire:$fruit = FRUITS[0];
Sophivorus
20
Ce code est élégant mais assez lent. Il est préférable d'utiliser une méthode de classe statique publique qui renvoie le tableau.
nom
844

Depuis PHP 5.6, vous pouvez déclarer une constante de tableau avec const:

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

La syntaxe courte fonctionne également, comme vous pouvez vous y attendre:

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

Si vous avez PHP 7, vous pouvez enfin utiliser define(), comme vous l'aviez d'abord essayé:

<?php
define('DEFAULT_ROLES', array('guy', 'development team'));
Andrea
la source
41
Cela doit être voté car toutes les autres réponses sont obsolètes ou simplement écrites par des utilisateurs mal informés.
Andreas Bergström
Est-ce la seule syntaxe? Pouvez-vous utiliser l'ancienne fonction de définition? define ('ARRAY_CONSTANT', array ('item1', 'item2', 'item3'));
Jack
5
@JackNicholsonn Malheureusement, vous ne pouvez pas utiliser define()ici en PHP 5.6, mais cela a été corrigé pour PHP 7.0 . :)
Andrea
@ AndreasBergström Non, cette question est trop nouvelle. Cette question a été posée en 2009! Cette syntaxe sera presque inutile pour la plupart des utilisateurs de nos jours. Presque n'importe qui a PHP 5.6 sur ses serveurs. Les autres réponses sont parfaitement correctes car elles offrent également des alternatives. La réponse acceptée est le seul moyen viable à ce jour, si vous ne souhaitez pas utiliser les classes.
Ismael Miguel
@IsmaelMiguel ne soyez pas si sûr qu'ils ont tous 5.6. Tout le monde sur le serveur Windows vient de recevoir les pilotes de serveur 5.6 sql de Microsoft il y a environ un mois.
MH
141

Vous pouvez les stocker en tant que variables statiques d'une classe:

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';

Si vous n'aimez pas l'idée que le tableau puisse être modifié par d'autres, un getter pourrait vous aider:

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

ÉDITER

Depuis PHP5.4, il est même possible d'accéder aux valeurs des tableaux sans avoir besoin de variables intermédiaires, c'est-à-dire les travaux suivants:

$x = Constants::getArray()['index'];
soulmerge
la source
1
+1. J'y vais depuis des années:const AtomicValue =42; public static $fooArray = ('how','di')
Frank Nocke
9
Bien qu'il me semble ridicule que nous ne puissions pas créer de tableaux immuables en php, cela fournit une solution de contournement décente.
Akoi Meexx
Si vous utilisez beaucoup la constante, j'éviterais certainement un appel de fonction, ils sont assez chers. La statique est la voie à suivre.
Chris Seufert
1
Cette solution était beaucoup plus impressionnante que ce à quoi je m'attendais: je n'avais besoin que d'une partie des valeurs du tableau, donc au lieu de simplement obtenir le tableau, j'ai utilisé certains paramètres dans la fonction. Dans mon cas, Constants :: getRelatedIDs ($ myID) m'obtient un tableau interne avec juste les valeurs dont j'avais besoin (je fais aussi une validation d'ID dans cette fonction). @cseufert obtenir le tableau complet et le filtrage pour chaque cas serait beaucoup plus cher pour moi ...
Armfoot
1
avoir une fonction (getArray) avec un membre statique privé est la meilleure représentation pour les constantes car elles peuvent être des changements 👍🏻
Kamaldeep singh Bhatia
41

Si vous utilisez PHP 5.6 ou supérieur, utilisez la réponse d'Andrea Faulds

Je l'utilise comme ça. J'espère que cela aidera les autres.

config.php

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

En dossier, où j'ai besoin de constantes.

require('config.php');
print_r(app::config('app_id'));
Jashwant
la source
J'ai fait la même chose que toi. Je cherchais donc une optimisation des performances, que ce soit bon ou autre chose, si c'est mieux.
NullPointer
Ya je suis d'accord avec cette solution. Comme c'est simple et facile à comprendre ...
Faris Rayhan
12

C'est ce que j'utilise. Il est similaire à l'exemple fourni par soulmerge, mais de cette façon, vous pouvez obtenir le tableau complet ou juste une seule valeur dans le tableau.

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

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

Utilisez-le comme ceci:

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

Vous pouvez le stocker sous forme de chaîne JSON dans une constante. Et du point de vue de l'application, JSON peut être utile dans d'autres cas.

define ("FRUITS", json_encode(array ("apple", "cherry", "banana")));    
$fruits = json_decode (FRUITS);    
var_dump($fruits);
Mahesh Talpade
la source
C'est exactement ce que je pensais. N'est-ce pas une bonne réponse légitime?
Con Antonakos
Cela fonctionne très bien avec AngularJS car il consomme du JSON. Je pense que c'est beaucoup mieux que la réponse de sérialisation, mais y a-t-il une raison pour laquelle la sérialisation est meilleure? Est-ce que c'est plus rapide peut-être?
Drellgor
Oui, la sérialisation est techniquement plus rapide. Cependant, pour les petits ensembles, ce qui est le plus nécessaire, je préfère cette méthode car elle est plus sûre. Lorsque vous désérialisez, le code peut être exécuté. Même si dans ce cas, il s'agit d'un risque très faible, je pense que nous devrions réserver l'utilisation ou la désérialisation uniquement aux cas extrêmes.
Mario Awad du
9

À partir de PHP 5.6, vous pouvez définir des tableaux constants à l'aide de constmots clés comme ci-dessous

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

et différents éléments sont accessibles comme ci-dessous:

echo DEFAULT_ROLES[1]; 
....

À partir de PHP 7, les tableaux constants peuvent être définis en utilisant definecomme ci-dessous:

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

et différents éléments sont accessibles de la même manière qu'auparavant.

Altaf Hussain
la source
3

Je sais que c'est une question un peu ancienne, mais voici ma solution:

<?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;

Je l'ai défini car j'avais besoin de stocker des objets et des tableaux dans des constantes, j'ai donc installé également runkit sur php pour pouvoir rendre la variable $ const superglobale.

Vous pouvez l'utiliser comme $const->define("my_constant",array("my","values"));ou simplement$const->my_constant = array("my","values");

Pour obtenir la valeur, appelez simplement $const->my_constant;

Rikudou sennin
la source
Wow, je ne m'attendais pas à ça ... je ne savais même pas __getet __set... je dois dire que cette méthode est géniale.
RedClover
Celles-ci sont appelées méthodes magiques, consultez la documentation php à leur sujet.
Rikudou_Sennin
3

PHP 7+

Depuis PHP 7, vous pouvez simplement utiliser la fonction define () pour définir un tableau constant:

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

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

Peut même fonctionner avec des tableaux associatifs .. par exemple dans une classe.

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
la source
2

En utilisant la fonction exploser et imploser, nous pouvons improviser une solution:

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

Cela fera écho email.

Si vous voulez l'optimiser davantage, vous pouvez définir 2 fonctions pour faire les choses répétitives pour vous comme ceci:

//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] ;
}

J'espère que cela pourra aider . Codage heureux.

MARYLAND. Sahib Bin Mahboob
la source
vous pouvez empêcher l'explosion deux fois en faisant: $ explodeResult = explode (',', $ const); if (isset ($ explodeResult) [$ index]) {return $ explodeResult [$ index];}
Saeed
@Saeed yup c'est un bon point. Je mettrai à jour ma réponse en conséquence
MD. Sahib Bin Mahboob
2

Faire une sorte de truc ser / deser ou encoder / décoder semble moche et vous oblige à vous souvenir de ce que vous avez fait exactement lorsque vous essayez d'utiliser la constante. Je pense que la variable statique privée de classe avec accesseur est une solution décente, mais je vous ferai mieux. Il suffit d'avoir une méthode getter statique publique qui renvoie la définition du tableau constant. Cela nécessite un minimum de code supplémentaire et la définition du tableau ne peut pas être accidentellement modifiée.

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

initMyRoles( UserRoles::getDefaultRoles() );

Si vous voulez vraiment le faire ressembler à une constante définie, vous pouvez lui donner un nom tout en majuscules, mais il serait déroutant de se rappeler d'ajouter les parenthèses '()' après le nom.

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

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

Je suppose que vous pourriez rendre la méthode globale pour être plus proche de la fonctionnalité define () que vous demandiez, mais vous devriez vraiment cibler le nom constant de toute façon et éviter les globaux.

Daniel Skarbek
la source
2

Vous pouvez définir comme ceci

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

$domains = json_decode(GENERIC_DOMAIN);
var_dump($domains);
Fawwad
la source
2

Oui, vous pouvez définir un tableau comme constant. A partir de PHP 5.6 , il est possible de définir une constante comme expression scalaire, et il est également possible de définir une constante de tableau . Il est possible de définir des constantes en tant que ressource, mais cela doit être évité, car cela peut entraîner des résultats inattendus.

<?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"
?>

Avec la référence de ce lien

Ayez un codage heureux.

Sahil Patel
la source
1

Si vous recherchez cela depuis 2009 et que vous n'aimez pas AbstractSingletonFactoryGenerators, voici quelques autres options.

N'oubliez pas que les tableaux sont "copiés" lorsqu'ils sont attribués ou, dans ce cas, retournés, vous obtenez donc pratiquement le même tableau à chaque fois. (Voir le comportement de copie sur écriture des tableaux en 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
la source
Nous avons été en mesure de définir des tableaux en tant que constantes depuis de nombreuses années maintenant, je ne pense plus qu'il y ait beaucoup de valeur à obtenir des solutions de contournement.
miken32
1
@ miken32 bien que vrai, la solution fournie est intéressante, n'a été fournie par personne d'autre et peut être appliquée conceptuellement à d'autres langues selon les besoins (ajoutez-la à votre boîte à outils)
puiu
1

si vous utilisez PHP 7 et 7+, vous pouvez également utiliser la récupération comme ceci

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

Les constantes ne peuvent contenir que des valeurs scalaires, je vous suggère de stocker la sérialisation (ou la représentation codée JSON) du tableau.

Alix Axel
la source
1
Cela n'ajoute rien à la réponse acceptée, alors peut-être devrait-elle être supprimée?
Ian Dunn
4
@IanDunn: Je dirais que la réponse acceptée n'explique pas pourquoi, ou qu'elle n'ajoute rien à ma réponse mais ... N'hésitez pas à voter pour supprimer.
Alix Axel
1
Je ne vois pas vraiment l'intérêt d'une représentation sous forme de chaîne du tableau souhaité.
Tomáš Zato - Rétablir Monica le