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