让我先给你看一下代码,这样你就能明白我在说什么了:
foreach($video_ftps as $video_ftp) {
$ftp = new FtpClient($video_ftp[0]);
$ftp->set_writing_destination($video_ftp[1]);
if($ftp) {
if($ftp->create_new_dir('archive'))
$utils->log("Created directory '/archive' on source.");
$tmp_ftp = new FtpClient($video_ftp[1]);
$tmp_ftp->create_new_dir('video');
$tmp_ftp->create_new_dir('video/'.$video_ftp[2]);
$tmp_ftp->close();
// Check if new files arrived on ftp
if($ftp->has_new_files())
{
foreach($ftp->fetch_new_file() as $file) {
$checksum_source = "";
$checksum_dest = "";
if($ftp->copy(MODE_SAME_FTP, $file, 'archive'))
$checksum_source = sha1_file($video_ftp[0].'/'.$file);
$utils->log("Copied {$file} to {$ftp->get_writing_destination()}archive/.");
$fileExtension = explode(".", $file)[1];
if($fileExtension == "mp4") {
if($ftp->rename($file , $video_ftp[1].'video/'.$video_ftp[2].'/'.$file))
$checksum_dest = sha1_file($video_ftp[1].'video/'.$video_ftp[2].'/'.$file);
if($checksum_source != $checksum_dest) {
$tmp_ftp = new FtpClient($video_ftp[1]);
$tmp_ftp->copy(MODE_DIFF_FTP, 'video/'.$video_ftp[2].'/'.$file, $video_ftp[0].'/'.$file);
$tmp_ftp->delete('video/'.$video_ftp[2].'/'.$file);
$tmp_ftp->close();
} else {
$utils->log("Moved {$file} file to {$ftp->get_writing_destination()}{$video_ftp[1]}'video/'{$video_ftp[2]}/.");
}
}
}
}
$ftp->close();
}
}
注意:FTPClient类和所有的ftp_*函数做同样的事情。类只是移除前缀,使其面向对象。
。把正在发生的事情留在循环中。假设FTP被操纵,文件被从FTP和不同的FTP中删除、移动和复制。
你需要理解的一件事是循环。我在$video_ftps
中有ftp连接字符串,我依次满足每个连接字符串并对其进行操作。
我想做的是,每个不同的FTP应该在不同的线程中,并且应该与其他FTP同时操作。
我读了关于PHP线程的书,但是找不到或理解任何与之相关的东西。你能告诉我怎么把这个基于循环的东西变成基于线程的东西吗?
更新1:我创建了一个单独的文件来保存ftp的操作部分:
<?php
require 'FtpClient.php';
require 'Utils.php';
$video_ftp = array($argv[0], $argv[1], $argv[2]);
$ftp = new FtpClient($video_ftp[0]);
$ftp->set_writing_destination($video_ftp[1]);
if($ftp) {
if($ftp->create_new_dir('archive'))
$utils->log("Created directory '/archive' on source.");
$tmp_ftp = new FtpClient($video_ftp[1]);
$tmp_ftp->create_new_dir('video');
$tmp_ftp->create_new_dir('video/'.$video_ftp[2]);
$tmp_ftp->close();
// Check if new files arrived on ftp
if($ftp->has_new_files())
{
foreach($ftp->fetch_new_file() as $file) {
$checksum_source = "";
$checksum_dest = "";
if($ftp->copy(MODE_SAME_FTP, $file, 'archive'))
$checksum_source = sha1_file($video_ftp[0].'/'.$file);
$utils->log("Copied {$file} to {$ftp->get_writing_destination()}archive/.");
$fileExtension = explode(".", $file)[1];
if($fileExtension == "mp4") {
if($ftp->rename($file , $video_ftp[1].'video/'.$video_ftp[2].'/'.$file))
$checksum_dest = sha1_file($video_ftp[1].'video/'.$video_ftp[2].'/'.$file);
if($checksum_source != $checksum_dest) {
$tmp_ftp = new FtpClient($video_ftp[1]);
$tmp_ftp->copy(MODE_DIFF_FTP, 'video/'.$video_ftp[2].'/'.$file, $video_ftp[0].'/'.$file);
$tmp_ftp->delete('video/'.$video_ftp[2].'/'.$file);
$tmp_ftp->close();
} else {
$utils->log("Moved {$file} file to {$ftp->get_writing_destination()}{$video_ftp[1]}'video/'{$video_ftp[2]}/.");
}
}
}
}
$ftp->close();
}
?比;
我更新了我以前的文件来运行这个函数,而不是我转移到一个单独的文件的代码:
exec("php video_ftp_manipulator.php ". $video_ftp[0] . "" . $video_ftp[1] . "" . $video_ftp[2] . " > /dev/null &");
现在的问题是,现在什么都没有发生,当我运行我的文件。FTP中没有任何变化。为什么会这样呢?
不需要任何线程。
问题是,你对FTP的抽象很差,我建议你放弃它,直接使用扩展。
FTP扩展自带非阻塞功能,以方便异步请求,使用它们:
- 非阻塞把
- 非阻塞得到
- 非阻塞继续
PHP本质上不做异步请求,尽管有一些方法可以通过在PHP中使用exec()或shell_exec()触发单独的子脚本来实现模拟多线程,将参数传递给子脚本,并将其输出发送到/dev/null,因此PHP在继续之前不会等待响应。虽然可能,但并不理想(我不推荐),因为没有有效的方法从子脚本中获取有用的数据。
可以在循环中使用exec()从shell命令触发另一个脚本。使用示例:
exec("php child.php argument1 argument2 > /dev/null &");
这里我运行child.php作为一个shell脚本,传递它的参数可能有额外的参数。我将输出发送到/dev/null,所以php不会等待它。
在我的子PHP脚本中,我需要使用以下命令来获取参数字符串:
$first_arg = $argv[1];
$second_arg = $argsv[2];
参数可以是ftp服务器和文件名,或者您可以添加参数来指定要由子脚本执行的操作…