Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中导入数据的后台过程_Php_Import_Background Process - Fatal编程技术网

在PHP中导入数据的后台过程

在PHP中导入数据的后台过程,php,import,background-process,Php,Import,Background Process,细节 当用户首次登录到我的应用程序时,我需要从API导入他们商店的所有产品,这可能是10种产品到11000种产品。因此,我认为我需要通知用户,我们将导入他们的产品,并在完成后向他们发送电子邮件 问题 在不要求用户停留在页面上的情况下,导入此数据的最佳方式是什么? 我应该走pcntl_岔路吗? 系统风格的后台任务会更好吗?我认为在PHP中实现这一点的标准方法是每五分钟左右运行一个cron,以检查一个等待导入的队列 因此,您的用户登录时,登录过程的一部分是将它们添加到挂起的导入表中,或者以您选择的方

细节

当用户首次登录到我的应用程序时,我需要从API导入他们商店的所有产品,这可能是10种产品到11000种产品。因此,我认为我需要通知用户,我们将导入他们的产品,并在完成后向他们发送电子邮件

问题

在不要求用户停留在页面上的情况下,导入此数据的最佳方式是什么? 我应该走pcntl_岔路吗?
系统风格的后台任务会更好吗?

我认为在PHP中实现这一点的标准方法是每五分钟左右运行一个cron,以检查一个等待导入的队列


因此,您的用户登录时,登录过程的一部分是将它们添加到挂起的导入表中,或者以您选择的方式存储导入队列。然后,下次cron启动时,它将处理队列的当前内容。

我认为在PHP中执行此操作的标准方法是每五分钟左右运行一次cron,以检查一个等待导入的队列

因此,您的用户登录时,登录过程的一部分是将它们添加到挂起的导入表中,或者以您选择的方式存储导入队列。然后,下次cron启动时,它将处理您队列的当前内容。

AFAIK无法从web服务器进程进行pcntl_分叉,您只能从命令行执行此操作。但是,您可以使用exec或类似工具启动子进程,该子进程将在终止后继续运行

我不知道这有多正确,但我会这样做:

upload.php-让用户以您想要的任何格式上传他们的产品列表。我假设你知道如何做到这一点,不会包括任何代码-如果你想要一个例子,让我知道

store.php-上传表单提交到此文件:

// Make sure a file was uploaded and you have the user's ID
if (!isset($_FILES['file'],$_POST['userId']))
  exit('No file uploaded or bad user ID');

// Make sure the upload was successful
if ($_FILES['file']['error'])
  exit('File uploaded with error code '.$_FILES['file']['error']);

// Generate a temp name and store the file for processing
$tmpname = microtime(TRUE).'.tmp';
$tmppath = '/tmp/'; // ...or wherever you want to temporarily store the file
if (!move_uploaded_file($_FILES['file']['tmp_name'],$tmppath.$tmpname))
  exit('Could not store file for processing');

// Start an import process, then display a message to the user
// The ' > /dev/null &' is required here - it let's you start the process asynchronously
exec("php import.php \"{$_POST['userId']}\" \"$tmppath$tmpname\" > /dev/null &");

// On Windows you can do this to start an asynchronous process instead:
//$WshShell = new COM("WScript.Shell");
//$oExec = $WshShell->Run("php import.php \"{$_POST['userId']}\" \"$tmppath$tmpname\"", 0, false);

exit("I'm importing your data - I'll email you when I've done it");
import.php-处理导入并发送电子邮件

// Make sure the required command line arguments were passed and make sense
if (!isset($argv[1],$argv[2]) || !file_exists($argv[2])) {
  // handle improper calls here
}

// Connect to DB here and get user details based on the username (passed in $argv[1])

// Do the import (pseudocode-ish)
$wasSuccessful = parse_import_data($argv[2]);

if ($wasSuccessful) {
  // send the user an email
} else {
  // handle import errors here
}

// Delete the file
unlink($argv[2]);
这种方法的主要问题是,如果很多人同时上传要导入的列表,那么在同时运行多个import.php版本的情况下,您可能会面临系统资源紧张的风险

因此,按照Aaron Bruce的建议,安排一个cron作业一次导入一个列表可能会更好,但哪种方法最适合您将取决于您的具体需求。

如果无法从web服务器进程进行pcntl_分叉,则只能从命令行执行。但是,您可以使用exec或类似工具启动子进程,该子进程将在终止后继续运行

我不知道这有多正确,但我会这样做:

upload.php-让用户以您想要的任何格式上传他们的产品列表。我假设你知道如何做到这一点,不会包括任何代码-如果你想要一个例子,让我知道

store.php-上传表单提交到此文件:

// Make sure a file was uploaded and you have the user's ID
if (!isset($_FILES['file'],$_POST['userId']))
  exit('No file uploaded or bad user ID');

// Make sure the upload was successful
if ($_FILES['file']['error'])
  exit('File uploaded with error code '.$_FILES['file']['error']);

// Generate a temp name and store the file for processing
$tmpname = microtime(TRUE).'.tmp';
$tmppath = '/tmp/'; // ...or wherever you want to temporarily store the file
if (!move_uploaded_file($_FILES['file']['tmp_name'],$tmppath.$tmpname))
  exit('Could not store file for processing');

// Start an import process, then display a message to the user
// The ' > /dev/null &' is required here - it let's you start the process asynchronously
exec("php import.php \"{$_POST['userId']}\" \"$tmppath$tmpname\" > /dev/null &");

// On Windows you can do this to start an asynchronous process instead:
//$WshShell = new COM("WScript.Shell");
//$oExec = $WshShell->Run("php import.php \"{$_POST['userId']}\" \"$tmppath$tmpname\"", 0, false);

exit("I'm importing your data - I'll email you when I've done it");
import.php-处理导入并发送电子邮件

// Make sure the required command line arguments were passed and make sense
if (!isset($argv[1],$argv[2]) || !file_exists($argv[2])) {
  // handle improper calls here
}

// Connect to DB here and get user details based on the username (passed in $argv[1])

// Do the import (pseudocode-ish)
$wasSuccessful = parse_import_data($argv[2]);

if ($wasSuccessful) {
  // send the user an email
} else {
  // handle import errors here
}

// Delete the file
unlink($argv[2]);
这种方法的主要问题是,如果很多人同时上传要导入的列表,那么在同时运行多个import.php版本的情况下,您可能会面临系统资源紧张的风险

因此,按照Aaron Bruce的建议,安排一个cron作业一次导入一个列表可能会更好,但哪种方法最适合您将取决于您的精确需求