Các hằng số PHP chứa các mảng?


408

Điều này thất bại:

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

Rõ ràng, hằng số không thể giữ mảng. Cách tốt nhất để có được xung quanh này là gì?

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

//...

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

Đây dường như là nỗ lực không cần thiết.


17
PHP 5.6 hỗ trợ các mảng không đổi, xem câu trả lời của tôi dưới đây.
Andrea

1
Khi nào bạn cần sử dụng một mảng như một hằng số, bạn có đang cố gắng thực hiện một phép liệt kê không? Nếu vậy, sau đó sử dụng SplEnum: php.net/manual/en/class.splenum.php
ziGi

2
@ziGi Đã phát hiện ra vấn đề này ngày hôm nay, có các loại hình ảnh khác nhau để lưu trữ yêu cầu kích thước cụ thể, việc lưu trữ các kích thước này dưới dạng mảng không đổi thay vì chiều rộng và chiều cao trở nên hữu ích.
Matt K

Câu trả lời:


499

LƯU Ý: mặc dù đây là câu trả lời được chấp nhận, nhưng đáng chú ý là trong PHP 5.6+ bạn có thể có các mảng const - xem câu trả lời của Andrea Faulds bên dưới .

Bạn cũng có thể tuần tự hóa mảng của mình và sau đó đặt nó vào hằng số:

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

# use it
$my_fruits = unserialize (FRUITS);

40
Chỉ muốn nói rằng tôi thích giải pháp này :)
GateKiller

16
Đẹp. Nhưng điểm tồi tệ là bạn không thể định nghĩa một lớp hằng theo cách này.
Gregoire

19
tốt hơn dính vào các biến tĩnh trong một lớp.
Jürgen Paul

5
Quá tệ, bạn không thể làm:$fruit = FRUITS[0];
Sophivorus 22/03/13

20
Mã này thanh lịch nhưng khá chậm. Nó tốt hơn nhiều khi sử dụng một phương thức lớp tĩnh công khai trả về mảng.
danh từ

844

Kể từ PHP 5.6, bạn có thể khai báo một hằng số mảng với const:

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

Cú pháp ngắn cũng hoạt động, như bạn mong đợi:

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

Nếu bạn có PHP 7, cuối cùng bạn cũng có thể sử dụng define(), giống như lần đầu tiên bạn thử:

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

41
Điều này cần phải được nâng cao vì tất cả các câu trả lời khác đã lỗi thời hoặc chỉ được viết bởi người dùng thông tin sai.
Andreas Bergström

Đó có phải là cú pháp duy nhất? Bạn có thể sử dụng chức năng xác định cũ? xác định ('ARRAY_CONSTANT', mảng ('item1', 'item2', 'item3'));
Jack

5
@JackNicholsonn Thật không may, bạn không thể sử dụng define()ở đây trong PHP 5.6, nhưng điều này đã được sửa cho PHP 7.0 . :)
Andrea

@ AndreasBergström Không, câu hỏi này quá mới. Câu hỏi này được thực hiện vào năm 2009! Cú pháp này sẽ gần như vô dụng đối với hầu hết người dùng bây giờ. Hầu như bất cứ ai cũng có PHP 5.6 trên máy chủ của họ. Các câu trả lời khác là hoàn toàn tốt vì họ cũng cung cấp các lựa chọn thay thế. Câu trả lời được chấp nhận là cách khả thi duy nhất cho đến nay, nếu bạn không muốn sử dụng các lớp học.
Ismael Miguel

@IsmaelMiguel không chắc chắn tất cả họ đều có 5.6. Bất cứ ai trên máy chủ windows bây giờ đều có trình điều khiển máy chủ 5,6 sql từ microsoft khoảng một tháng trước.
MH

141

Bạn có thể lưu trữ chúng dưới dạng các biến tĩnh của một lớp:

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

Nếu bạn không thích ý tưởng rằng mảng có thể bị thay đổi bởi người khác, một getter có thể giúp:

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

BIÊN TẬP

Kể từ PHP5.4, thậm chí có thể truy cập các giá trị mảng mà không cần các biến trung gian, tức là các công việc sau:

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

1
+1. Tôi sẽ làm điều này trong nhiều năm:const AtomicValue =42; public static $fooArray = ('how','di')
Frank Nocke

9
Mặc dù có vẻ nực cười với tôi rằng chúng ta không thể tạo ra các mảng bất biến trong php, nhưng điều này cung cấp một cách giải quyết hợp lý.
Akoi Meexx

Nếu bạn đang sử dụng hằng số rất nhiều, tôi chắc chắn sẽ tránh một cuộc gọi chức năng, chúng khá đắt. Tĩnh là con đường để đi.
Chris Seufert

1
Giải pháp này tuyệt vời hơn tôi mong đợi: Tôi chỉ cần một phần của các giá trị của mảng, do đó thay vì chỉ đơn giản là lấy mảng, tôi đã sử dụng một số tham số trong hàm. Trong trường hợp của tôi, Hằng số :: getRelatedIDs ($ myID) mang lại cho tôi một mảng bên trong chỉ với các giá trị tôi cần (tôi cũng thực hiện một số xác thực ID bên trong hàm này). @cseufert nhận toàn bộ mảng và lọc cho từng trường hợp sẽ tốn kém hơn nhiều đối với tôi ...
Armfoot

1
có một chức năng (getArray) với thành viên tĩnh riêng là đại diện tốt nhất cho các hằng số vì chúng có thể thay đổi
Kamaldeep singh Bhatia

41

Nếu bạn đang sử dụng PHP 5.6 trở lên, hãy sử dụng câu trả lời của Andrea Faulds

Tôi đang sử dụng nó như thế này. Tôi hy vọng, nó sẽ giúp người khác.

cấu hình

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

Trong tập tin, nơi tôi cần hằng số.

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

Tôi đã làm giống như bạn đã làm. Vì vậy, đã tìm kiếm tối ưu hóa hiệu suất cho dù điều này là tốt hay cái gì khác nếu tốt hơn.
NullPulum

Tôi đồng ý với giải pháp này. Vì nó đơn giản và dễ hiểu ...
Faris Rayhan

12

Đây là những gì tôi sử dụng. Nó tương tự như ví dụ được cung cấp bởi soulmerge, nhưng bằng cách này bạn có thể nhận được toàn bộ mảng hoặc chỉ một giá trị trong mảng.

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

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

Sử dụng nó như thế này:

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

10

Bạn có thể lưu trữ nó dưới dạng một chuỗi JSON trong một hằng số. Và quan điểm ứng dụng, JSON có thể hữu ích trong các trường hợp khác.

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

Đây chính xác là những gì tôi đã nghĩ. Đây không phải là một câu trả lời hợp pháp tốt?
Con Antonakos

Điều này hoạt động thực sự tốt với AngularJS vì nó tiêu thụ JSON. Tôi cảm thấy như thế này là tốt hơn nhiều câu trả lời nối tiếp, nhưng có một số lý do tại sao nối tiếp là tốt hơn? Có lẽ nhanh hơn?
Drellgor

Có serialization là kỹ thuật nhanh hơn. Tuy nhiên, đối với các bộ nhỏ, chủ yếu là những gì cần thiết, tôi thích phương pháp này vì nó an toàn hơn. Khi bạn hủy xác nhận, mã có thể được thực thi. Ngay cả trong trường hợp này đây là rủi ro rất thấp, tôi nghĩ chúng ta chỉ nên bảo lưu việc sử dụng hoặc không xác định cho các trường hợp cực đoan.
Mario Awad

9

Bắt đầu với PHP 5.6, bạn có thể xác định các mảng không đổi bằng cách sử dụng consttừ khóa như bên dưới

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

và các yếu tố khác nhau có thể được truy cập như dưới đây:

echo DEFAULT_ROLES[1]; 
....

Bắt đầu với PHP 7, các mảng không đổi có thể được định nghĩa bằng cách sử dụng definenhư sau:

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

và các yếu tố khác nhau có thể được truy cập theo cùng một cách như trước đây.


3

Tôi biết đó là một câu hỏi hơi cũ, nhưng đây là giải pháp của tôi:

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

Tôi đã định nghĩa nó bởi vì tôi cần lưu trữ các đối tượng và mảng trong các hằng số nên tôi đã cài đặt runkit vào php để tôi có thể tạo siêu biến $ const.

Bạn có thể sử dụng nó như $const->define("my_constant",array("my","values"));hoặc chỉ$const->my_constant = array("my","values");

Để có được giá trị chỉ cần gọi $const->my_constant;


Ồ, tôi không mong đợi như vậy ... Tôi thậm chí còn không biết __get__set... Tôi phải nói rằng phương pháp này rất hay.
RedClover

Chúng được gọi là phương thức ma thuật, kiểm tra tài liệu php về chúng.
Rikudou_Sennin

3

7+ PHP

Kể từ PHP 7, bạn chỉ có thể sử dụng hàm định nghĩa () để xác định một mảng không đổi:

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

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

3

Thậm chí có thể làm việc với Mảng liên kết .. ví dụ trong một lớp.

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

Sử dụng chức năng nổ và nổ, chúng ta có thể ứng biến một giải pháp:

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

Điều này sẽ lặp lại email.

Nếu bạn muốn nó tối ưu hóa nó nhiều hơn, bạn có thể xác định 2 hàm để thực hiện những việc lặp đi lặp lại cho bạn như thế này:

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

Mong rằng sẽ giúp. Chúc mừng mã hóa.


bạn có thể ngăn nổ hai lần bằng cách thực hiện: $ explodeResult = explode (',', $ const); if (isset ($ explodeResult) [$ index]) {return $ explodeResult [$ index];}
Saeed

@Saeed yup đó là một điểm tốt đẹp. Tôi sẽ cập nhật câu trả lời của mình cho phù hợp
MD. Sahib Bin Mahboob

2

Thực hiện một số loại ser / deser hoặc mã hóa / giải mã lừa có vẻ xấu và đòi hỏi bạn phải nhớ chính xác những gì bạn đã làm khi bạn đang cố gắng sử dụng hằng số. Tôi nghĩ rằng biến tĩnh riêng của lớp với accessor là một giải pháp tốt, nhưng tôi sẽ làm tốt hơn cho bạn. Chỉ cần có một phương thức getter tĩnh công khai trả về định nghĩa của mảng không đổi. Điều này đòi hỏi tối thiểu mã bổ sung và định nghĩa mảng không thể được sửa đổi ngẫu nhiên.

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

initMyRoles( UserRoles::getDefaultRoles() );

Nếu bạn muốn thực sự làm cho nó trông giống như một hằng số xác định, bạn có thể đặt cho nó một tên mũ, nhưng sẽ thật khó hiểu khi thêm dấu ngoặc đơn '()' sau tên.

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

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

Tôi cho rằng bạn có thể làm cho phương thức toàn cầu trở nên gần gũi hơn với chức năng xác định () mà bạn đang yêu cầu, nhưng bạn thực sự nên đặt tên liên tục bằng mọi cách và tránh toàn cầu.


2

Bạn có thể định nghĩa như thế này

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

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

2

Có, bạn có thể định nghĩa một mảng là hằng số. Từ PHP 5.6 trở đi , có thể định nghĩa một hằng là biểu thức vô hướng và cũng có thể định nghĩa một hằng số mảng . Có thể định nghĩa các hằng số là một tài nguyên, nhưng nên tránh, vì nó có thể gây ra kết quả không mong muốn.

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

Với sự tham khảo của liên kết này

Có một mã hóa hạnh phúc.


1

Nếu bạn đang tìm kiếm điều này từ năm 2009 và bạn không thích AbstractSingletonFactoryGenerators, đây là một vài lựa chọn khác.

Hãy nhớ rằng, các mảng được "sao chép" khi được gán hoặc trong trường hợp này được trả về, do đó bạn thực tế sẽ nhận được cùng một mảng mỗi lần. (Xem hành vi sao chép trên ghi của mảng trong 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;
}

Chúng ta đã có thể định nghĩa mảng là hằng số trong nhiều năm nay, tôi không nghĩ rằng có nhiều giá trị để làm khó các cách giải quyết nữa.
miken32

1
@ miken32 trong khi sự thật, giải pháp được cung cấp rất thú vị, không được cung cấp bởi bất kỳ ai khác và có thể được áp dụng về mặt khái niệm cho các ngôn ngữ khác khi cần (thêm nó vào hộp công cụ của bạn)
puiu

1

nếu bạn đang sử dụng PHP 7 & 7+, bạn cũng có thể sử dụng tìm nạp như thế này

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

0

Các hằng số chỉ có thể chứa các giá trị vô hướng, tôi khuyên bạn nên lưu trữ tuần tự hóa (hoặc biểu diễn được mã hóa JSON) của mảng.


1
Điều này không thêm bất cứ điều gì vào câu trả lời được chấp nhận, vì vậy có lẽ nó nên bị xóa?
Ian Dunn

4
@IanDunn: Tôi sẽ lập luận rằng câu trả lời được chấp nhận không giải thích lý do hoặc nó không thêm bất cứ điều gì vào câu trả lời của tôi nhưng ... Hãy bình chọn để xóa mặc dù.
Alix Axel

1
Tôi không thực sự thấy điểm của bất kỳ chuỗi đại diện nào của mảng mong muốn.
Tomáš Zato - Phục hồi Monica
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.