当前位置: 首页> 最新文章列表> 结合 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 上传与自动化部署结合在一起,实现更加智能化的文件同步和更新。