首先,你需要确保你的 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 服务器。
我们需要使用 PHP 提供的 ftp_connect 和 ftp_login 函数连接到 FTP 服务器。
<span><span><span class="hljs-meta"><?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">?></span></span><span>
</span></span>
以上代码通过 ftp_connect 连接到 FTP 服务器,并使用 ftp_login 进行身份验证。
ftp_rawlist 函数返回服务器指定目录的原始列表。此列表包括每个文件或目录的详细信息,如权限、大小、日期等。通过解析这些信息,我们可以判断某个文件是否已经存在,并决定是否上传或覆盖。
<span><span><span class="hljs-meta"><?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">?></span></span><span>
</span></span>
执行以上代码后,会返回类似于以下格式的文件列表:
<span><span>Array
(
[0] => drwxr-xr-x 2 1000 1000 4096 May 7 12:30 public_html
[1] => -rw-r--r-- 1 1000 1000 2048 May 7 12:35 index.php
[2] => -rw-r--r-- 1 1000 1000 1024 May 7 12:36 style.css
)
</span></span>
通过分析这些信息,我们可以编写脚本来检查某个文件是否已经存在,或者获取文件的修改时间,从而决定是否需要上传文件。
假设我们有一个本地的部署文件夹,并希望将其与远程服务器上的文件进行比较。我们可以通过 ftp_rawlist 获取远程文件的时间戳和大小,结合本地文件的信息来决定是否上传。
<span><span><span class="hljs-meta"><?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> > </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">?></span></span><span>
</span></span>
现在我们将所有部分结合,编写一个自动化部署脚本。此脚本将会自动判断哪些文件需要更新,并上传到远程服务器。
<span><span><span class="hljs-meta"><?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>-></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>-></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>-></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> > </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>-></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>-></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">?></span></span><span>
</span></span>
通过 ftp_rawlist 函数,我们能够轻松获取远程服务器上文件的详细信息。结合文件的修改时间和大小,我们可以判断是否需要上传新的文件或覆盖已有的文件。这种方式非常适合自动化部署,能够有效减少人工操作,提高部署效率。
通过这个简单的 PHP 脚本,你可以将 FTP 上传与自动化部署结合在一起,实现更加智能化的文件同步和更新。