web-dev-qa-db-ja.com

.env値をlaravelでプログラム的にオンザフライで設定する方法

Laravelで最初から書いているカスタムCMSがあり、ユーザーが設定したら、コントローラーからデータベースの詳細、メーラーの詳細、一般構成などのenv値を設定したい私が作成しているGUIを使用して、外出先でそれらを変更できる柔軟性をユーザーに提供したいと考えています。

だから私の質問は、ユーザーから受け取った値を.envファイルをコントローラーから必要なときに。

そして、.env外出先でのファイル、または他の方法がありますか?

前もって感謝します。

17
Chintan Palan

Totymedliの回答に基づきます。

複数の環境変数値を一度に変更する必要がある場合は、配列を渡すことができます(key-> value)。以前に存在しなかったキーが追加され、boolが返されるため、成功をテストできます。

public function setEnvironmentValue(array $values)
{

    $envFile = app()->environmentFilePath();
    $str = file_get_contents($envFile);

    if (count($values) > 0) {
        foreach ($values as $envKey => $envValue) {

            $str .= "\n"; // In case the searched variable is in the last line without \n
            $keyPosition = strpos($str, "{$envKey}=");
            $endOfLinePosition = strpos($str, "\n", $keyPosition);
            $oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);

            // If key does not exist, add it
            if (!$keyPosition || !$endOfLinePosition || !$oldLine) {
                $str .= "{$envKey}={$envValue}\n";
            } else {
                $str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
            }

        }
    }

    $str = substr($str, 0, -1);
    if (!file_put_contents($envFile, $str)) return false;
    return true;

}
7
Oluwafisayo

Laravelは.env_データにアクセスして保存するために設定ファイルを使用するので、config()メソッドでこのデータをオンザフライで設定できます:

_config(['database.connections.mysql.Host' => '127.0.0.1']);
_

このデータを取得するには、config()を使用します。

_config('database.connections.mysql.Host')
_

実行時に構成値を設定するには、配列をconfigヘルパーに渡します

https://laravel.com/docs/5.3/configuration#accessing-configuration-values

34
Alexey Mezenin

気を付けて! laravel .envのすべての変数が設定環境に保存されるわけではありません。実際の.envコンテンツを上書きするには、単に次のように使用します。

putenv( "CUSTOM_VARIABLE = hero");

いつものように読むには、env( 'CUSTOM_VARIABLE')またはenv( 'CUSTOM_VARIABLE'、 'devault')

注:アプリのどの部分でenv設定を使用するかに応じて、変数をindex.phpまたはbootstrap.phpファイルに配置して、変数を早期に設定する必要がある場合があります。アプリサービスプロバイダーでの設定は、env設定の一部のパッケージ/使用には遅すぎる場合があります。

20
Oliver Maslo

Joshの答えに基づきます。 .envファイル内のキーの値を置き換える方法が必要でした。

しかし、joshの答えとは異なり、現在の値や、構成ファイルでアクセス可能な現在の値を知ることに依存したくありませんでした。

私の目標は、設定ファイルをまったく使用せず、.envファイルを直接使用するLaravel Envoyが使用する値を置き換えることです。

私の考えは次のとおりです。

public function setEnvironmentValue($envKey, $envValue)
{
    $envFile = app()->environmentFilePath();
    $str = file_get_contents($envFile);

    $oldValue = strtok($str, "{$envKey}=");

    $str = str_replace("{$envKey}={$oldValue}", "{$envKey}={$envValue}\n", $str);

    $fp = fopen($envFile, 'w');
    fwrite($fp, $str);
    fclose($fp);
}

使用法:

$this->setEnvironmentValue('DEPLOY_SERVER', '[email protected]');
14
vesperknight

より単純化された:

public function putPermanentEnv($key, $value)
{
    $path = app()->environmentFilePath();

    $escaped = preg_quote('='.env($key), '/');

    file_put_contents($path, preg_replace(
        "/^{$key}{$escaped}/m",
        "{$key}={$value}",
        file_get_contents($path)
    ));
}

またはヘルパーとして:

if ( ! function_exists('put_permanent_env'))
{
    function put_permanent_env($key, $value)
    {
        $path = app()->environmentFilePath();

        $escaped = preg_quote('='.env($key), '/');

        file_put_contents($path, preg_replace(
            "/^{$key}{$escaped}/m",
           "{$key}={$value}",
           file_get_contents($path)
        ));
    }
}
7
Elias Tutungi

これらの設定を環境ファイルに永続化して、後で再度読み込まれるようにする場合(構成がキャッシュされている場合でも)、このような関数を使用できます。セキュリティに関する注意をここに入れます。このようなメソッドへの呼び出しは厳しくガードし、ユーザー入力は適切にサニタイズする必要があります。

_private function setEnvironmentValue($environmentName, $configKey, $newValue) {
    file_put_contents(App::environmentFilePath(), str_replace(
        $environmentName . '=' . Config::get($configKey),
        $environmentName . '=' . $newValue,
        file_get_contents(App::environmentFilePath())
    ));

    Config::set($configKey, $newValue);

    // Reload the cached config       
    if (file_exists(App::getCachedConfigPath())) {
        Artisan::call("config:cache");
    }
}
_

その使用例は次のとおりです。

_$this->setEnvironmentValue('APP_LOG_LEVEL', 'app.log_level', 'debug');
_

_$environmentName_は環境ファイルのキーです(例。APP_LOG_LEVEL)

_$configKey_は、実行時に構成にアクセスするために使用されるキーです(例。app.log_level(tinker config('app.log_level'))。

_$newValue_はもちろん、永続化する新しい値です。

4
Josh

tl; dr

vesperknight's answer に基づいて、 strtok または env() を使用しないソリューションを作成しました。

_private function setEnvironmentValue($envKey, $envValue)
{
    $envFile = app()->environmentFilePath();
    $str = file_get_contents($envFile);

    $str .= "\n"; // In case the searched variable is in the last line without \n
    $keyPosition = strpos($str, "{$envKey}=");
    $endOfLinePosition = strpos($str, PHP_EOL, $keyPosition);
    $oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
    $str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
    $str = substr($str, 0, -1);

    $fp = fopen($envFile, 'w');
    fwrite($fp, $str);
    fclose($fp);
}
_

説明

これは、一部の人には機能しないstrtokや、評価され、埋め込み変数を補間する二重引用符で囲まれた_.env_変数では機能しないenv()を使用しません

_KEY="Something with spaces or variables ${KEY2}"
_
3
totymedli

このパッケージを使用できます https://github.com/ImLiam/laravel-env-set-command

次に、Artisan Facadeを使用して職人コマンドを呼び出します。例:

Artisan::call('php artisan env:set app_name Example')
0
Ahmed Atoui

。envファイル関数のsignle値を置換

/**
 * @param string $key
 * @param string $value
 * @param null $env_path
 */
function set_env(string $key, string $value, $env_path = null)
{
    $value = preg_replace('/\s+/', '', $value); //replace special ch
    $key = strtoupper($key); //force upper for security
    $env = file_get_contents(isset($env_path) ? $env_path : base_path('.env')); //fet .env file
    $env = str_replace("$key=" . env($key), "$key=" . $value, $env); //replace value
    /** Save file eith new content */
    $env = file_put_contents(isset($env_path) ? $env_path : base_path('.env'), $env);
}

ローカル(laravel)の使用例:set_env( 'APP_VERSION'、1.8)

カスタムパスの使用例:set_env( 'APP_VERSION'、1.8、$ envfilepath)

0
Mwspace LLC

このソリューションは、Elias Tutungiが提供するものに基づいており、複数の値の変更を受け入れ、foreachがグロスであるためLaravelコレクションを使用します

    function set_environment_value($values = [])
    {
        $path = app()->environmentFilePath();

        collect($values)->map(function ($value, $key) use ($path) {
            $escaped = preg_quote('='.env($key), '/');

            file_put_contents($path, preg_replace(
                "/^{$key}{$escaped}/m",
               "{$key}={$value}",
               file_get_contents($path)
            ));
        });

        return true;
    }
0
Randy Allen

Totymedliの回答とOluwafisayoの回答に基づきます。

.envファイルを変更するために少し変更を設定しました。Laravel 5.8では正常に動作しますが、変更後、.envファイルが変更されたときに変数が変更されないことがわかりました。 php artisan serveで再起動して、キャッシュなどをクリアしようとしましたが、解決策が見つかりません。

public function setEnvironmentValue(array $values)
{
    $envFile = app()->environmentFilePath();
    $str = file_get_contents($envFile);
    $str .= "\r\n";
    if (count($values) > 0) {
        foreach ($values as $envKey => $envValue) {

            $keyPosition = strpos($str, "$envKey=");
            $endOfLinePosition = strpos($str, "\n", $keyPosition);
            $oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);

            if (is_bool($keyPosition) && $keyPosition === false) {
                // variable doesnot exist
                $str .= "$envKey=$envValue";
                $str .= "\r\n";
            } else {
                // variable exist                    
                $str = str_replace($oldLine, "$envKey=$envValue", $str);
            }            
        }
    }

    $str = substr($str, 0, -1);
    if (!file_put_contents($envFile, $str)) {
        return false;
    }

    app()->loadEnvironmentFrom($envFile);    

    return true;
}

したがって、setEnvironmentValue関数を使用して.envファイルを正しく書き換えますが、どのようにLaravel=システムを再起動せずに新しい.envを再読み込みできますか?

私はそれに関する情報を探していましたが、私は見つけました

    Artisan::call('cache:clear');

しかし、ローカルでは動作しません!私にとっては、しかし、コードをアップロードしてサーブでテストすると、うまくいきます。

Larave 5.8でテストし、サーバーで作業しました...

これは、複数のWordとスペースを別々に持つ変数がある場合のヒントかもしれません、私がした解決策

    public function update($variable, $value)
    {

        if ($variable == "APP_NAME" ||  $variable ==  "MAIL_FROM_NAME") {
            $value = "\"$value\"";
        }

        $values = array(
            $variable=>$value
            );
        $this->setEnvironmentValue($values);

        Artisan::call('config:clear');
        return true;
    }
0
iohan sandoval