gpt4 book ai didi

php - 在代码或数据库中保存计算?

转载 作者:可可西里 更新时间:2023-11-01 08:32:53 24 4
gpt4 key购买 nike

我正在建立一个系统,它将对原始数据进行各种计算,并根据计算结果提供输出。
我的主要问题,是更多的建议,而不是如何去做。
使用mysql数据库,和php进行访问。
目前大约有200种不同的计算需要完成,但这些计算分为4种类型,即一种计算类型是x除以y,而不同的计算将是x或y的不同原始值。
系统需要在系统的不同部分执行不同的计算,因此我创建了一个函数来执行计算。目前我有实际计算的代码(有一点错误处理)保存在数据库中,如下所示;

**calc_id** | **calc_code**
aDIVb | if($primBVal != 0){ $result = ($primAVal / $primBVal);} else {$result = 'NA';}
aPERCb | if($primBVal != 0){ $result = (100 / $primBVal) * $primAVal;} else {$result = 'NA';}

等。
然后在php中使用 eval( $calcArray['calc_code']);
计算这些值。
这四种计算方法永远不会改变,尽管将来可能会增加更多。
问题是,我应该将这段代码构建到php函数中,还是保持原样留在数据库中?基于可能会添加更多的内容,我倾向于使用数据库,因为我可以在中添加新行来处理新的计算类型,而不必编辑任何代码。
希望这一切都是有意义的,为这个冗长的问题道歉,并且可能是错误的格式。
提前谢谢。

最佳答案

eval是邪恶的
首先:除非有充分的理由,否则不要使用eval()。从来没有一个好的理由。
在最坏的情况下,eval()会使您的应用程序容易受到注入攻击,而且速度非常慢。一些研究揭示了很多原因,为什么eval是一个很大的不-不。
不要将计算代码保存到数据库中
如果这样做,并且希望从php切换到另一种语言,那么数据库中仍会有php代码。这使得迁移语言变得非常困难。您应该始终努力使应用程序的许多部分尽可能独立。
在这种情况下,您可以将使用的语言与数据库紧密结合起来。那是一种不好的做法。
另外,从数据库运行计算的唯一可能是对它们进行求值(这是不好的,请参见上文),或者使用字符串操作或正则表达式反汇编字符串,这会导致不必要的工作。
都是关于Strategy
为了解决您的问题,您必须执行依赖于所需计算的代码。这可以通过switch case语句或if语句完成。但这也不是一个非常优雅的解决方案。假设在将来进行计算之前需要执行其他操作,或者扩展功能。您需要更新所有案例或if语句。
有一个很好的设计模式叫做Strategy Pattern。当一个用例可以以不同的方式处理时,策略模式可以解决问题,这可能是您想要的。
你想计算一些东西(用例),它有不同的计算类型(不同的策略)
工作原理
要实现战略模式,基本上需要三件事。
一个你注入你的策略的类。它基本上是你的策略任务的包装。
将由您的策略实现的接口
你的策略
您的界面可能如下所示:

<?php
interface CalculatableInterface {

public function calculate();

}

界面将确保所有策略都提供了一个实际运行计算的方法。没什么特别的。
接下来,您可能需要一个基类,它将计算运算符作为构造函数参数并将它们存储到属性中。
<?php
abstract class Calculatable {

protected $valueA;
protected $valueB;

public function __construct($valueA, $valueB)
{
$this->valueA = $valueA;
$this->valueB = $valueB;
}

}

现在情况越来越严重了。我们正在执行我们的战略。
<?php
class Division extends Calculatable implements CalculatableInterface {

public function calculate()
{
return ($this->valueB != 0) ? $this->valueA / $this->valueB : 'NA';
}

}

class Percentage extends Calculatable implements CalculatableInterface {

public function calculate()
{
return ($this->valueB != 0) ? (100 / $this->valueB) * $this->valueA : 'NA';
}

}

当然你可以把这个清理一下,但是我想指出的是类声明。
我们正在扩展我们的 Calculatable类,以便通过构造函数传递算术操作,我们正在实现 CalculatableInterface,它告诉我们的类:“嘿!你必须提供一个计算方法,我不管你是否愿意。
我们稍后会看到为什么这是模式的一个组成部分。
所以我们有两个具体的类,包含实际算术运算的实际代码。如果你需要的话,你可以很容易地改变它。
要添加更多操作,只需添加另一个类。
现在我们将创建一个可以注入我们的策略的类。稍后,您将实例化这个类的一个对象并使用它。
下面是它的样子:
<?php 
class Calculator {

protected $calculatable;

public function __construct( CalculatableInterface $calculatable )
{
$this->calculatable = $calculatable;
}

public function calculate()
{
return $this->calculatable->calculate();
}

}

这里最重要的部分是构造函数。看看我们如何在这里输入提示界面。通过这样做,我们确保只能注入其类实现接口的对象( Dependency Injection)。我们这里不需要具体的课程。这是关键的一点。
还有一种计算方法。它只是我们执行计算方法的策略的包装器。
把它包起来
所以现在我们只需要创建一个 Calculator类的对象,并传递一个策略类的对象(包含算术运算的代码)。
<?php
//The corresponding string is stored in your DB
$calculatable = 'Division';

$calc = new Calculator( new $calculatable(15, 100) );
echo $calc->calculate();

尝试将 $calculatable中存储的字符串替换为 Percentage,您将看到计算百分比的操作将被执行。
结论
策略模式允许您创建一个干净的接口,用于处理仅在运行时具体化的动态任务。你的数据库不需要知道我们是如何计算的,你的实际计算器也不需要知道。我们唯一需要确保的是针对一个接口编写代码,该接口提供了一个方法,让我们计算东西。

关于php - 在代码或数据库中保存计算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22249833/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com