getenv () vs. $ _ENV di PHP

88

Apa perbedaan antara getenv()dan $_ENV?

Adakah trade-off antara menggunakan keduanya?

Saya perhatikan terkadang getenv()memberi saya apa yang saya butuhkan, sementara $_ENVtidak (seperti HOME).

tau
sumber
1
Jangan terjebak oleh PHP yang menyembunyikan detail berdarah dari Anda. $_ENVdan $_SERVERdiisi dengan data yang diperoleh dengan berbagai cara. getenv()adalah cara lain untuk mengakses data yang PHP tidak memungkinkan Anda untuk mengaksesnya secara langsung. Ia bekerja bahkan dengan variables_order = "G", saat $_SERVERdan $_ENVkosong. Baca jawaban bagus dari Conor McDermottroe .
Palec
Bagi mereka, yang menggunakan framework Symfony, ada satu kasus terbatas di atas. getenv () akan selalu mengembalikan nilai variabel env seperti saat server php dijalankan, bahkan jika setelah itu diubah. Sementara $ _ENV [] dapat diubah dalam runtime dengan memodifikasi file .env. Tapi tentu saja ini berkaitan dengan Symfony, dan bukan PHP pada umumnya.
Ross Ivantsiv

Jawaban:

60

Menurut dokumentasi php tentang getenv , keduanya persis sama, kecuali yang getenvakan mencari variabel secara case-insensitive. Sebagian besar waktu mungkin tidak masalah, tetapi salah satu komentar di dokumentasi menjelaskan:

Misalnya pada Windows $ _SERVER ['Path'] seperti yang Anda lihat, dengan huruf pertama dikapitalisasi, bukan 'PATH' seperti yang Anda harapkan.

Karena itu, saya mungkin akan memilih untuk menggunakan getenvkecuali Anda yakin tentang kapitalisasi judul variabel yang Anda coba ambil.

Batkins
sumber
15
Tidak menjelaskan mengapa $ _ENV ("FOO") dan getenv ("FOO") memberikan hasil yang berbeda.
rich remer
Ditambahkan getenv()Keuntungan: Anda tidak perlu memeriksa isset/ emptysebelum akses. getenv()tidak akan mengeluarkan pemberitahuan.
Steve Clay
53

Saya tahu bahwa komentar di dokumen mengatakan bahwa getenvtidak peka huruf besar / kecil, tetapi bukan itu perilaku yang saya lihat:

> 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

Melihat kode sumber untuk getenvfungsi tersebut, ini karena ada tiga cara PHP dapat mengambil variabel lingkungan:

  1. Melalui sapi_getenv(misalnya jika mendapatkan variabel lingkungan dari Apache)
  2. Jika di Windows, dari GetEnvironmentVariableA.
  3. Jika di non-Windows, dari getenvfungsi yang disediakan oleh libc.

Sejauh yang saya tahu, satu-satunya waktu ketika itu akan berperilaku dengan cara yang tidak peka huruf besar kecil adalah di Windows karena begitulah perilaku API variabel lingkungan Windows. Jika Anda menggunakan Linux, BSD, Mac, dll, maka getenvmasih case sensitive.

Seperti yang disebutkan oleh mario , $_ENVtidak selalu diisi karena konfigurasi yang berbeda variables_orderjadi sebaiknya hindari $_ENVjika Anda tidak mengontrol konfigurasi server.

Jadi, untuk kode PHP paling portabel:

  1. Gunakan getenv.
  2. Gunakan kasus yang benar untuk nama variabel lingkungan.
Conor McDermottroe
sumber
39

Selain $_ENVitu biasanya kosong jika variables_ordertidak Eterdaftar. Pada banyak pengaturan, kemungkinan hanya $_SERVERdiisi, dan $_ENVhanya untuk penggunaan CLI.

Di sisi lain, getenv()mengakses lingkungan secara langsung.

(Mengenai ambiguitas kasus, orang bisa lebih sederhana menggunakan array_change_key_case().)

mario
sumber
6

Saya merasa getenv()berguna untuk menghindari bug PHP aneh di mana kadang $_SERVER- kadang dan $_ENVtidak ditentukan jika auto_globals_jitdiaktifkan (membuat variabel _SERVER dan _ENV saat pertama kali digunakan). Sejak itu saya mulai menggunakannya.

Leopoldo Sanczyk
sumber
3

Diambil dari dokumen PHP :

Fungsi ini berguna (dibandingkan dengan $_SERVER, $_ENV) karena mencari kunci $ varname dengan cara array case-insensitive. Misalnya di Windows $_SERVER['Path']seperti Anda melihat Kapitalisasi, bukan ' PATH' seperti yang Anda harapkan. Jadi hanya:<?php getenv('path') ?>

Ayman Safadi
sumber
3

Saya akan menambahkan bahwa getenv () adalah pilihan yang lebih baik karena, sebagai sebuah fungsi, ia dapat kelebihan beban untuk tujuan pengujian. Sedangkan menimpa variabel $ _SERVER atau $ _ENV Anda dapat mengganggu kerangka kerja pengujian dan pustaka lain dan pada akhirnya membutuhkan lebih banyak pekerjaan untuk dilakukan dengan aman.

Joe Green
sumber
-1

baca env dan buat

<?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);
    }
}
?>
neoistone inc.
sumber
Apa hubungannya ini dengan pertanyaan sebenarnya?
Cyclonecode