評価は悪です
まず第一に:eval()
を使用しないでください 正当な理由がない限り。 そして正当な理由はありません 。
最悪の場合、eval()
アプリケーションがインジェクション攻撃に対して脆弱になり、また非常に遅くなります。少し調べてみると、evalが大きなノーノーである理由がたくさん明らかになっています。
計算コードをデータベースに保存しないでください
そうして、PHPから別の言語に切り替えたい場合でも、データベースにはPHPコードがあります。言語の移行が非常に難しくなります。アプリケーションのできるだけ多くの部分をできるだけ独立させるように常に努力する必要があります。
この場合、使用する言語をデータベースに緊密に結合します。それは悪い習慣です。
また、データベースから計算を実行する唯一の可能性は、それらを評価するか(これは悪いです。上記を参照)、文字列操作または正規表現を使用して文字列を分解することです。これにより、不要な作業が発生します。
それはすべて戦略
に関するものです
問題を解決するには、必要な計算に応じてコードを実行する必要があります。これは、switch-case-statementsまたはif-statementsのいずれかを使用して実行できます。しかし、それはあまりエレガントな解決策でもありません。将来計算する前に他の操作を実行するか、機能を拡張する必要があると想像してください。すべてのケースまたはifステートメントを更新する必要があります。
戦略パターン と呼ばれる優れたデザインパターンがあります。 。戦略パターンは、1つのユースケースを異なる方法で処理できる場合に問題を解決します。これは、おそらくあなたが望むものです。
何かを計算したい(ユースケース)と、それにはさまざまな計算タイプがあります(さまざまな戦略)
仕組み
戦略パターンを実装するには、基本的に3つのものが必要です。
- 戦略を注入するクラス。これは基本的に、戦略タスクのラッパーです。
- 戦略によって実装されるインターフェース
- あなたの戦略
インターフェースは次のようになります:
<?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
を実装しています。 これは私たちのクラスに次のように伝えます:「ねえ!あなたはcalculateメソッドを提供しなければなりません、私はあなたが望むかどうかは気にしません。
これがパターンの不可欠な部分である理由は後でわかります。
したがって、実際の算術演算の実際のコードを含む2つの具象クラスがあります。必要に応じて、表示どおりに簡単に変更できます。操作を追加するには、別のクラスを追加するだけです。
次に、戦略を注入できるクラスを作成します。後で、このクラスのオブジェクトをインスタンス化して操作します。
外観は次のとおりです。
<?php
class Calculator {
protected $calculatable;
public function __construct( CalculatableInterface $calculatable )
{
$this->calculatable = $calculatable;
}
public function calculate()
{
return $this->calculatable->calculate();
}
}
ここで最も重要な部分はコンストラクターです。ここで、インターフェイスの入力方法を確認してください。そうすることで、オブジェクトのみを注入できるようにします(依存性注入 )そのクラスがインターフェースを実装している 。ここで具体的なクラスを要求する必要はありません。それがここでの重要なポイントです。
また、そこには計算方法があります。これは、calculateメソッドを実行するための戦略の単なるラッパーです。
まとめ
したがって、Calculator
のオブジェクトを作成する必要があります。 クラスを作成し、戦略クラスの1つのオブジェクト(算術演算のコードを含む)を渡します。
<?php
//The corresponding string is stored in your DB
$calculatable = 'Division';
$calc = new Calculator( new $calculatable(15, 100) );
echo $calc->calculate();
$calculatable
に保存されている文字列を置き換えてみてください Percentage
へ パーセンテージを計算するための操作が実行されることがわかります。
結論
戦略パターンにより、実行時にのみ具体化される動的タスクを操作するためのクリーンなインターフェイスを作成できました。データベースは、私たちがどのように計算するかを知る必要はなく、実際の計算機も知る必要はありません。確認する必要があるのは、インターフェースに対してコーディングすることだけです。 それは私たちが物事を計算できるようにする方法を提供します。