Costanti PHP contenenti array?


408

Questo non è riuscito:

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

Apparentemente, le costanti non possono contenere array. Qual è il modo migliore per aggirare questo?

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

//...

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

Questo sembra uno sforzo inutile.


17
PHP 5.6 supporta array costanti, vedi la mia risposta di seguito.
Andrea,

1
Quando dovresti usare un array come costante, stai provando a fare un conteggio? Se è così, quindi utilizzare SplEnum: php.net/manual/en/class.splenum.php
Zigi

2
@ziGi Oggi sono venuti a conoscenza di questo problema, hanno diversi tipi di immagini da memorizzare che richiedono dimensioni specifiche, è diventato utile memorizzare queste dimensioni come array costanti anziché uno per larghezza e uno per altezza.
Matt K,

Risposte:


499

NOTA: sebbene questa sia la risposta accettata, vale la pena notare che in PHP 5.6+ è possibile disporre di array cost - vedere la risposta di Andrea Faulds di seguito .

Puoi anche serializzare l'array e inserirlo nella costante:

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

# use it
$my_fruits = unserialize (FRUITS);

40
Voglio solo dire che adoro questa soluzione :)
GateKiller,

16
Bello. Ma il punto negativo è che non puoi definire una costante di classe in questo modo.
Gregoire,

19
meglio attenersi alle variabili statiche in una classe.
Jürgen Paul,

5
Peccato che non puoi fare:$fruit = FRUITS[0];
Sophivorus

20
Questo codice è elegante ma piuttosto lento. È molto meglio usare un metodo di classe statica pubblica che restituisce l'array.
sostantivo

844

Da PHP 5.6, puoi dichiarare una costante di array con const:

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

La sintassi breve funziona anche, come ci si aspetterebbe:

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

Se hai PHP 7, puoi finalmente usare define(), proprio come hai provato per la prima volta:

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

41
Questo deve essere valutato in quanto tutte le altre risposte sono obsolete o semplicemente scritte da utenti male informati.
Andreas Bergström,

È l'unica sintassi? Sei in grado di utilizzare la vecchia funzione di definizione? define ('ARRAY_CONSTANT', array ('item1', 'item2', 'item3'));
Jack,

5
@JackNicholsonn Purtroppo non è possibile utilizzare define()qui in PHP 5.6, ma questo è stato risolto per PHP 7.0 . :)
Andrea,

@ AndreasBergström No, questa domanda è troppo nuova. Questa domanda è stata fatta nel 2009! Questa sintassi sarà quasi inutile per la maggior parte degli utenti al giorno d'oggi. Quasi tutti hanno PHP 5.6 sui loro server. Le altre risposte vanno benissimo poiché offrono anche alternative. La risposta accettata è l'unica strada percorribile finora, se non si desidera utilizzare le classi.
Ismael Miguel,

@IsmaelMiguel non essere così sicuro che tutti abbiano 5.6. Chiunque su Windows Server ha appena ricevuto i driver del server 5.6 sql da Microsoft circa un mese fa.
MH,

141

Puoi memorizzarli come variabili statiche di una 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';

Se non ti piace l'idea che l'array possa essere modificato da altri, un getter potrebbe aiutarti:

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

MODIFICARE

A partire da PHP5.4, è persino possibile accedere ai valori dell'array senza la necessità di variabili intermedie, ovvero i seguenti lavori:

$x = Constants::getArray()['index'];

1
+1. Ci vado da anni:const AtomicValue =42; public static $fooArray = ('how','di')
Frank Nocke,

9
Mentre mi sembra ridicolo che non possiamo creare array immutabili in php, questo fornisce una soluzione decente.
Akoi Meexx,

Se usi molto la costante, eviterei sicuramente una chiamata di funzione, sono piuttosto costosi. Statico è la strada da percorrere.
Chris Seufert,

1
Questa soluzione è stata molto più fantastica di quanto mi aspettassi: avevo solo bisogno di parte dei valori dell'array, quindi invece di ottenere semplicemente l'array, ho usato alcuni parametri nella funzione. Nel mio caso Constants :: getRelatedIDs ($ myID) mi fornisce un array interno con solo i valori di cui avevo bisogno (eseguo anche una convalida dell'ID all'interno di questa funzione). @cseufert ottenere l'intero array e filtrare per ogni caso sarebbe molto più costoso per me ...
Armfoot

1
avere una funzione (getArray) con membro statico privato è la migliore rappresentazione per le costanti in quanto possono essere cambiamenti 👍🏻
Kamaldeep singh Bhatia

41

Se stai usando PHP 5.6 o versioni successive, usa la risposta di Andrea Faulds

Lo sto usando in questo modo. Spero che aiuterà gli altri.

config.php

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

Nel file, dove ho bisogno di costanti.

require('config.php');
print_r(app::config('app_id'));

Ho fatto lo stesso di te. Quindi cercavo l'ottimizzazione delle prestazioni se questo è buono o qualcos'altro se migliore.
NullPointer

Ya sono d'accordo con questa soluzione. Come è semplice e facile da capire ...
Faris Rayhan,

12

Questo è quello che uso. È simile all'esempio fornito da soulmerge, ma in questo modo è possibile ottenere l'array completo o solo un singolo valore nell'array.

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

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

Usalo in questo modo:

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

10

È possibile memorizzarlo come stringa JSON in una costante. E dal punto di vista dell'applicazione, JSON può essere utile in altri casi.

define ("FRUITS", json_encode(array ("apple", "cherry", "banana")));    
$fruits = json_decode (FRUITS);    
var_dump($fruits);

Questo è esattamente quello che stavo pensando. Non è una risposta legittima?
Con Antonakos,

Funziona davvero bene con AngularJS perché consuma JSON. Sento che questo è molto meglio della risposta serializzata, ma c'è qualche ragione per cui la serializzazione è migliore? Forse è più veloce?
Drellgor,

Sì, serializzare è tecnicamente più veloce. Tuttavia, per piccoli set, che è ciò che è maggiormente necessario, preferisco questo metodo perché è più sicuro. Quando si annulla la serializzazione, il codice potrebbe essere eseguito. Anche se in questo caso si tratta di un rischio molto basso, penso che dovremmo riservare l'uso o annullare la serializzazione solo per casi estremi.
Mario Awad,

9

A partire da PHP 5.6, puoi definire array costanti usando la constparola chiave come di seguito

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

e diversi elementi sono accessibili come di seguito:

echo DEFAULT_ROLES[1]; 
....

A partire da PHP 7, le matrici costanti possono essere definite definecome di seguito:

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

e si può accedere a elementi diversi come prima.


3

So che è una domanda un po 'vecchia, ma ecco la mia soluzione:

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

L'ho definito perché avevo bisogno di memorizzare oggetti e matrici in costanti, quindi ho installato anche runkit su php in modo da rendere superglobal la variabile $ const.

Puoi usarlo come $const->define("my_constant",array("my","values"));o solo$const->my_constant = array("my","values");

Per ottenere il valore basta semplicemente chiamare $const->my_constant;


Caspita, non me l'aspettavo in questo modo ... Non sapevo nemmeno __gete __set... Devo dire che questo metodo è eccezionale.
RedClover

Questi sono chiamati metodi magici, controlla la documentazione php su di loro.
Rikudou_Sennin

3

PHP 7+

A partire da PHP 7, puoi semplicemente usare la funzione define () per definire un array costante:

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

echo ANIMALS[1]; // outputs "cat"

3

Può persino lavorare con array associativi .. ad esempio in una 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.

2

Usando la funzione esplodere e implodere possiamo improvvisare una soluzione:

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

Questo echeggerà email.

Se vuoi che lo ottimizzi di più, puoi definire 2 funzioni per fare le cose ripetitive per te in questo modo:

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

Spero che aiuti . Buona codifica.


puoi evitare di esplodere due volte facendo: $ explodeResult = explode (',', $ const); if (isset ($ explodeResult) [$ index]) {return $ explodeResult [$ index];}
Saeed,

@Saeed yup questo è un bel punto. Aggiornerò la mia risposta di conseguenza
MD. Sahib Bin Mahboob,

2

Fare una sorta di trucco ser / deser o di codifica / decodifica sembra brutto e richiede di ricordare cosa hai fatto esattamente quando stai cercando di usare la costante. Penso che la variabile statica privata di classe con accessor sia una soluzione decente, ma farò di meglio. Basta avere un metodo getter statico pubblico che restituisce la definizione dell'array costante. Ciò richiede un minimo di codice aggiuntivo e la definizione dell'array non può essere modificata accidentalmente.

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

initMyRoles( UserRoles::getDefaultRoles() );

Se vuoi davvero farlo sembrare una costante definita potresti dargli un nome tutto maiuscolo, ma sarebbe confuso ricordare di aggiungere le parentesi '()' dopo il nome.

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

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

Suppongo che tu possa rendere il metodo globale più vicino alla funzionalità define () che stavi chiedendo, ma dovresti comunque considerare il nome costante ed evitare i globali.


2

Puoi definire così

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

$domains = json_decode(GENERIC_DOMAIN);
var_dump($domains);

2

Sì, è possibile definire un array come costante. Da PHP 5.6 in poi , è possibile definire una costante come espressione scalare ed è anche possibile definire una costante di array . È possibile definire le costanti come una risorsa, ma dovrebbe essere evitato, in quanto può causare risultati imprevisti.

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

Con il riferimento di questo link

Buona codifica.


1

Se stai cercando questo dal 2009 e non ti piace AbstractSingletonFactoryGenerators, ecco alcune altre opzioni.

Ricorda, le matrici vengono "copiate" quando assegnate, o in questo caso, restituite, quindi praticamente ottieni sempre la stessa matrice. (Vedi comportamento copia su scrittura degli array 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;
}

Siamo in grado di definire le matrici come costanti da molti anni ormai, non credo che ci sia molto valore per otturare soluzioni alternative.
miken32,

1
@miken32 è vero, la soluzione fornita è interessante, non è stata fornita da nessun altro e può essere concettualmente applicata ad altre lingue secondo necessità (aggiungila alla tua cassetta degli attrezzi)
puiu,

1

se stai usando PHP 7 e 7+, puoi usare anche fetch in questo modo

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

0

Le costanti possono contenere solo valori scalari, ti suggerisco di memorizzare la serializzazione (o la rappresentazione codificata JSON) dell'array.


1
Questo non aggiunge nulla alla risposta accettata, quindi forse dovrebbe essere eliminato?
Ian Dunn,

4
@IanDunn: Direi che la risposta accettata non spiega il perché, o che non aggiunge nulla alla mia risposta ma ... Sentiti libero di votare per cancellare però.
Alix Axel,

1
Non vedo davvero il punto di nessuna rappresentazione di stringa dell'array desiderato.
Tomáš Zato - Ripristina Monica
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.