同时在多个FTPs上进行数据操作


Data manipulation on multiple FTPs simultaneosly

让我先给你看一下代码,这样你就能明白我在说什么了:

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服务器和文件名,或者您可以添加参数来指定要由子脚本执行的操作…