PHP คงมีอาร์เรย์?


407

สิ่งนี้ล้มเหลว:

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

เห็นได้ชัดว่าค่าคงที่ไม่สามารถเก็บอาร์เรย์ได้ วิธีที่ดีที่สุดที่จะหลีกเลี่ยงสิ่งนี้คืออะไร?

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

//...

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

ดูเหมือนว่าจะมีความพยายามที่ไม่จำเป็น


17
PHP 5.6 รองรับอาเรย์คงที่, ดูคำตอบของฉันด้านล่าง
Andrea

1
เมื่อใดที่คุณจะต้องใช้อาร์เรย์เป็นค่าคงที่คุณพยายามทำการแจงนับหรือไม่ หากเป็นเช่นนั้นให้ใช้ SplEnum: php.net/manual/en/class.splenum.php
ziGi

2
@ziGi มาถึงปัญหานี้แล้ววันนี้มีรูปภาพหลายรูปแบบที่จะจัดเก็บที่ต้องการขนาดเฉพาะมันกลายเป็นประโยชน์ในการจัดเก็บมิติเหล่านี้เป็นอาร์เรย์คงที่แทนที่จะเป็นหนึ่งสำหรับความกว้างและอีกหนึ่งสำหรับความสูง
Matt K

คำตอบ:


498

หมายเหตุ: ขณะนี้เป็นคำตอบที่ได้รับการยอมรับก็เป็นที่น่าสังเกตว่าใน PHP 5.6+ คุณสามารถมีอาร์เรย์ const - ดูคำตอบ Andrea Faulds' ด้านล่าง

คุณยังสามารถจัดลำดับอาร์เรย์ของคุณและทำให้เป็นค่าคงที่:

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

# use it
$my_fruits = unserialize (FRUITS);

40
แค่อยากจะบอกว่าฉันรักการแก้ปัญหานี้ :)
GateKiller

16
ดี แต่จุดที่ไม่ดีคือคุณไม่สามารถกำหนดค่าคงที่ของคลาสได้ด้วยวิธีนี้
Gregoire

19
ดีกว่าติดกับตัวแปรคงที่ในชั้นเรียน
Jürgen Paul

5
น่าเสียดายที่คุณทำไม่ได้:$fruit = FRUITS[0];
Sophivorus

20
รหัสนี้ดูหรูหรา แต่ค่อนข้างช้า จะดีกว่าการใช้วิธีคลาสคงที่สาธารณะที่ส่งกลับอาร์เรย์
คำนาม

844

ตั้งแต่ PHP 5.6 คุณสามารถประกาศค่าคงที่ของอาร์เรย์ด้วยconst:

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

ไวยากรณ์สั้น ๆ ก็ใช้ได้เช่นกันตามที่คุณคาดหวัง:

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

หากคุณมี PHP 7 คุณสามารถใช้งานได้ในที่สุดdefine()เช่นเดียวกับที่คุณลองครั้งแรก:

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

41
สิ่งนี้จำเป็นต้องได้รับการอัปเดตเนื่องจากคำตอบอื่น ๆ ทั้งหมดล้าสมัยหรือเขียนโดยผู้ใช้ที่เข้าใจผิด
Andreas Bergström

นั่นเป็นไวยากรณ์เท่านั้นหรือไม่ คุณสามารถใช้ฟังก์ชั่นกำหนดแบบเก่าหรือไม่? define ('ARRAY_CONSTANT', array ('item1', 'item2', 'item3'));
แจ็ค

5
@JackNicholsonn แต่น่าเสียดายที่คุณไม่สามารถใช้define()ที่นี่ใน PHP 5.6 แต่นี้ได้รับการแก้ไขสำหรับ PHP 7.0 :)
Andrea

@ AndreasBergströmไม่คำถามนี้ใหม่เกินไป คำถามนี้ทำในปี 2009! ไวยากรณ์นี้แทบจะไร้ประโยชน์สำหรับผู้ใช้ส่วนใหญ่ในแต่ละวัน เกือบทุกคนมี PHP 5.6 บนเซิร์ฟเวอร์ของพวกเขา คำตอบอื่น ๆ นั้นสมบูรณ์แบบเพราะพวกเขายังมีทางเลือก คำตอบที่ได้รับการยอมรับเป็นวิธีเดียวที่ปฏิบัติได้จนถึงตอนนี้หากคุณไม่ต้องการใช้คลาส
Ismael Miguel

@IsmaelMiguel ไม่ต้องแน่ใจว่าพวกเขาทั้งหมดมี 5.6 ทุกคนบนเซิร์ฟเวอร์ windows เพิ่งได้ไดรเวอร์เซิร์ฟเวอร์ 5.6 sql จาก microsoft เมื่อประมาณหนึ่งเดือนที่แล้ว
MH

141

คุณสามารถเก็บไว้เป็นตัวแปรคงที่ของคลาส:

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

หากคุณไม่ชอบแนวคิดที่ว่าผู้อื่นสามารถเปลี่ยนแปลงได้อาร์เรย์ผู้ทะเยอทะยานอาจช่วยได้:

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

แก้ไข

ตั้งแต่ PHP5.4 มันเป็นไปได้ที่จะเข้าถึงค่าของอาเรย์โดยไม่จำเป็นต้องใช้ตัวแปรกลางเช่นงานต่อไปนี้:

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

1
+1 ฉันจะทำสิ่งนี้เป็นเวลาหลายปี:const AtomicValue =42; public static $fooArray = ('how','di')
Frank Nocke

9
ในขณะที่ดูเหมือนไร้สาระสำหรับฉันที่เราไม่สามารถสร้างอาร์เรย์ที่ไม่เปลี่ยนรูปแบบใน PHP แต่ก็มีวิธีแก้ปัญหาที่ดี
Akoi Meexx

หากคุณใช้ค่าคงที่จำนวนมากฉันจะหลีกเลี่ยงการเรียกใช้ฟังก์ชันอย่างแน่นอนพวกเขาค่อนข้างแพง คงที่เป็นวิธีที่จะไป
Chris Seufert

1
โซลูชันนี้ยอดเยี่ยมเกินกว่าที่ฉันคาดไว้: ฉันต้องการเพียงบางส่วนของค่าอาร์เรย์ดังนั้นแทนที่จะได้รับอาร์เรย์ฉันใช้พารามิเตอร์บางอย่างในฟังก์ชัน ในกรณีของฉันค่าคงที่ :: getRelatedIDs ($ myID) ทำให้ฉันมีอาร์เรย์ภายในที่มีเพียงค่าที่ฉันต้องการ (ฉันยังทำการตรวจสอบ ID บางอย่างภายในฟังก์ชั่นนี้) @cseufert รับอาร์เรย์ทั้งหมดและกรองสำหรับแต่ละกรณีจะมีราคาแพงมากสำหรับฉัน ...
Armfoot

1
มีฟังก์ชั่น (getArray) กับสมาชิกคงที่ส่วนตัวเป็นตัวแทนที่ดีที่สุดสำหรับค่าคงที่ขณะที่พวกเขาสามารถเปลี่ยนแปลงได้👍🏻
Kamaldeep singh Bhatia

41

หากคุณใช้ PHP 5.6 ขึ้นไปให้ใช้คำตอบ Andrea Faulds

ฉันใช้มันแบบนี้ ฉันหวังว่ามันจะช่วยให้ผู้อื่น

config.php

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

ในไฟล์ที่ฉันต้องการค่าคงที่

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

ฉันทำเช่นเดียวกันกับที่คุณทำ ดังนั้นกำลังมองหาการเพิ่มประสิทธิภาพประสิทธิภาพไม่ว่าจะดีหรืออย่างอื่นก็ดีกว่า
NullPointer

ใช่ฉันเห็นด้วยกับวิธีนี้ ในฐานะที่มันเป็นเรื่องง่ายและง่ายที่จะเข้าใจ ...
Faris Rayhan

12

นี่คือสิ่งที่ฉันใช้ มันคล้ายกับตัวอย่างที่จัดทำโดย Soulmerge แต่ด้วยวิธีนี้คุณสามารถรับอาร์เรย์ทั้งหมดหรือเพียงค่าเดียวในอาร์เรย์

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

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

ใช้แบบนี้:

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

10

คุณสามารถจัดเก็บเป็นสตริง JSON ในค่าคงที่ และมุมมองของแอปพลิเคชัน JSON จะมีประโยชน์ในกรณีอื่น ๆ

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

นี่คือสิ่งที่ฉันคิด นี่ไม่ใช่คำตอบที่ดีหรือไม่?
Con Antonakos

สิ่งนี้ใช้ได้ดีกับ AngularJS เพราะใช้ JSON ฉันรู้สึกว่านี่เป็นคำตอบที่ดีกว่ามาก แต่มีบางเหตุผลที่ทำให้เป็นอันดับดีกว่า มันเร็วกว่านี้ไหม?
Drellgor

ใช่เป็นอันดับเป็นเทคนิคได้เร็วขึ้น อย่างไรก็ตามสำหรับชุดเล็ก ๆ ซึ่งเป็นสิ่งที่ต้องการเป็นส่วนใหญ่ฉันชอบวิธีนี้มากกว่าเพราะปลอดภัยกว่า เมื่อคุณยกเลิกการตั้งค่ารหัสอาจถูกดำเนินการ แม้ว่าในกรณีนี้มันมีความเสี่ยงต่ำมากฉันคิดว่าเราควรสำรองการใช้งานหรือยกเลิกการตั้งค่าสำหรับกรณีที่รุนแรงเท่านั้น
Mario Awad

9

เริ่มต้นด้วย PHP 5.6 คุณสามารถกำหนดอาร์เรย์คงที่โดยใช้constคำหลักดังต่อไปนี้

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

และองค์ประกอบต่าง ๆ สามารถเข้าถึงได้ดังนี้:

echo DEFAULT_ROLES[1]; 
....

เริ่มต้นด้วย PHP 7 อาร์เรย์คงที่สามารถกำหนดได้โดยใช้defineด้านล่าง:

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

และองค์ประกอบต่าง ๆ สามารถเข้าถึงได้เช่นเดียวกับเมื่อก่อน


3

ฉันรู้ว่ามันเป็นคำถามเก่า แต่นี่คือวิธีการแก้ปัญหาของฉัน:

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

ฉันกำหนดไว้เพราะฉันต้องการเก็บวัตถุและอาร์เรย์ในค่าคงที่ดังนั้นฉันจึงติดตั้ง runkit เป็น php ดังนั้นฉันจึงสามารถสร้างตัวแปร $ $ superglobal

คุณสามารถใช้มันเป็น$const->define("my_constant",array("my","values"));หรือเพียงแค่$const->my_constant = array("my","values");

เพื่อรับค่าเพียงแค่โทร $const->my_constant;


ว้าวฉันไม่ได้คาดหวังแบบนั้น ... ฉันไม่รู้ด้วยซ้ำ__getและ__set... ฉันต้องบอกว่าวิธีนี้ดีมาก
RedClover

สิ่งเหล่านี้เรียกว่าวิธีเวทย์มนตร์ตรวจสอบเอกสารเกี่ยวกับ php
Rikudou_Sennin

3

PHP 7+

ในฐานะของ PHP 7 คุณสามารถใช้ฟังก์ชันdefine ()เพื่อกำหนดอาเรย์คงที่:

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

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

3

สามารถทำงานกับ Associative Arrays ได้เช่นในชั้นเรียน

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

การใช้ฟังก์ชั่น explode และ implode ทำให้เราสามารถแก้ไขปัญหาได้อย่างเหมาะสม:

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

สิ่งนี้จะสะท้อนemailออกมา

หากคุณต้องการเพิ่มประสิทธิภาพให้มากขึ้นคุณสามารถกำหนด 2 ฟังก์ชันเพื่อทำสิ่งที่ซ้ำ ๆ สำหรับคุณดังนี้:

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

หวังว่าจะช่วย การเข้ารหัสที่มีความสุข


คุณสามารถป้องกันการระเบิดสองครั้งโดยทำ: $ explodeResult = explode (',', $ const); if (isset ($ explodeResult) [$ index]) {return $ explodeResult [$ index];}
Saeed

@Seed yup นั่นเป็นจุดที่ดี ฉันจะอัปเดตคำตอบของฉันตาม
MD Sahib Bin Mahboob

2

การเรียงลำดับของ ser / deser หรือเคล็ดลับการเข้ารหัส / ถอดรหัสดูเหมือนน่าเกลียดและคุณต้องจำสิ่งที่คุณทำเมื่อคุณพยายามใช้ค่าคงที่ ฉันคิดว่าตัวแปรคลาสส่วนตัวคงที่กับ accessor เป็นทางออกที่ดี แต่ฉันจะทำให้คุณดีขึ้น เพียงแค่มีเมธอด getter แบบสแตติกสาธารณะที่ส่งคืนนิยามของอาร์เรย์คงที่ ต้องใช้รหัสพิเศษขั้นต่ำและไม่สามารถแก้ไขข้อกำหนดอาร์เรย์ได้โดยไม่ตั้งใจ

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

initMyRoles( UserRoles::getDefaultRoles() );

หากคุณต้องการทำให้มันดูเหมือนค่าคงที่ที่กำหนดไว้จริงๆคุณสามารถตั้งชื่อตัวพิมพ์ใหญ่ทั้งหมดได้ แต่ก็อาจทำให้สับสนในการจำการเพิ่มเครื่องหมาย '()' ไว้หลังชื่อ

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

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

ฉันคิดว่าคุณสามารถทำให้วิธีการทั่วโลกใกล้เคียงกับฟังก์ชั่น define () ที่คุณขอ แต่คุณควรกำหนดขอบเขตชื่อคงที่ให้ดีและหลีกเลี่ยงการกลม


2

คุณสามารถกำหนดเช่นนี้

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

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

2

ใช่คุณสามารถกำหนดอาร์เรย์เป็นค่าคงที่ได้ จากPHP 5.6 เป็นต้นไปสามารถกำหนดค่าคงที่เป็นนิพจน์สเกลาร์และสามารถกำหนดค่าคงที่อาร์เรย์ได้ เป็นไปได้ที่จะกำหนดค่าคงที่เป็นทรัพยากร แต่ควรหลีกเลี่ยงเนื่องจากอาจทำให้เกิดผลลัพธ์ที่ไม่คาดคิด

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

ด้วยการอ้างอิงของลิงค์นี้

ขอให้มีความสุข


1

หากคุณกำลังมองหาสิ่งนี้ตั้งแต่ปี 2009 และคุณไม่ชอบ AbstractSingletonFactoryGenerators นี่คือตัวเลือกอื่น ๆ

โปรดจำไว้ว่าอาร์เรย์จะ "คัดลอก" เมื่อได้รับมอบหมายหรือในกรณีนี้กลับมาดังนั้นคุณจะได้รับอาร์เรย์เดียวกันทุกครั้ง (ดูพฤติกรรมการคัดลอกเมื่อเขียนของอาร์เรย์ใน 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;
}

เราสามารถกำหนดให้อาร์เรย์เป็นค่าคงที่มาหลายปีแล้วตอนนี้ฉันไม่คิดว่าจะมีคุณค่าอีกมากในการแก้ไขปัญหาอีกต่อไป
miken32

1
@ miken32 ในขณะที่เป็นจริง, วิธีการแก้ปัญหาให้เป็นที่น่าสนใจไม่ได้ถูกจัดทำโดยคนอื่นและสามารถนำไปใช้กับแนวคิดภาษาอื่น ๆ ตามที่ต้องการ (เพิ่มไปยังกล่องเครื่องมือของคุณ)
puiu

1

หากคุณใช้ PHP 7 และ 7+ คุณสามารถใช้การดึงข้อมูลแบบนี้ได้เช่นกัน

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

0

ค่าคงที่สามารถมีค่าสเกลาร์ได้เท่านั้นฉันขอแนะนำให้คุณจัดเก็บซีเรียลไลซ์เซชั่น (หรือการนำเสนอที่เข้ารหัสด้วย JSON) ของอาร์เรย์


1
สิ่งนี้จะไม่เพิ่มอะไรลงไปในคำตอบที่ยอมรับดังนั้นอาจจะถูกลบหรือไม่
Ian Dunn

4
@IanDunn: ฉันจะยืนยันว่าคำตอบที่ยอมรับไม่ได้อธิบายว่าทำไมหรือว่าจะไม่เพิ่มอะไรลงไปในคำตอบของฉัน แต่ ... รู้สึกอิสระที่จะลงคะแนนเพื่อลบ
Alix Axel

1
ฉันไม่เห็นจุดใด ๆ ของการแทนค่าสตริงของอาร์เรย์ที่ต้องการ
Tomáš Zato - Reinstate Monica
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.