Diziler İçeren PHP Sabitler?


408

Bu başarısız oldu:

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

Görünüşe göre, sabitler dizileri tutamaz. Bu sorunu aşmanın en iyi yolu nedir?

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

//...

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

Bu gereksiz bir çaba gibi görünüyor.


17
PHP 5.6 sabit dizileri destekler, aşağıdaki cevabıma bakın.
Andrea

1
Bir diziyi ne zaman sabit olarak kullanmanız gerekir, numaralandırma yapmaya çalışıyorsunuz? Öyleyse, SplEnum kullanın: php.net/manual/en/class.splenum.php
ziGi

2
@ziGi Bugün bu konuya geldi, saklamak için belirli boyutlar gerektiren farklı görüntü türlerine sahip, bu boyutları genişlik ve yükseklik için bir tane yerine sabit diziler olarak saklamak yararlı oldu.
Matt K

Yanıtlar:


499

NOT: Bu kabul edilen cevap olsa da, PHP 5.6 ve üstü sürümlerde const dizileri olabileceğinizi belirtmek gerekir - aşağıdaki Andrea Faulds'un cevabına bakın .

Ayrıca dizinizi serileştirebilir ve ardından sabite koyabilirsiniz:

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

# use it
$my_fruits = unserialize (FRUITS);

40
Sadece bu çözümü sevdiğimi söylemek istiyorum :)
GateKiller

16
Güzel. Ancak kötü olan nokta, bu şekilde bir sınıf sabiti tanımlayamamanızdır.
Gregoire

19
sınıftaki statik değişkenlere daha iyi yapışır.
Jürgen Paul

5
$fruit = FRUITS[0];
Yapamayacağınız

20
Bu kod zarif ama oldukça yavaş. Diziyi döndüren bir genel statik sınıf yöntemi kullanmak daha iyidir.
İsim

844

PHP 5.6'dan beri, aşağıdakilerle bir dizi sabiti bildirebilirsiniz const:

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

Kısa sözdizimi de beklediğiniz gibi çalışır:

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

PHP 7'niz define()varsa, ilk denediğiniz gibi nihayet kullanabilirsiniz :

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

41
Diğer tüm yanıtlar güncel olmadığından veya yalnızca yanlış bilgilendirilmiş kullanıcılar tarafından yazıldığından, bu durumun kaldırılması gerekir.
Andreas Bergström

Tek sözdizimi bu mu? Eski tanımlama işlevini kullanabiliyor musunuz? define ('ARRAY_CONSTANT', dizi ('item1', 'item2', 'item3'));
Jack

5
@JackNicholsonn Ne yazık ki define()burada PHP 5.6'da kullanamazsınız , ancak bu PHP 7.0 için düzeltildi . :)
Andrea

@ AndreasBergström Hayır, bu soru çok yeni. Bu soru 2009 yılında yapıldı! Bu sözdizimi, günümüzde çoğu kullanıcı için neredeyse işe yaramayacaktır. Hemen hemen herkes sunucularında PHP 5.6'ya sahiptir. Alternatifler sundukları için diğer cevaplar gayet iyi. Eğer sınıfları kullanmak istemiyorsanız, kabul edilen cevap şimdiye kadar geçerli tek yoldur.
Ismael Miguel

@IsmaelMiguel hepsinde 5.6 olduğundan emin olma. Windows sunucusundaki herkes şimdi bir ay önce microsoft'tan 5.6 sql sunucu sürücülerini aldı.
MH

141

Bunları bir sınıfın statik değişkenleri olarak saklayabilirsiniz:

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

Dizinin başkaları tarafından değiştirilebileceği fikrinden hoşlanmıyorsanız, bir alıcı yardımcı olabilir:

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

DÜZENLE

PHP5.4'ten beri, ara değişkenlere ihtiyaç duymadan dizi değerlerine erişmek bile mümkündür, yani aşağıdakiler çalışır:

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

1
+1. Bunun için yıllarca gidiyorum:const AtomicValue =42; public static $fooArray = ('how','di')
Frank Nocke

9
Php'de değişmez diziler yaratamayacağımız bana saçma gelse de, bu iyi bir çözüm sağlar.
Akoi Meexx

Eğer sabiti çok kullanıyorsanız, kesinlikle bir işlev çağrısından kaçınırım, oldukça pahalıdırlar. Statik gitmek için bir yoldur.
Chris Seufert

1
Bu çözüm beklediğimden çok daha harikaydı: Dizi değerlerinin sadece bir kısmına ihtiyacım vardı, bu nedenle sadece dizi almak yerine, işlevde bazı parametreler kullandım. Benim durumumda Constants :: getRelatedIDs ($ myID) bana sadece gerekli değerleri ile bir iç dizi alır (Ayrıca bu işlev içinde bazı kimlik doğrulama yapmak). @cseufert tüm dizi almak ve her vaka için filtreleme benim için çok daha pahalı olurdu ...
Armfoot

1
özel statik üyesi olan bir işlevi (getArray) olması, değişimler olabileceğinden sabitler için en iyi temsildir 👍🏻
Kamaldeep singh Bhatia

41

PHP 5.6 veya üstünü kullanıyorsanız Andrea Faulds yanıtını kullanın

Ben böyle kullanıyorum. Umarım başkalarına yardımcı olur.

config.php

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

Dosyada sabitlere ihtiyacım var.

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

Senin gibi yaptım. Bu, bunun iyi veya daha iyi bir şey olup olmadığını performans optimizasyonu arıyordu.
NullPointer

Bu çözüme katılıyorum. Basit ve anlaşılması kolay olduğu için ...
Faris Rayhan

12

Ben bunu kullanıyorum. Soulmerge tarafından sağlanan örneğe benzer, ancak bu şekilde dizinin tamamını veya yalnızca tek bir değeri elde edebilirsiniz.

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

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

Şöyle kullanın:

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

10

Bir sabiti JSON dizesi olarak saklayabilirsiniz. Ve uygulama bakış açısından, JSON diğer durumlarda yararlı olabilir.

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

Tam da böyle düşünüyordum. Bu meşru olarak iyi bir cevap değil mi?
Con Antonakos

JSON tüketir çünkü bu AngularJS ile gerçekten iyi çalışır. Bunun seri hale getirme cevabından çok daha iyi olduğunu hissediyorum, ancak seri hale getirmenin daha iyi olmasının bir nedeni var mı? Belki daha hızlı mı?
Drellgor

Evet, seri hale getirme teknik olarak daha hızlıdır. Ancak, en çok ihtiyaç duyulan küçük setler için bu yöntemi daha güvenli olduğu için tercih ederim. Serileştirmeyi kaldırdığınızda kod yürütülebilir. Bu durumda bu çok düşük bir risk olsa bile, sadece aşırı durumlarda kullanımı ayırmalı veya serileştirmemeliyiz.
Mario Awad

9

PHP 5.6 ile başlayarak, constaşağıdaki gibi anahtar kelimeleri kullanarak sabit diziler tanımlayabilirsiniz

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

ve farklı öğelere aşağıdaki gibi erişilebilir:

echo DEFAULT_ROLES[1]; 
....

PHP 7 ile başlayarak, sabit diziler aşağıdaki gibi tanımlanabilir define:

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

ve farklı elemanlara eskisi gibi erişilebilir.


3

Biraz eski bir soru olduğunu biliyorum, ama işte benim çözümüm:

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

Ben sabitler nesneleri ve dizileri saklamak için gerekli çünkü ben de php için runkit yüklü böylece $ const değişken superglobal yapabilirsiniz böylece tanımladı.

Olarak $const->define("my_constant",array("my","values"));veya sadece kullanabilirsiniz$const->my_constant = array("my","values");

Değeri elde etmek için sadece $const->my_constant;


Vay be, ben böyle bir yol beklenen olmadı ... Ben bile bilmiyordum __getve __setbu yöntem büyük olduğunu söylemek gerekir ....
RedClover

Bunlara sihirli yöntemler denir, onlar hakkında php belgelerine bakın.
Rikudou_Sennin

3

PHP 7+

PHP 7'den itibaren, sabit bir dizi tanımlamak için define () işlevini kullanabilirsiniz:

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

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

3

İlişkilendirilebilir Dizilerle bile çalışabilir .. örneğin bir sınıfta.

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

Patlama ve implode fonksiyonunu kullanarak bir çözüm geliştirebiliriz:

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

Bu yankılanacak email .

Daha fazla optimize etmesini istiyorsanız, tekrarlayan şeyleri sizin için yapmak için 2 işlev tanımlayabilirsiniz:

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

Umarım yardımcı olur . Mutlu kodlama.


yaparak iki kez patlamayı önleyebilirsiniz: $ explodeResult = explode (',', $ const); if (isset ($ explodeResult) [$ index]) {return $ explodeResult [$ index];}
Saeed

@ Evet, güzel bir nokta. Cevabımı buna göre güncelleyeceğim
MD. Sahib Bin Mahboob

2

Bir çeşit ser / deser veya encode / decode hile yapmak çirkin görünüyor ve sabiti kullanmaya çalışırken tam olarak ne yaptığınızı hatırlamanızı gerektiriyor. Erişimci ile sınıf özel statik değişken iyi bir çözüm olduğunu düşünüyorum, ama ben daha iyi yapacağım. Sabit dizinin tanımını döndüren genel bir statik getter yöntemine sahip olmanız yeterlidir. Bu, minimum ek kod gerektirir ve dizi tanımı yanlışlıkla değiştirilemez.

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

initMyRoles( UserRoles::getDefaultRoles() );

Gerçekten tanımlanmış bir sabit gibi görünmesini istiyorsanız, ona büyük harf adı verebilirsiniz, ancak addan sonra '()' parantezlerini eklemeyi hatırlamak kafa karıştırıcı olacaktır.

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

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

İstediğiniz define () işlevselliğine daha yakın olmak için global yöntemi yapabileceğinizi düşünüyorum, ancak gerçekten sabit adı yine de kapsamalı ve globallerden kaçınmalısınız.


2

Bu şekilde tanımlayabilirsiniz

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

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

2

Evet, bir diziyi sabit olarak tanımlayabilirsiniz. Kaynaktan itibaren PHP 5.6 , bir skaler ifadesi olarak sabit tanımlamak mümkündür, ve da bir dizi sabit tanımlamak mümkündür . Sabitleri bir kaynak olarak tanımlamak mümkündür, ancak beklenmedik sonuçlara neden olabileceğinden kaçınılmalıdır.

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

Bu bağlantının referansı ile

Mutlu bir kodlama yapın.


1

Bunu 2009'dan bakıyorsanız ve AbstractSingletonFactoryGenerators'ı sevmiyorsanız, işte birkaç seçenek daha.

Unutmayın, diziler atandığında "kopyalanır" veya bu durumda döndürülür, böylece her seferinde hemen hemen aynı diziyi alırsınız. (PHP'de dizilerin yazma üzerine kopyalama davranışına bakın.)

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

Dizileri uzun yıllardır sabit olarak tanımlayabildik, artık geçici çözümlere ulaşmak için çok fazla değer olduğunu düşünmüyorum.
miken32

1
@ miken32 doğru olsa da, sağlanan çözüm ilginçtir, başkaları tarafından sağlanmamıştır ve gerektiğinde diğer dillere kavramsal olarak uygulanabilir (alet kutunuza ekleyin)
puiu

1

PHP 7 ve 7+ kullanıyorsanız, bu gibi getirmeyi de kullanabilirsiniz

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

0

Sabitler sadece skaler değerler içerebilir, dizinin serileştirilmesini (veya JSON kodlu gösterimini) saklamanızı öneririm.


1
Bu, kabul edilen cevaba hiçbir şey eklemez, bu yüzden silinmelidir?
Ian Dunn

4
@IanDunn: Kabul edilen cevabın nedenini açıklamadığını veya cevabıma hiçbir şey eklemediğini iddia ediyorum ama ... Silmek için oy kullanmaktan çekinmeyin.
Alix Axel

1
Gerçekten istenen dizinin herhangi bir dize temsil noktası görmüyorum.
Tomáš Zato - Monica'yı
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.