简体   繁体   English

PHP:使用Goto的正当理由?

[英]PHP: Valid Reason To Use Goto?

I know that the goto statement is frowned upon but I wanted to know if the following situation would make it the most acceptable. 我知道goto语句不被接受,但是我想知道以下情况是否会使它最容易接受。

I want to create a unique random number for a column value but to do that I need to create a random number and check to see if it exists in a table. 我想为列值创建一个唯一的随机数,但是要做到这一点,我需要创建一个随机数并检查表中是否存在该随机数。

a:
$rnumber = rand(1, 10);
$queryresult = $mysqli->query("SELECT uniquerandomcolumn FROM tbldata WHERE uniquerandomcolumn =" . $rnumber);

if ($queryresult->num_rows > 0) //if random number exists a row would be returned
{goto a;}  //try again
else {//insert into table}

请改用此号码,这样号码将是唯一的

$id = uniqid(rand(), true);

You don't need goto for that. 您不需要那么做。

do
{
    $rnumber = rand(1, 10);
    $queryresult = $mysqli->query("SELECT uniquerandomcolumn FROM tbldata WHERE uniquerandomcolumn =" . $rnumber);
}
while($queryresult->num_rows > 0);
//insert into table}

EDIT: This answer is just to prove that goto isn't necessary in the original code. 编辑:此答案只是为了证明原始代码中没有必要使用goto。 In this particular example, I would advise against using this code and use WereWolf - The Alpha's answer in your code. 在此特定示例中,我建议您不要使用此代码,而建议使用WereWolf-您代码中的Alpha答案。

Instead, you should use a while loop, that counts retry attempts: 相反,您应该使用while循环,该循环计入重试次数:

$attempt = 0; $success = false;
while ($attempt++ < 3) {
    // ... make sure $success gets marked true!
    // in case of success, make sure you break here!
}
if (!$success) {
    // Failure
}

This makes sure your script never freezes (infinite loop). 这样可以确保您的脚本永不冻结(无限循环)。

The goto statement was mainly - if any - used for error processing: in a long list of statement, each of them being able to trigger an error, a jump (goto) was made near the bottom of the function to skip all the remaining statements, and run a common error processor at the end of the function. goto语句主要(如果有的话)用于错误处理:在很长的语句列表中,每个语句都可以触发错误,在函数底部附近进行了跳转(转到)以跳过所有其余语句,然后在函数末尾运行一个常见的错误处理器。

But nowadays, even PHP has exception handling , thus the use of goto is even less justified. 但是如今,即使PHP都具有异常处理功能 ,因此使用goto的理由就更少了。

Fix the problem as mentioned 如前所述解决问题

In your case, you can implement a simple algorithm to perform the equivalent function 在您的情况下,您可以实现一个简单的算法来执行等效功能

do {
  $rnumber = rand(1, 10);
  $queryresult = $mysqli->query("SELECT uniquerandomcolumn FROM tbldata WHERE uniquerandomcolumn =" . $rnumber);

} while ($queryresult->num_rows > 0);

having the risk of being in an infinite (or very long) loop... 有陷入无限(或很长)循环的风险...

Room for improvement 有待改进

Since the number of tries is limited (1 .. 10), it would be better to 由于尝试次数有限(1 .. 10),因此最好

  • try all numbers from 1 to 10 (maximum) once without repetition 试着从1所有数字到10(最大)一次重复
  • randomly (eg 7 2 3 9 ...) 随机(例如7 2 3 9 ...)

ie, perform a maximum of 10 tries, and exit if the row does not exist or if all 10 tries have been done. 即, 最多执行10次尝试,如果该不存在或已完成10次尝试,则退出。 To try randomly from 1 to 10, use the shuffle function to shuffle randomly an array of 1 to 10 elements. 要随机尝试1到10,请使用随机播放功能随机随机播放1到10个元素的数组。

$tries = array();
for ($i=1 ; $i<=10 ; $i++) $tries[] = $i; // create an array (1,2,3,4,5...)

shuffle ($tries); // shuffle the array, eg now $tries is (8,2,9,1,7...)

$index = 0; // start with first element of $tries
do {
  $rnumber = $tries[$index++];
  $queryresult = $mysqli->query("SELECT uniquerandomcolumn FROM tbldata WHERE uniquerandomcolumn =" . $rnumber);

} while ($queryresult->num_rows > 0 && $tries < 10);

This way you try randomly all 10 possible values, not more. 这样,您将随机尝试所有10个可能的值,而不是更多。

After the while add 一会儿之后添加

if ($queryresult->num_rows < 1) {
  // found a non existing number: $tries[$index-1]
}
else {
  // all 10 numbers exist in the DB...
}

to deal with the two conditions. 处理两个条件。

goto isn't a good coding practice, it will make your code unaccountable and unmanageable. goto不是一个好的编码习惯,它将使您的代码无法解释和管理。 Don't ever use goto . 永远不要使用goto Or else a velociraptor will hit you while you compiling your code. 否则在您编译代码时,速激肽会击中您。

在此处输入图片说明

But it's okay if you are making a console application, it's okay. 但是,如果您正在制作控制台应用程序,那也没关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM