PHP Contants Contays Arrays?

408

Ini gagal:

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

Rupanya, konstanta tidak dapat menahan array. Apa cara terbaik untuk mengatasi ini?

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

//...

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

Ini sepertinya upaya yang tidak perlu.

Nick Heiner
sumber
17
PHP 5.6 mendukung array konstan, lihat jawaban saya di bawah ini.
Andrea
1
Kapan Anda perlu menggunakan array sebagai konstanta, apakah Anda mencoba melakukan enumerasi? Jika demikian, maka gunakan SplEnum: php.net/manual/en/class.splenum.php
ziGi
2
@ziGi Datang pada masalah ini hari ini, memiliki berbagai jenis gambar untuk menyimpan yang memerlukan dimensi tertentu, menjadi berguna untuk menyimpan dimensi ini sebagai array konstan, bukan satu untuk lebar dan satu untuk tinggi.
Matt K

Jawaban:

499

CATATAN: sementara ini adalah jawaban yang diterima, perlu dicatat bahwa dalam PHP 5.6+ Anda dapat memiliki array const - lihat jawaban Andrea Faulds di bawah ini .

Anda juga bisa membuat serialisasi array Anda dan kemudian memasukkannya ke dalam konstanta:

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

# use it
$my_fruits = unserialize (FRUITS);
Komunitas
sumber
40
Hanya ingin mengatakan saya suka solusi ini :)
GateKiller
16
Bagus. Tetapi poin buruknya adalah Anda tidak dapat mendefinisikan konstanta kelas dengan cara ini.
Gregoire
19
lebih baik tetap pada variabel statis di kelas.
Jürgen Paul
5
Sayang sekali Anda tidak dapat melakukan:$fruit = FRUITS[0];
Sophivorus
20
Kode ini elegan tetapi sangat lambat. Jauh lebih baik menggunakan metode kelas statis publik yang mengembalikan array.
kata benda
844

Sejak PHP 5.6, Anda dapat mendeklarasikan konstanta array dengan const:

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

Sintaks pendek juga berfungsi, seperti yang Anda harapkan:

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

Jika Anda memiliki PHP 7, Anda akhirnya dapat menggunakan define(), seperti yang pertama kali Anda coba:

<?php
define('DEFAULT_ROLES', array('guy', 'development team'));
Andrea
sumber
41
Ini perlu diputuskan karena semua jawaban lain sudah usang atau hanya ditulis oleh pengguna yang salah informasi.
Andreas Bergström
Apakah itu satu-satunya sintaks? Apakah Anda dapat menggunakan fungsi define lama? define ('ARRAY_CONSTANT', array ('item1', 'item2', 'item3'));
Jack
5
@JackNicholsonn Sayangnya Anda tidak dapat menggunakan define()di sini di PHP 5.6, tetapi ini telah diperbaiki untuk PHP 7.0 . :)
Andrea
@ AndreasBergström Tidak, pertanyaan ini terlalu baru. Pertanyaan ini dibuat pada tahun 2009! Sintaks ini hampir tidak berguna untuk sebagian besar pengguna sekarang-a-hari. Hampir setiap orang memiliki PHP 5.6 di server mereka. Jawaban lain baik-baik saja karena mereka juga menawarkan alternatif. Jawaban yang diterima adalah satu-satunya cara yang layak sejauh ini, jika Anda tidak ingin menggunakan kelas.
Ismael Miguel
@ IsmaelMiguel jangan begitu yakin mereka semua memiliki 5.6. Siapa pun di windows server sekarang mendapat driver server 5,6 sql dari microsoft sekitar sebulan yang lalu.
MH
141

Anda bisa menyimpannya sebagai variabel statis suatu kelas:

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

Jika Anda tidak menyukai gagasan bahwa array dapat diubah oleh orang lain, seorang pengambil dapat membantu:

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

EDIT

Sejak PHP5.4, bahkan dimungkinkan untuk mengakses nilai-nilai array tanpa perlu variabel perantara, yaitu yang berikut berfungsi:

$x = Constants::getArray()['index'];
soulmerge
sumber
1
+1. Saya akan melakukannya selama bertahun-tahun:const AtomicValue =42; public static $fooArray = ('how','di')
Frank Nocke
9
Walaupun tampaknya konyol bagi saya bahwa kita tidak dapat membuat array yang tidak dapat diubah di php, ini memberikan solusi yang layak.
Akoi Meexx
Jika Anda sering menggunakan konstanta, saya pasti akan menghindari panggilan fungsi, mereka cukup mahal. Statis adalah jalan yang harus ditempuh.
Chris Seufert
1
Solusi ini jauh lebih dahsyat daripada yang saya perkirakan: Saya hanya membutuhkan sebagian dari nilai-nilai array, oleh karena itu alih-alih hanya mendapatkan array, saya menggunakan beberapa parameter dalam fungsi. Dalam kasus saya, Konstanta :: getRelatedIDs ($ myID) membuat saya array internal hanya dengan nilai yang saya butuhkan (saya juga melakukan beberapa validasi ID di dalam fungsi ini). @cseufert mendapatkan seluruh array dan pemfilteran untuk setiap kasing akan jauh lebih mahal bagi saya ...
Armfoot
1
memiliki fungsi (getArray) dengan anggota statis pribadi adalah representasi terbaik untuk konstanta karena mereka dapat berubah 👍🏻
Kamaldeep singh Bhatia
41

Jika Anda menggunakan PHP 5.6 atau lebih tinggi, gunakan jawaban Andrea Faulds

Saya menggunakannya seperti ini. Saya harap, ini akan membantu orang lain.

config.php

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

Dalam file, di mana saya membutuhkan konstanta.

require('config.php');
print_r(app::config('app_id'));
Jashwant
sumber
Saya melakukan hal yang sama seperti Anda. Jadi sedang mencari optimasi kinerja apakah ini baik atau sesuatu yang lain jika lebih baik.
NullPointer
Ya saya setuju dengan solusi ini. Karena sederhana dan mudah dipahami ...
Faris Rayhan
12

Inilah yang saya gunakan. Ini mirip dengan contoh yang diberikan oleh soulmerge, tetapi dengan cara ini Anda bisa mendapatkan array penuh atau hanya satu nilai tunggal dalam 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;
    }
}

Gunakan seperti ini:

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

Anda bisa menyimpannya sebagai string JSON dalam konstanta. Dan sudut pandang aplikasi, JSON dapat berguna dalam kasus lain.

define ("FRUITS", json_encode(array ("apple", "cherry", "banana")));    
$fruits = json_decode (FRUITS);    
var_dump($fruits);
Talpade Mahesh
sumber
Inilah yang saya pikirkan. Apakah ini bukan jawaban yang baik dan sah?
Con Antonakos
Ini bekerja sangat baik dengan AngularJS karena mengkonsumsi JSON. Saya merasa ini jauh lebih baik daripada jawaban serialisasi, tetapi adakah alasan mengapa serialisasi lebih baik? Apakah mungkin lebih cepat?
Drellgor
Ya, serialisasi secara teknis lebih cepat. Namun, untuk set kecil, yang paling dibutuhkan, saya lebih suka metode ini karena lebih aman. Ketika Anda membatalkan registrasi, kode mungkin dieksekusi. Bahkan jika dalam kasus ini ini adalah risiko yang sangat rendah, saya pikir kita harus mencadangkan penggunaan atau membatalkan pengunaan untuk kasus-kasus ekstrim saja.
Mario Awad
9

Dimulai dengan PHP 5.6, Anda dapat menentukan array konstan menggunakan constkata kunci seperti di bawah ini

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

dan berbagai elemen dapat diakses seperti di bawah ini:

echo DEFAULT_ROLES[1]; 
....

Dimulai dengan PHP 7, array konstan dapat didefinisikan menggunakan defineseperti di bawah ini:

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

dan berbagai elemen dapat diakses dengan cara yang sama seperti sebelumnya.

Altaf Hussain
sumber
3

Saya tahu ini pertanyaan yang agak lama, tapi ini solusinya:

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

Saya mendefinisikannya karena saya perlu menyimpan objek dan array dalam konstanta jadi saya menginstal juga runkit ke php sehingga saya bisa membuat variabel $ const superglobal.

Anda bisa menggunakannya sebagai $const->define("my_constant",array("my","values"));atau hanya$const->my_constant = array("my","values");

Untuk mendapatkan nilai cukup menelepon saja $const->my_constant;

Rikudou Sennin
sumber
Wow, saya tidak mengharapkan seperti itu ... Saya bahkan tidak tahu __getdan __set... Saya harus mengatakan bahwa metode ini hebat.
RedClover
Ini disebut metode ajaib, periksa dokumentasi php tentang mereka.
Rikudou_Sennin
3

PHP 7+

Pada PHP 7, Anda bisa menggunakan fungsi define () untuk mendefinisikan array konstan:

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

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

Bahkan dapat bekerja dengan Array Asosiatif .. misalnya di dalam kelas.

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.
Sangat berbahaya
sumber
2

Menggunakan fungsi explode dan implode kita dapat berimprovisasi solusi:

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

Ini akan bergema email.

Jika Anda ingin lebih mengoptimalkannya, Anda dapat menentukan 2 fungsi untuk melakukan hal-hal berulang untuk Anda seperti ini:

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

Semoga itu bisa membantu. Selamat coding.

MD. Sahib Bin Mahboob
sumber
Anda dapat mencegah meledak dua kali dengan melakukan: $ explodeResult = explode (',', $ const); if (isset ($ explodeResult) [$ index]) {return $ explodeResult [$ index];}
Saeed
@Sayeed yup itu poin yang bagus. Saya akan memperbarui jawaban saya sesuai
MD. Sahib Bin Mahboob
2

Melakukan semacam trik ser / deser atau encode / decode tampaknya jelek dan mengharuskan Anda untuk mengingat apa yang sebenarnya Anda lakukan ketika Anda mencoba menggunakan konstanta. Saya pikir variabel statis kelas privat dengan accessor adalah solusi yang layak, tetapi saya akan melakukan yang lebih baik. Hanya memiliki metode pengambil statis publik yang mengembalikan definisi array konstan. Ini membutuhkan minimal kode tambahan dan definisi array tidak dapat dimodifikasi secara tidak sengaja.

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

initMyRoles( UserRoles::getDefaultRoles() );

Jika Anda benar-benar ingin membuatnya terlihat seperti konstanta yang didefinisikan, Anda dapat memberikannya semua nama kapitalisasi, tetapi akan membingungkan untuk mengingat untuk menambahkan tanda kurung '()' setelah nama.

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

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

Saya kira Anda bisa membuat metode global menjadi lebih dekat dengan fungsionalitas define () yang Anda minta, tetapi Anda benar-benar harus menentukan cakupan nama tetap dan menghindari global.

Daniel Skarbek
sumber
2

Anda dapat mendefinisikan seperti ini

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

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

Ya, Anda bisa mendefinisikan array sebagai konstanta. Dari PHP 5.6 dan selanjutnya , dimungkinkan untuk mendefinisikan konstanta sebagai ekspresi skalar, dan juga dimungkinkan untuk mendefinisikan konstanta array . Dimungkinkan untuk mendefinisikan konstanta sebagai sumber daya, tetapi harus dihindari, karena dapat menyebabkan hasil yang tidak terduga.

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

Dengan referensi tautan ini

Selamat coding.

Sahil Patel
sumber
1

Jika Anda mencari ini dari 2009, dan Anda tidak suka AbstractSingletonFactoryGenerators, berikut adalah beberapa opsi lain.

Ingat, array "disalin" ketika ditugaskan, atau dalam hal ini, dikembalikan, sehingga Anda praktis mendapatkan array yang sama setiap waktu. (Lihat perilaku array copy-on-write dalam 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
sumber
Kami sudah dapat mendefinisikan array sebagai konstanta selama bertahun-tahun sekarang, saya tidak berpikir ada banyak nilai untuk mengakali solusi lagi.
miken32
1
@ miken32 sementara true, solusi yang disediakan menarik, tidak disediakan oleh orang lain, dan dapat diterapkan secara konseptual ke bahasa lain sesuai kebutuhan (tambahkan ke kotak alat Anda)
puiu
1

jika Anda menggunakan PHP 7 & 7+, Anda dapat menggunakan fetch seperti ini juga

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

Konstanta hanya dapat berisi nilai skalar, saya sarankan Anda menyimpan serialisasi (atau representasi dikodekan JSON) dari array.

Alix Axel
sumber
1
Ini tidak menambahkan apa pun ke jawaban yang diterima, jadi mungkin itu harus dihapus?
Ian Dunn
4
@IanDunn: Saya berpendapat bahwa jawaban yang diterima tidak menjelaskan mengapa, atau bahwa itu tidak menambahkan apa pun pada jawaban saya tapi ... Jangan ragu untuk memilih untuk menghapus.
Alix Axel
1
Saya tidak benar-benar melihat titik representasi string dari array yang diinginkan.
Tomáš Zato - Reinstate Monica