當前位置: 首頁> 最新文章列表> 結合ftp_rawlist 編寫自動化部署腳本

結合ftp_rawlist 編寫自動化部署腳本

gitbox 2025-06-17

1. 準備工作

首先,你需要確保你的PHP 環境支持FTP 函數。可以通過以下命令檢查是否已經啟用:

 <span><span><span class="hljs-title function_ invoke__">phpinfo</span></span><span>();
</span></span>

在輸出中查找FTP 部分,確保FTP 擴展已啟用。如果未啟用,可以通過修改php.ini文件啟用該擴展:

 <span><span><span class="hljs-attr">extension</span></span><span>=ftp
</span></span>

然後重啟你的Web 服務器。

2. 連接到FTP 服務器

我們需要使用PHP 提供的ftp_connectftp_login函數連接到FTP 服務器。

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-variable">$ftp_server</span></span><span> = </span><span><span class="hljs-string">"ftp.example.com"</span></span><span>; </span><span><span class="hljs-comment">// FTP 服務器地址</span></span><span>
</span><span><span class="hljs-variable">$ftp_user_name</span></span><span> = </span><span><span class="hljs-string">"username"</span></span><span>;     </span><span><span class="hljs-comment">// FTP 使用者名稱</span></span><span>
</span><span><span class="hljs-variable">$ftp_user_pass</span></span><span> = </span><span><span class="hljs-string">"password"</span></span><span>;     </span><span><span class="hljs-comment">// FTP 密碼</span></span><span>

</span><span><span class="hljs-comment">// 連接到 FTP 伺服器</span></span><span>
</span><span><span class="hljs-variable">$conn_id</span></span><span> = </span><span><span class="hljs-title function_ invoke__">ftp_connect</span></span><span>(</span><span><span class="hljs-variable">$ftp_server</span></span><span>);

</span><span><span class="hljs-comment">// 登錄到 FTP 伺服器</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (@</span><span><span class="hljs-title function_ invoke__">ftp_login</span></span><span>(</span><span><span class="hljs-variable">$conn_id</span></span><span>, </span><span><span class="hljs-variable">$ftp_user_name</span></span><span>, </span><span><span class="hljs-variable">$ftp_user_pass</span></span><span>)) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"成功連接到 <span class="hljs-subst">$ftp_server</span></span></span><span>\n";
} </span><span><span class="hljs-keyword">else</span></span><span> {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"无法連接到 <span class="hljs-subst">$ftp_server</span></span></span><span>\n";
    </span><span><span class="hljs-keyword">exit</span></span><span>;
}
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

以上代碼通過ftp_connect連接到FTP 服務器,並使用ftp_login進行身份驗證。

3. 使用ftp_rawlist獲取文件和目錄列表

ftp_rawlist函數返回服務器指定目錄的原始列表。此列表包括每個文件或目錄的詳細信息,如權限、大小、日期等。通過解析這些信息,我們可以判斷某個文件是否已經存在,並決定是否上傳或覆蓋。

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-comment">// 獲取根目錄的文件列表</span></span><span>
</span><span><span class="hljs-variable">$remote_dir</span></span><span> = </span><span><span class="hljs-string">"/"</span></span><span>;
</span><span><span class="hljs-variable">$file_list</span></span><span> = </span><span><span class="hljs-title function_ invoke__">ftp_rawlist</span></span><span>(</span><span><span class="hljs-variable">$conn_id</span></span><span>, </span><span><span class="hljs-variable">$remote_dir</span></span><span>);

</span><span><span class="hljs-comment">// 輸出獲取到的文件列表</span></span><span>
</span><span><span class="hljs-title function_ invoke__">print_r</span></span><span>(</span><span><span class="hljs-variable">$file_list</span></span><span>);
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

執行以上代碼後,會返回類似於以下格式的文件列表:

 <span><span>Array
(
    [0] =&gt; drwxr-xr-x   2 1000 1000  4096 May  7 12:30 public_html
    [1] =&gt; -rw-r--r--   1 1000 1000  2048 May  7 12:35 index.php
    [2] =&gt; -rw-r--r--   1 1000 1000  1024 May  7 12:36 style.css
)
</span></span>

通過分析這些信息,我們可以編寫腳本來檢查某個文件是否已經存在,或者獲取文件的修改時間,從而決定是否需要上傳文件。

4. 比較本地文件和遠程文件

假設我們有一個本地的部署文件夾,並希望將其與遠程服務器上的文件進行比較。我們可以通過ftp_rawlist獲取遠程文件的時間戳和大小,結合本地文件的信息來決定是否上傳。

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-comment">// 本地文件路徑</span></span><span>
</span><span><span class="hljs-variable">$local_file</span></span><span> = </span><span><span class="hljs-string">'path/to/local/index.php'</span></span><span>;
</span><span><span class="hljs-variable">$remote_file</span></span><span> = </span><span><span class="hljs-string">'index.php'</span></span><span>;

</span><span><span class="hljs-comment">// 獲取本地文件的修改時間</span></span><span>
</span><span><span class="hljs-variable">$local_file_time</span></span><span> = </span><span><span class="hljs-title function_ invoke__">filemtime</span></span><span>(</span><span><span class="hljs-variable">$local_file</span></span><span>);

</span><span><span class="hljs-comment">// 獲取遠程文件的詳細信息</span></span><span>
</span><span><span class="hljs-variable">$remote_file_info</span></span><span> = </span><span><span class="hljs-title function_ invoke__">ftp_rawlist</span></span><span>(</span><span><span class="hljs-variable">$conn_id</span></span><span>, </span><span><span class="hljs-variable">$remote_file</span></span><span>);
</span><span><span class="hljs-variable">$remote_file_info</span></span><span> = </span><span><span class="hljs-title function_ invoke__">explode</span></span><span>(</span><span><span class="hljs-string">" "</span></span><span>, </span><span><span class="hljs-variable">$remote_file_info</span></span><span>[</span><span><span class="hljs-number">0</span></span><span>]);
</span><span><span class="hljs-variable">$remote_file_time</span></span><span> = </span><span><span class="hljs-title function_ invoke__">strtotime</span></span><span>(</span><span><span class="hljs-variable">$remote_file_info</span></span><span>[</span><span><span class="hljs-number">5</span></span><span>] . </span><span><span class="hljs-string">' '</span></span><span> . </span><span><span class="hljs-variable">$remote_file_info</span></span><span>[</span><span><span class="hljs-number">6</span></span><span>] . </span><span><span class="hljs-string">' '</span></span><span> . </span><span><span class="hljs-variable">$remote_file_info</span></span><span>[</span><span><span class="hljs-number">7</span></span><span>]);

</span><span><span class="hljs-comment">// 比較文件時間,決定是否需要上傳</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$local_file_time</span></span><span> &gt; </span><span><span class="hljs-variable">$remote_file_time</span></span><span>) {
    </span><span><span class="hljs-comment">// 上傳文件</span></span><span>
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">ftp_put</span></span><span>(</span><span><span class="hljs-variable">$conn_id</span></span><span>, </span><span><span class="hljs-variable">$remote_file</span></span><span>, </span><span><span class="hljs-variable">$local_file</span></span><span>, FTP_BINARY)) {
        </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"文件 <span class="hljs-subst">$local_file</span></span></span><span> 上傳成功!\n";
    } </span><span><span class="hljs-keyword">else</span></span><span> {
        </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"文件 <span class="hljs-subst">$local_file</span></span></span><span> 上傳失敗!\n";
    }
} </span><span><span class="hljs-keyword">else</span></span><span> {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"遠程文件已經是最新的,無需上傳。\n"</span></span><span>;
}
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

5. 自動化部署腳本

現在我們將所有部分結合,編寫一個自動化部署腳本。此腳本將會自動判斷哪些文件需要更新,並上傳到遠程服務器。

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-variable">$ftp_server</span></span><span> = </span><span><span class="hljs-string">"ftp.example.com"</span></span><span>;
</span><span><span class="hljs-variable">$ftp_user_name</span></span><span> = </span><span><span class="hljs-string">"username"</span></span><span>;
</span><span><span class="hljs-variable">$ftp_user_pass</span></span><span> = </span><span><span class="hljs-string">"password"</span></span><span>;

</span><span><span class="hljs-comment">// 連接到 FTP 伺服器</span></span><span>
</span><span><span class="hljs-variable">$conn_id</span></span><span> = </span><span><span class="hljs-title function_ invoke__">ftp_connect</span></span><span>(</span><span><span class="hljs-variable">$ftp_server</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (!@</span><span><span class="hljs-title function_ invoke__">ftp_login</span></span><span>(</span><span><span class="hljs-variable">$conn_id</span></span><span>, </span><span><span class="hljs-variable">$ftp_user_name</span></span><span>, </span><span><span class="hljs-variable">$ftp_user_pass</span></span><span>)) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"无法連接到 <span class="hljs-subst">$ftp_server</span></span></span><span>\n";
    </span><span><span class="hljs-keyword">exit</span></span><span>;
}

</span><span><span class="hljs-comment">// 本地部署文件夾</span></span><span>
</span><span><span class="hljs-variable">$local_dir</span></span><span> = </span><span><span class="hljs-string">"path/to/local/files/"</span></span><span>;
</span><span><span class="hljs-variable">$remote_dir</span></span><span> = </span><span><span class="hljs-string">"/"</span></span><span>;

</span><span><span class="hljs-comment">// 獲取本地文件列表</span></span><span>
</span><span><span class="hljs-variable">$local_files</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">RecursiveIteratorIterator</span></span><span>(
    </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">RecursiveDirectoryIterator</span></span><span>(</span><span><span class="hljs-variable">$local_dir</span></span><span>),
    </span><span><span class="hljs-title class_">RecursiveIteratorIterator</span></span><span>::</span><span><span class="hljs-variable constant_">LEAVES_ONLY</span></span><span>
);

</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$local_files</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$local_file</span></span><span>) {
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$local_file</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">isDir</span></span><span>()) {
        </span><span><span class="hljs-keyword">continue</span></span><span>;
    }

    </span><span><span class="hljs-comment">// 獲取相對路徑</span></span><span>
    </span><span><span class="hljs-variable">$relative_path</span></span><span> = </span><span><span class="hljs-title function_ invoke__">substr</span></span><span>(</span><span><span class="hljs-variable">$local_file</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">getRealPath</span></span><span>(), </span><span><span class="hljs-title function_ invoke__">strlen</span></span><span>(</span><span><span class="hljs-variable">$local_dir</span></span><span>));

    </span><span><span class="hljs-comment">// 獲取遠程文件的詳細信息</span></span><span>
    </span><span><span class="hljs-variable">$remote_file</span></span><span> = </span><span><span class="hljs-variable">$remote_dir</span></span><span> . </span><span><span class="hljs-variable">$relative_path</span></span><span>;
    </span><span><span class="hljs-variable">$remote_file_info</span></span><span> = </span><span><span class="hljs-title function_ invoke__">ftp_rawlist</span></span><span>(</span><span><span class="hljs-variable">$conn_id</span></span><span>, </span><span><span class="hljs-variable">$remote_file</span></span><span>);
    
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$remote_file_info</span></span><span>) {
        </span><span><span class="hljs-comment">// 文件已存在,比較時間</span></span><span>
        </span><span><span class="hljs-variable">$remote_file_info</span></span><span> = </span><span><span class="hljs-title function_ invoke__">explode</span></span><span>(</span><span><span class="hljs-string">" "</span></span><span>, </span><span><span class="hljs-variable">$remote_file_info</span></span><span>[</span><span><span class="hljs-number">0</span></span><span>]);
        </span><span><span class="hljs-variable">$remote_file_time</span></span><span> = </span><span><span class="hljs-title function_ invoke__">strtotime</span></span><span>(</span><span><span class="hljs-variable">$remote_file_info</span></span><span>[</span><span><span class="hljs-number">5</span></span><span>] . </span><span><span class="hljs-string">' '</span></span><span> . </span><span><span class="hljs-variable">$remote_file_info</span></span><span>[</span><span><span class="hljs-number">6</span></span><span>] . </span><span><span class="hljs-string">' '</span></span><span> . </span><span><span class="hljs-variable">$remote_file_info</span></span><span>[</span><span><span class="hljs-number">7</span></span><span>]);
        </span><span><span class="hljs-variable">$local_file_time</span></span><span> = </span><span><span class="hljs-title function_ invoke__">filemtime</span></span><span>(</span><span><span class="hljs-variable">$local_file</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">getRealPath</span></span><span>());

        </span><span><span class="hljs-comment">// 如果本地文件較新,則上傳</span></span><span>
        </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$local_file_time</span></span><span> &gt; </span><span><span class="hljs-variable">$remote_file_time</span></span><span>) {
            </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">ftp_put</span></span><span>(</span><span><span class="hljs-variable">$conn_id</span></span><span>, </span><span><span class="hljs-variable">$remote_file</span></span><span>, </span><span><span class="hljs-variable">$local_file</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">getRealPath</span></span><span>(), FTP_BINARY)) {
                </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"文件 <span class="hljs-subst">$relative_path</span></span></span><span> 更新成功!\n";
            } </span><span><span class="hljs-keyword">else</span></span><span> {
                </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"文件 <span class="hljs-subst">$relative_path</span></span></span><span> 更新失敗!\n";
            }
        }
    } </span><span><span class="hljs-keyword">else</span></span><span> {
        </span><span><span class="hljs-comment">// 文件不存在,直接上傳</span></span><span>
        </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">ftp_put</span></span><span>(</span><span><span class="hljs-variable">$conn_id</span></span><span>, </span><span><span class="hljs-variable">$remote_file</span></span><span>, </span><span><span class="hljs-variable">$local_file</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">getRealPath</span></span><span>(), FTP_BINARY)) {
            </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"文件 <span class="hljs-subst">$relative_path</span></span></span><span> 上傳成功!\n";
        } </span><span><span class="hljs-keyword">else</span></span><span> {
            </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"文件 <span class="hljs-subst">$relative_path</span></span></span><span> 上傳失敗!\n";
        }
    }
}

</span><span><span class="hljs-comment">// 關閉 FTP 連接</span></span><span>
</span><span><span class="hljs-title function_ invoke__">ftp_close</span></span><span>(</span><span><span class="hljs-variable">$conn_id</span></span><span>);
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

6. 總結

通過ftp_rawlist函數,我們能夠輕鬆獲取遠程服務器上文件的詳細信息。結合文件的修改時間和大小,我們可以判斷是否需要上傳新的文件或覆蓋已有的文件。這種方式非常適合自動化部署,能夠有效減少人工操作,提高部署效率。

通過這個簡單的PHP 腳本,你可以將FTP 上傳與自動化部署結合在一起,實現更加智能化的文件同步和更新。