getenv () so với $ _ENV trong PHP


88

Sự khác biệt giữa getenv() và là $_ENVgì?

Bất kỳ sự đánh đổi nào giữa việc sử dụng một trong hai?

Tôi nhận thấy đôi khi getenv()cung cấp cho tôi những gì tôi cần, trong khi $_ENVkhông (chẳng hạn như HOME).


1
Đừng để bị mắc kẹt bởi PHP che giấu các chi tiết đẫm máu từ bạn. $_ENV$_SERVERđược điền vào dữ liệu thu được theo nhiều cách khác nhau. getenv()là một cách khác để truy cập dữ liệu mà PHP không cho phép bạn truy cập trực tiếp. Nó hoạt động ngay cả với variables_order = "G", khi $_SERVER$_ENVtrống. Đọc câu trả lời tuyệt vời của Conor McDermottroe .
Palec


Đối với những người đang sử dụng Symfony framework, có một trường hợp hạn chế hơn ở trên. getenv () sẽ luôn trả về giá trị của biến env như khi khởi động máy chủ php, ngay cả khi sau đó nó đã được thay đổi. Trong khi $ _ENV [] có thể được thay đổi trong thời gian chạy bằng cách sửa đổi các tệp .env. Nhưng tất nhiên nó liên quan đến Symfony, và không phải PHP nói chung.
Ross Ivantsiv

Câu trả lời:


59

Theo tài liệu php về getenv , chúng hoàn toàn giống nhau, ngoại trừ việc getenvsẽ tìm kiếm biến theo cách không phân biệt chữ hoa chữ thường. Hầu hết thời gian nó có thể không quan trọng, nhưng một trong những nhận xét trên tài liệu giải thích:

Ví dụ trên Windows $ _SERVER ['Đường dẫn'] giống như bạn thấy, với chữ cái đầu tiên được viết hoa, không phải 'PATH' như bạn mong đợi.

Do đó, tôi có thể sẽ chọn sử dụng getenvtrừ khi bạn chắc chắn về cách viết hoa của tiêu đề của biến mà bạn đang cố gắng truy xuất.


14
Không giải thích tại sao $ _ENV ("FOO") và getenv ("FOO") trả về kết quả khác nhau.
rich remer

Thêm getenv()lợi thế: bạn không cần phải kiểm tra isset/ emptytrước khi truy cập. getenv()sẽ không phát ra thông báo.
Steve Clay

53

Tôi biết rằng nhận xét trong tài liệu nói rằng getenvkhông phân biệt chữ hoa chữ thường, nhưng đó không phải là hành vi mà tôi đang thấy:

> env FOO=bar php -r 'print getenv("FOO") . "\n";'
bar
> env FOO=bar php -r 'print getenv("foo") . "\n";'

> env foo=bar php -r 'print getenv("foo") . "\n";'
bar
> env foo=bar php -r 'print getenv("FOO") . "\n";'

> php --version
PHP 5.4.24 (cli) (built: Jan 24 2014 03:51:25)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

Nhìn vào mã nguồn của getenvhàm, điều này là do có ba cách mà PHP có thể tìm nạp biến môi trường:

  1. Qua sapi_getenv(ví dụ: nếu nó nhận được biến môi trường từ Apache)
  2. Nếu trên Windows, từ GetEnvironmentVariableA.
  3. Nếu trên không phải Windows, từ getenvchức năng được cung cấp bởi libc.

Theo như tôi có thể nói, lần duy nhất khi nó hoạt động theo cách phân biệt chữ hoa chữ thường là trên Windows vì đó là cách API biến môi trường Windows hoạt động. Nếu bạn đang sử dụng Linux, BSD, Mac, v.v. thì getenvvẫn phân biệt chữ hoa chữ thường.

Như đã đề cập bởi mario , $_ENVkhông phải lúc nào cũng được phổ biến do các cấu hình khác nhau, variables_ordervì vậy tốt nhất là bạn nên tránh $_ENVnếu bạn không kiểm soát cấu hình máy chủ.

Vì vậy, đối với mã PHP di động nhất:

  1. Sử dụng getenv.
  2. Sử dụng trường hợp đúng cho tên biến môi trường.

36

Ngoài ra, $_ENVthường trống nếu variables_orderkhông có Edanh sách. Trên nhiều thiết lập, có khả năng chỉ $_SERVERđược điền và $_ENVhoàn toàn dành cho việc sử dụng CLI.

Mặt khác getenv()truy cập trực tiếp vào môi trường.

(Về sự mơ hồ chữ hoa, người ta có thể sử dụng đơn giản hơn array_change_key_case().)


6

Tôi thấy getenv()hữu ích để tránh một lỗi PHP lạ mà đôi khi $_SERVER$_ENVkhông xác định auto_globals_jitđược nếu được bật (tạo các biến _SERVER_ENV khi chúng được sử dụng lần đầu). Kể từ đó tôi bắt đầu sử dụng nó.


3

Lấy từ tài liệu PHP :

Hàm này hữu ích (so với $_SERVER, $_ENV) vì nó tìm kiếm khóa $ varname theo cách không phân biệt chữ hoa chữ thường của mảng đó. Ví dụ trên Windows $_SERVER['Path']giống như bạn thấy Viết hoa, không phải ' PATH' như bạn mong đợi. Vì vậy chỉ cần:<?php getenv('path') ?>


3

Tôi muốn nói thêm rằng getenv () là một lựa chọn tốt hơn bởi vì, là một hàm, nó có thể bị quá tải cho các mục đích thử nghiệm. Trong khi đó, việc ghi đè các biến $ _SERVER hoặc $ _ENV của bạn có thể gây trở ngại cho các khung thử nghiệm và các thư viện khác và cuối cùng đòi hỏi nhiều công việc hơn để thực hiện một cách an toàn.


0

đọc env và tạo

<?php

namespace neoistone;

class ns_env {
    
    
    /**
     * env to array file storage
     *
     * @param $envPath
     */
    public static function envToArray(string $envPath)
    {
        $variables = [];
        $mread = fopen($envPath, "r");
        $content = fread($mread,filesize($envPath));
        fclose($mread);
        $lines = explode("\n", $content);
        if($lines) {
            foreach($lines as $line) {
                // If not an empty line then parse line
                if($line !== "") {
                    // Find position of first equals symbol
                    $equalsLocation = strpos($line, '=');

                    // Pull everything to the left of the first equals
                    $key = substr($line, 0, $equalsLocation);

                    // Pull everything to the right from the equals to end of the line
                    $value = substr($line, ($equalsLocation + 1), strlen($line));

                    $variables[$key] = $value;

                } else {
                    $variables[] = "";
                }
            }
        }
        return $variables;
    }
  
    /**
     * Array to .env file storage
     *
     * @param $array
     * @param $envPath
     */
    public static function arrayToEnv(array $array, string $envPath)
    {
        $env = "";
        $position = 0;
        foreach($array as $key => $value) {
            $position++;
            // If value isn't blank, or key isn't numeric meaning not a blank line, then add entry
            if($value !== "" || !is_numeric($key)) {
                // If passed in option is a boolean (true or false) this will normally
                // save as 1 or 0. But we want to keep the value as words.
                if(is_bool($value)) {
                    if($value === true) {
                        $value = "true";
                    } else {
                        $value = "false";
                    }
                }

                // Always convert $key to uppercase
                $env .= strtoupper($key) . "=" . $value;

                // If isn't last item in array add new line to end
                if($position != count($array)) {
                   $env .= "\n";
                }
            } else {
                $env .= "\n";
            }
        }
        $mwrite = fopen($envPath, "w");
        fwrite($mwrite, $env);
        fclose($mwrite);
    }
    /**
     * Json to .env file storage
     *
     * @param $json
     * @param $envPath
     */
    public static function JsonToEnv(array $json, string $envPath)
    {
        $env = "";
        $position = 0;
        $array = json_decode($json,true);
        foreach($array as $key => $value) {
            $position++;
            // If value isn't blank, or key isn't numeric meaning not a blank line, then add entry
            if($value !== "" || !is_numeric($key)) {
                // If passed in option is a boolean (true or false) this will normally
                // save as 1 or 0. But we want to keep the value as words.
                if(is_bool($value)) {
                    if($value === true) {
                        $value = "true";
                    } else {
                        $value = "false";
                    }
                }

                // Always convert $key to uppercase
                $env .= strtoupper($key) . "=" . $value;

                // If isn't last item in array add new line to end
                if($position != count($array)) {
                   $env .= "\n";
                }
            } else {
                $env .= "\n";
            }
        }
        $mwrite = fopen($envPath, "w");
        fwrite($mwrite, $env);
        fclose($mwrite);
    }
    /**
     * XML to .env file storage
     *
     * @param $json
     * @param $envPath
     */
    public static function XmlToEnv(array $xml, string $envPath)
    {
        $env = "";
        $position = 0;
        $array = simplexml_load_string($xml);
        foreach($array as $key => $value) {
            $position++;
            // If value isn't blank, or key isn't numeric meaning not a blank line, then add entry
            if($value !== "" || !is_numeric($key)) {
                // If passed in option is a boolean (true or false) this will normally
                // save as 1 or 0. But we want to keep the value as words.
                if(is_bool($value)) {
                    if($value === true) {
                        $value = "true";
                    } else {
                        $value = "false";
                    }
                }

                // Always convert $key to uppercase
                $env .= strtoupper($key) . "=" . $value;

                // If isn't last item in array add new line to end
                if($position != count($array)) {
                   $env .= "\n";
                }
            } else {
                $env .= "\n";
            }
        }
        $mwrite = fopen($envPath, "w");
        fwrite($mwrite, $env);
        fclose($mwrite);
    }
}
?>
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.