動態

詳情 返回 返回

Yii2 init 初始化腳本分析 - 動態 詳情

腳本目的:

init 腳本主要的作用是:從 environments 目錄中複製配置文件,確保應用適配不同環境(例如開發、生產環境等)。

工作流程:

  • 獲取 $_SERVERargv 參數
  • 加載 environments/index.php 文件,拿到不同環境配置指定的配置文件關係。
  • 如果執行 init 腳本時提供了 --env 選項,例如:--env=Development 則直接應用此環境,否則會被提示需要選擇一個環境來初始化。
  • 獲取 environments 對應環境下的所有文件。
  • 因為上一步獲取到的所有文件是帶有文件全路徑的,所以這一步直接複製文件到對應的路徑,如:frontend/config/params-local.php
  • environments/index.php 文件中獲取到對應環境所配置的需要設置可寫、可執行的目錄來執行操作。

代碼詳解:

  • 解析命令行參數:

  • 檢查命令行參數:

  • 獲取 environments 中的文件列表:

  • 複製文件:
function copyFile($root, $source, $target, &$all, $params)
{
    // 檢查源文件是否存在
    if (!is_file($root . '/' . $source)) {
        echo "       skip $target ($source not exist)\n";
        return true;
    }
    // 檢查目標文件是否存在
    if (is_file($root . '/' . $target)) {
        if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) {
            echo "  unchanged $target\n";
            return true;
        }
        // 如果$all為true,輸出信息並直接進行覆蓋。
        // 否則,提示用户目標文件已存在,並詢問是否覆蓋(選擇“是”、“否”、“全部”或“退出”)。
        if ($all) {
            echo "  overwrite $target\n";
        } else {
            echo "      exist $target\n";
            echo "            ...overwrite? [Yes|No|All|Quit] ";


            // 通過命令行接收用户輸入。如果$params['overwrite']不為空,使用該值;否則,等待用户輸入。
            $answer = !empty($params['overwrite']) ? $params['overwrite'] : trim(fgets(STDIN));

            // 根據用户輸入執行相應操作:
            // 如果輸入“q”或“Q”,返回false以退出操作。
            // 如果輸入“y”或“Y”,輸出覆蓋信息並繼續。
            // 如果輸入“a”或“A”,輸出覆蓋信息並設置$all為true,以便後續文件均自動覆蓋。
            // 其他輸入則跳過目標文件。
            if (!strncasecmp($answer, 'q', 1)) {
                return false;
            } else {
                if (!strncasecmp($answer, 'y', 1)) {
                    echo "  overwrite $target\n";
                } else {
                    if (!strncasecmp($answer, 'a', 1)) {
                        echo "  overwrite $target\n";
                        $all = true;
                    } else {
                        echo "       skip $target\n";
                        return true;
                    }
                }
            }
        }
        file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
        return true;
    }
    // 如果目標文件不存在,輸出信息並進行復制。
    echo "   generate $target\n";
    // 使用@mkdir創建目標文件的目錄(如果不存在),並設置目錄權限為0777。
    @mkdir(dirname($root . '/' . $target), 0777, true);
    file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
    return true;
}
  • 執行回調方法:
$callbacks = ['setCookieValidationKey', 'setWritable', 'setExecutable', 'createSymlink'];
foreach ($callbacks as $callback) {
    if (!empty($env[$callback])) {
        $callback($root, $env[$callback]);
    }
}
// 讀取 environments/index.php 文件的配置:
'Development' => [
    'path' => 'dev',
    'setWritable' => [ // runtime目錄設置為可寫
        'backend/runtime',
        'console/runtime',
        'frontend/runtime',
    ],
    'setExecutable' => [ // yii、yii_test文件設置為可執行
        'yii',
        'yii_test',
    ],
    'setCookieValidationKey' => [
        'backend/config/main-local.php',
        'common/config/codeception-local.php',
        'frontend/config/main-local.php',
    ],
],

// 執行具體的回調方法:
// 設置文件可寫
function setWritable($root, $paths)
{
    foreach ($paths as $writable) {
        if (is_dir("$root/$writable")) {
            if (@chmod("$root/$writable", 0777)) {
                echo "      chmod 0777 $writable\n";
            } else {
                printError("Operation chmod not permitted for directory $writable.");
            }
        } else {
            printError("Directory $writable does not exist.");
        }
    }
}

// 設置文件可執行
function setExecutable($root, $paths)
{
    foreach ($paths as $executable) {
        if (file_exists("$root/$executable")) {
            if (@chmod("$root/$executable", 0755)) {
                echo "      chmod 0755 $executable\n";
            } else {
                printError("Operation chmod not permitted for $executable.");
            }
        } else {
            printError("$executable does not exist.");
        }
    }
}

function setCookieValidationKey($root, $paths)
{
    foreach ($paths as $file) {
        echo "   generate cookie validation key in $file\n";
        $file = $root . '/' . $file;
        $length = 32;
        $bytes = openssl_random_pseudo_bytes($length);
        $key = strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.');
        $content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($file));
        file_put_contents($file, $content);
    }
}
user avatar bugcatcher 頭像 lazytimes 頭像 aoshunseo 頭像 womaxuanhuang 頭像 kip_67231fa160bbc 頭像 muzijun_68c14af5563a2 頭像
點贊 6 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.