getenv () เทียบกับ $ _ENV ใน PHP


88

อะไรคือความแตกต่างระหว่างgetenv()และ$_ENV ?

การแลกเปลี่ยนระหว่างการใช้อย่างใดอย่างหนึ่ง?

ฉันสังเกตเห็นบางครั้งgetenv()ให้สิ่งที่ฉันต้องการในขณะที่$_ENVไม่ได้ (เช่นHOME)


1
อย่าติดกับ PHP ที่ซ่อนรายละเอียดที่เต็มไปด้วยเลือดจากคุณ $_ENVและ$_SERVERมีการเติมข้อมูลที่ได้รับในรูปแบบต่างๆ getenv()ยังเป็นอีกวิธีหนึ่งในการเข้าถึงข้อมูลที่ PHP ไม่อนุญาตให้คุณเข้าถึงโดยตรง ใช้งานได้แม้variables_order = "G"เมื่อใด$_SERVERและ$_ENVว่างเปล่า อ่านคำตอบที่ดีโดยคอเนอร์แมคเดอร์ มอตโตร
Palec


สำหรับผู้ที่ใช้ Symfony framework มีอีกหนึ่งกรณีที่ จำกัด ดังกล่าวข้างต้น getenv () จะส่งคืนค่าของตัวแปร env เหมือนเดิมเสมอเมื่อเซิร์ฟเวอร์ php เริ่มทำงานแม้ว่าจะมีการเปลี่ยนแปลงในภายหลังก็ตาม ในขณะที่ $ _ENV [] สามารถเปลี่ยนแปลงได้ในรันไทม์โดยการแก้ไขไฟล์. env แต่แน่นอนว่ามันเกี่ยวข้องกับ Symfony ไม่ใช่ PHP โดยทั่วไป
Ross Ivantsiv

คำตอบ:


60

ตามเอกสาร php เกี่ยวกับ getenvมันเหมือนกันทุกgetenvประการยกเว้นว่าจะมองหาตัวแปรในลักษณะที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ ส่วนใหญ่แล้วอาจไม่สำคัญ แต่หนึ่งในความคิดเห็นในเอกสารอธิบาย:

ตัวอย่างเช่นใน Windows $ _SERVER ['Path'] ก็เหมือนที่คุณเห็นโดยตัวอักษรตัวแรกเป็นตัวพิมพ์ใหญ่ไม่ใช่ "PATH" อย่างที่คุณคาดหวัง

ด้วยเหตุนี้ฉันจึงอาจเลือกใช้getenvเว้นแต่คุณจะแน่ใจเกี่ยวกับปลอกของชื่อเรื่องของตัวแปรที่คุณพยายามดึง


15
ไม่ได้อธิบายว่าทำไม $ _ENV ("FOO") และ getenv ("FOO") ให้ผลลัพธ์ที่แตกต่างกัน
rich remer

getenv()ข้อดีเพิ่มเติม: คุณไม่จำเป็นต้องตรวจสอบisset/ emptyก่อนเข้าถึง getenv()จะไม่แจ้งเตือน
Steve Clay

53

ฉันรู้ว่าความคิดเห็นในเอกสารบอกว่าgetenvไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ แต่นั่นไม่ใช่พฤติกรรมที่ฉันเห็น:

> 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

ดูที่ซอร์สโค้ดสำหรับgetenvฟังก์ชันเนื่องจากมีสามวิธีที่ PHP สามารถดึงตัวแปรสภาพแวดล้อม:

  1. ผ่านsapi_getenv(เช่นหากได้รับตัวแปรสภาพแวดล้อมจาก Apache)
  2. ถ้าบน Windows จาก GetEnvironmentVariableA .
  3. หากไม่ใช่ Windows จากgetenvฟังก์ชันที่มีให้โดยlibc.

เท่าที่ฉันสามารถบอกได้มีเพียงครั้งเดียวที่มันจะทำงานในลักษณะที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่คือบน Windows เพราะนั่นคือลักษณะการทำงานของ API ตัวแปรสภาพแวดล้อมของ Windows หากคุณใช้ Linux, BSD, Mac เป็นต้นgetenvยังคงพิจารณาตัวพิมพ์เล็กและใหญ่

ดังกล่าวโดยมาริโอ , $_ENVไม่ได้บรรจุอยู่เสมอเนื่องจากการกำหนดค่าที่แตกต่างกันของvariables_orderดังนั้นจึงเป็นเรื่องที่ดีที่สุดถ้าคุณหลีกเลี่ยง$_ENVถ้าคุณไม่ได้ควบคุมการตั้งค่าเซิร์ฟเวอร์

ดังนั้นสำหรับโค้ด PHP แบบพกพาส่วนใหญ่:

  1. ใช้ getenv .
  2. ใช้กรณีที่ถูกต้องสำหรับชื่อตัวแปรสภาพแวดล้อม

39

นอกจาก$_ENVนี้มักจะว่างเปล่าหากvariables_orderไม่มีในEรายการ ในการตั้งค่าจำนวนมากมีแนวโน้มว่า$_SERVERจะมีการเติมข้อมูลเท่านั้นและ$_ENVมีไว้สำหรับการใช้งาน CLI เท่านั้น

ในทางกลับกันgetenv()เข้าถึงสภาพแวดล้อมโดยตรง

(เกี่ยวกับความคลุมเครือของกรณีสามารถใช้งานได้array_change_key_case()มากกว่า)


6

ฉันพบว่าgetenv()มีประโยชน์ในการหลีกเลี่ยงข้อผิดพลาด PHP แปลก ๆซึ่งบางครั้ง$_SERVERและ$_ENVไม่ได้กำหนดว่าauto_globals_jitเปิดใช้งานอยู่หรือไม่ (สร้างตัวแปร_SERVERและ_ENVเมื่อใช้ครั้งแรก) ตั้งแต่นั้นมาฉันก็เริ่มใช้มัน


3

นำมาจากเอกสาร PHP :

ฟังก์ชั่นนี้จะเป็นประโยชน์ (เมื่อเทียบกับ$_SERVER, $_ENV) เพราะมันค้นหาคีย์ varName $ ในอาร์เรย์ลักษณะกรณีตายเหล่านั้น ตัวอย่างเช่นใน Windows $_SERVER['Path']ก็เหมือนกับที่คุณเห็นเป็นตัวพิมพ์ใหญ่ไม่ใช่ ' PATH' ตามที่คุณคาดไว้ เพียงแค่:<?php getenv('path') ?>


3

ฉันขอเพิ่มว่า getenv () เป็นตัวเลือกที่ดีกว่าเพราะตามหน้าที่แล้วมันสามารถโอเวอร์โหลดได้เพื่อวัตถุประสงค์ในการทดสอบ ในขณะที่การเขียนทับตัวแปร $ _SERVER หรือ $ _ENV ของคุณอาจรบกวนกรอบการทดสอบและไลบรารีอื่น ๆ และท้ายที่สุดก็ต้องใช้งานมากขึ้นเพื่อดำเนินการอย่างปลอดภัย


-1

อ่าน env และสร้าง

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

สิ่งนี้เกี่ยวข้องกับคำถามจริงหรือไม่?
Cyclonecode
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.