7

Tôi đang sử dụng dotenv cho PHP để quản lý các thiết lập môi trường (không lavarel nhưng tôi gắn thẻ nó vì lavarel cũng sử dụng dotenv)dotenv đòi hỏi tập tin .env về sản xuất

tôi đã loại trừ các .env từ cơ sở mã và tôi đã thêm .env.example cho tất cả các cộng tác viên khác

trên trang github của dotenv:

phpdotenv được thực hiện cho môi trường phát triển, và nói chung không nên được sử dụng trong sản xuất. Trong quá trình sản xuất, các biến môi trường thực tế nên được đặt để không có phí tải tệp .env trên mỗi yêu cầu. Điều này có thể đạt được thông qua một quá trình triển khai tự động với các công cụ như Vagrant, chef, hoặc Puppet, hoặc có thể được thiết lập thủ công với các máy chủ đám mây như Pagodabox và Heroku.

Điều mà tôi không hiểu là tôi có được ngoại lệ sau đây:

PHP Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Dotenv: Environment file .env not found or not readable.

Điều này mâu thuẫn với những gì tài liệu nói "các biến môi trường thực tế nên được thiết lập để không có trên không tải tệp .env trên mỗi yêu cầu. "

Vì vậy, câu hỏi đặt ra là nếu có lý do nào khiến dotenv ném ngoại lệ đó và/hoặc tôi có thiếu gì đó không? Trước hết hành vi này là khác nhau so với các thư viện dotenv khác (ruby)

tôi có thể dễ dàng làm việc xung quanh này, giải pháp không tốt bụng:

if(getenv('APPLICATION_ENV') !== 'production') { /* or staging */ 
    $dotenv = new Dotenv\Dotenv(__DIR__); 
    $dotenv->load(); 
} 

giải pháp Nicest theo ý kiến ​​của tôi, nhưng tôi nghĩ dotenv nên xử lý này.

$dotenv = new Dotenv\Dotenv(__DIR__); 
//Check if file exists the same way as dotenv does it 
//See classes DotEnv\DotEnv and DotEnv\Loader 
//$filePath = $dotenv->getFilePath(__DIR__); 
//This method is protected so extract code from method (see below) 

$filePath = rtrim(__DIR__, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR . '.env'; 
//both calls are cached so (almost) no performance loss 
if(is_file($filePath) && is_readable($filePath)) { 
    $dotenv->load(); 
} 

Trả lời

7

Dotenv được xây dựng xung quanh ý tưởng, nó sẽ chỉ được sử dụng trong môi trường phát triển. Vì vậy, nó luôn luôn mong đợi .env tập tin để có mặt.

Giải pháp bạn không thích là cách được khuyến nghị sử dụng Dotenv. Và có vẻ như là nó won't change in near future. Liên quan thảo luận trong theo dõi vấn đề của dự án: https://github.com/vlucas/phpdotenv/issues/63#issuecomment-74561880

Lưu ý, rằng Mark offers có một cách tiếp cận tốt cho các môi trường sản xuất/dàn, mà bỏ qua tải tập tin, nhưng không xác nhận

$dotenv = new Dotenv\Dotenv(); 
if(getenv('APP_ENV') === 'development') { 
    $dotenv->load(__DIR__); 
} 
$dotenv->required('OTHER_VAR'); 
+0

Aaah Tôi có thể sử dụng '$ dotenv-> required()' nó hoạt động theo bất kỳ cách nào tốt đẹp. 'Getenv ('APP_ENV'); 'tôi đoán là an toàn hơn? Tôi nghĩ rằng tôi đi cho các filecheck đó sẽ là tốt cho dự án hiện tại. Cảm ơn! –

+0

@SanderVisser ý của bạn là gì khi nói rằng 'getenv ('APP_ENV')' an toàn hơn? – Alik

+0

Nó ngăn tải tệp .env trên môi trường sản xuất ngay cả khi nó ở đó. –

0

Nếu bạn có vấn đề để tạo ra một APP_ENV biến, mã này là dễ dàng hơn:

$dotenv = new Dotenv\Dotenv(__DIR__); 
if(file_exists(".env")) { 
    $dotenv->load(); 
} 
0

Ngoài ra nhìn vào trong này, giải pháp hiện tại của tôi là sử dụng Lumen's way (tính đến 06 tháng sáu năm 2016) mà là suggested in a discussion:

try { 
    (new Dotenv\Dotenv(__DIR__.'/../'))->load(); 
} catch (Dotenv\Exception\InvalidPathException $e) { 
    // 
} 

Bạn vẫn có thể thực hiện một số xử lý ngoại lệ bổ sung nếu cần (ví dụ: rơi vào giá trị mặc định hoặc thực hiện một số xác thực.

+1

Điều này đánh bại mục đích "không có phí tải tệp .env trên mỗi yêu cầu" –

Các vấn đề liên quan