将大型脚本处理传递给另一个脚本

Most serious developers often face larger projects where user forms take a long time to process, leaving the user wondering what is happening and often clicking the submit button more than once. This article is not to show you how to disable the submit button once clicked or to show a spinner or progress bar. I will show you how to let another script do all the work while your form gets an almost instant response back from the server, allowing the user to continue interacting with your website. I will also show you how to have your form "checkup" on the external process so you can show a real time progress bar (or spinner).

大多数认真的开发人员经常面对较大的项目,在这些项目中用户表单需要花费很长时间来处理,从而使用户不知道发生了什么,并且经常多次单击“提交”按钮。 本文不是为了向您展示单击后如何禁用“提交”按钮,也不是为了显示微调框或进度条。 我将向您展示如何让另一个脚本完成所有工作,同时您的表单几乎可以立即从服务器返回响应,从而允许用户继续与您的网站进行交互。 我还将向您展示如何在外部流程上进行表单“检查”,以便您可以显示实时进度栏(或微调器)。

If you have ever had a form that takes more than a few seconds to process then this article is for you. Although I am focusing on PHP, the general idea should work for any other scripting language.

如果您曾经处理过几秒钟的表格,那么本文适合您。 尽管我专注于PHP,但总体思路应适用于任何其他脚本语言。

Recently I had to write a script that took a rather large user form and processed it, interacting with a database and calling an outside public API to register items on another website as well as on the local website local website meaning your online (www.yoursite.com) website. Unfortunately the public API of the company in question was very slow to respond. Asking them if they could speed up their API got no response so I came up with a better way not to leave my users hanging.

最近,我不得不编写一个脚本,该脚本采用了相当大的用户形式并进行了处理,与数据库进行了交互,并调用了外部公共API来在另一个网站以及本地网站本地网站上注册项目,这意味着您在线( www.yoursite .com )网站。 不幸的是,相关公司的公共API响应速度很慢。 询问他们是否可以加快其API的响应没有得到任何响应,因此我想出了一种更好的方法,可以让用户不挂机。

This process will work whether you are using a public API on another website or doing all local database stuff. Here is what I did.

无论您是在另一个网站上使用公共API还是进行所有本地数据库操作,此过程都将起作用。 这是我所做的。

Initially my user form submitted all the form data to a processing script which took care of all the local database stuff and did the 60 plus, API calls, and dealt with the responses. If it made it all the way to the end it would send a response back to the user form with an error message number (0 for success).

最初,我的用户表单将所有表单数据提交给处理脚本,该脚本负责处理所有本地数据库内容,并执行60多个API调用,并处理响应。 如果一直进行到最后,它将以错误消息号(成功为0)发送回用户表单。

From the time the user clicked the submit button to the time they got notification of success, they had been waiting just over 1 minute.  This was unacceptable to me and simply disabling the submit button and showing a spinner was not good enough.

从用户单击“提交”按钮到收到成功通知的时间,他们一直在等待超过1分钟。 这对我来说是不可接受的,仅禁用提交按钮并显示微调器还不够好。

HOW IT WORKS:

这个怎么运作:

Nothing in your form changes. The change happens in the processing script. The first part of the script was to register the new user on the websites database (our website not the public API's website). This was done in the usual way making SQL insert statements and entering in the users details. This script then needs to get the new userid and send it back to the form. You will need this userid in order to call the real processing script.

您的表单没有任何变化。 更改发生在处理脚本中。 脚本的第一部分是在网站数据库(我们的网站而不是公共API的网站)上注册新用户。 这是通过创建SQL插入语句并输入用户详细信息的常规方法完成的。 然后,此脚本需要获取新的用户ID,并将其发送回表单。 您将需要此用户ID才能调用实际的处理脚本。

So now you insert the user sent data into the database and retrieve the new userid.

因此,现在您将用户发送的数据插入数据库,并检索新的用户ID。

As soon as you get a userid returned you need to create a master results array to store all the information. So the master_results looked something like this to start with.

一旦返回用户ID,就需要创建一个主结果数组来存储所有信息。 所以master_results看起来像这样。

<?php

// Current Step variable - available to all functions/methods
$current_step = 1;

// Master results array needs to be available to all public and private functions/methods

$master_results = array(
'total_steps' => 20,
'current_step' => $current_step,
'userid' => $userid
);

// Remember we already have the new userid.

// Json encode the results.
$json = json_encode($master_result<wbr ></wbr>s);

// Save the results string into your database so other functions/methods can retrieve and update it.

mysql_query("INSERT INTO user_data (data) VALUES ('$json')") or die(mysql_error());

// I also updated a field I labeled 'updatedon' with the current date/time so I could use that later for other functions but this is not required.
?>

PASSING OFF:

通过:

The final step to do is to PASS OFF the rest of the work to another script to finish off the job. To call another script is as simple as doing a shell command passing the path, filename and any arguments you need to send. In my case, I only needed the userid so here is my call.

最后要做的步骤是将其余工作传递给另一个脚本以完成工作。 调用另一个脚本就像执行shell命令一样简单,它会传递路径,文件名和您需要发送的所有参数。 就我而言,我只需要用户名,所以这是我的电话。

To learn more about the exec() command go here exec()

要了解有关exec()命令的更多信息,请转到此处exec()

Assuming the process.php file is in the same folder as the current script. If not, then add the path to the call.

假设process.php文件与当前脚本位于同一文件夹中。 如果不是,则将路径添加到呼叫中。

$pid = exec('php process.php '.$userid.' > /dev/null 2>&1 & echo $!');

if (!$pid) {
    // error here
} else {
    // We are done so this script should return the userid so we can use it for "CHECKUP"
    echo $userid;
}

CHECKUP:

检查:

The checkup is a simple process. The only thing you need to pass to it is the userid which was created in step 1 in my case. The first job to do is get the user data information (json string) and decode it back into an array so you can checkup on the progress.

核对是一个简单的过程。 您需要传递给它的唯一东西是本例中在步骤1中创建的userid。 首先要做的是获取用户数据信息(json字符串)并将其解码回数组,以便您可以检查进度。

<?php // checkup.php
// Get the user data

$json = mysql_query("SELECT data FROM user_data WHERE userid = '$userid' LIMIT 1") or die(mysql_error());

if (!$json) {
     // return an error code here
     echo 1;
}

// We got the results so decode them into an array.

$master_results = json_decode($json, true);
// If you add the 'true' argument you will get an array instead of an object returned.

// Get the step information from the results array and do some simple math to determine how far the script has gotten.

// Total steps
if (!isset($master_results['total_steps'])) {
      // error here
} else { 
    $total_steps = $master_results['total_steps'];
}

// Current step
if (!isset($master_results['current_step'])) {
      // error here
} else { 
    $current_step = $master_results['current_step'];
}

// NOTE: you don't have to assign these values to a variable if you only need to use them once. You can just operate directly with the master_results['total_steps'] etc...

// Do the math
$percent_complete = $current_step / $total_steps;

// Return the result
echo round($percent_complete);

// you could round this number if you prefer or do it in javascript it really doesn't matter. I usually round it
?>

So ajax will call "checkup.php?userid=" and the userid returned from the first form submit and it will get back the percent complete of the entire process.

因此,ajax将调用“ checkup.php?userid =“,并且从第一个表单提交返回的用户ID将返回整个过程的完成百分比。

LAST STEP:

最后一步:

This step is the process.php where all the work is done in the background (independent of your user form or the initial script which has now completed and returned the userid).

此步骤是process.php,其中所有工作均在后台完成(与您的用户表单或已完成并返回userid的初始脚本无关)。

It is important to note that in order to do a checkup of progress, each step involved in the processing script needs to update the database with it's current step number as we did in the initial script. Firstly though, we need to get the results back from the database and decode them just like we did in CHECKUP so we have the current step number. I won't bother repeating the code as it is already written above.

重要的是要注意,为了进行进度检查,处理脚本中涉及的每个步骤都需要像在初始脚本中一样使用当前步骤号来更新数据库。 但是首先,我们需要从数据库中获取结果并像在CHECKUP中一样对它们进行解码,以便获得当前的步骤号。 我不会重复上面已经写过的代码。

This process script will be called through the "exec()" command in the previous script and it is passed at least 1 argument. In my case it was the userid. So we need to retrieve it inside the script. For this we use $argv which is a built in PHP array similar to $_POST and $_GET. You can read up on $argv HERE

该过程脚本将通过上一个脚本中的“ exec()”命令调用,并至少传递一个参数。 就我而言,它是用户名。 因此,我们需要在脚本中检索它。 为此,我们使用$ argv,它是类似于$ _POST和$ _GET的内置PHP数组。 您可以在此处阅读$ argv

To get the first argument we passed to this script it will always reside in $agv[1];

为了获得我们传递给该脚本的第一个参数,它将始终驻留在$ agv [1];中。

$argv[0] holds the script name (process.php);

$ argv [0]保存脚本名称(process.php);

$userid = $argv[1]; // There it is.

$ userid = $ argv [1]; //有。

So now you can retrieve the users data from the database as we have the userid.

因此,现在有了用户标识,您就可以从数据库中检索用户数据。

All your functions/methods will go in here and after each stage/step is complete, you must increment $current_step and place it back into the $master_results array and re-encode it to a json string, then save it back to the database.

您的所有函数/方法都将放在此处,并且在完成每个阶段/步骤之后,必须递增$ current_step并将其放回到$ master_results数组中,并将其重新编码为json字符串,然后将其保存回数据库。

In my case, I had some 40 private methods and handful of public methods that took care of all the external API calls, each one returning an id for that item, which I would record back into my database via the $master_results array.

就我而言,我有大约40个私有方法和一些公共方法来处理所有外部API调用,每个方法都返回该项目的ID,我将通过$ master_results数组将其记录回数据库中。

It is important to note here that this process.php must not return anything to the screen as no one is watching it run. No echo or print statements are required. Just get the job done and if an error occurs, error_log('Place your error notice in here so you can view it later') or something along those lines. This script will get to the end (if no errors along the way) and just finish with no output.

重要的是在这里要注意,此process.php不得将任何内容返回屏幕,因为没有人看着它运行。 不需要回显或打印语句。 只需完成工作,如果发生错误,请使用error_log('将您的错误通知放在此处,以便稍后查看')或类似的内容。 该脚本将结束(如果在执行过程中没有错误),并且最后没有任何输出。

So that is it in a nutshell.

简而言之就是这样。

SUMMARY:

摘要:

This article is designed to show you how to pass off a slow running form due to the amount of work it is doing, to another script which does all the work. It also shows you how to do a checkup on that process in case you want to have a progress bar or similar on your webpage. If the progress bar or checkup is not required, there is no need to record the steps into the database so you can ignore those parts. The main thing is to know how to pass off or call another script from the main script and that is done with exec() command in PHP. In other scripting languages there will be a similar shell command to call files but that is beyond the scope of this article.

本文旨在向您展示如何将慢速运行的表单传递给另一个完成所有工作的脚本,该表单由于工作量大而已。 它还显示了您如何在该进程上进行检查,以防您想要在网页上显示进度条或类似内容。 如果不需要进度条或检查,则无需将步骤记录到数据库中,因此可以忽略这些部分。 最主要的是要知道如何通过主脚本传递或调用另一个脚本,而这是通过PHP中的exec()命令完成的。 在其他脚本语言中,将有一个类似的shell命令来调用文件,但这超出了本文的范围。

I hope this will prove to be helpful to the many developers who find themselves in this predicament. I will be happy to elaborate on any part of this if you don't understand it.

我希望这将证明对陷入困境的许多开发人员有所帮助。 如果您不了解,我将很乐意对此进行详细说明。

Regards

问候

Mark (elvin66)

马克(elvin66)

翻译自: https://www.experts-exchange.com/articles/10449/Passing-off-large-script-processing-to-another-script.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值