Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zapisz obliczenia w kodzie lub bazie danych?

Eval jest zły

Po pierwsze:nie używaj eval() chyba że istnieje dobry powód. I nigdy nie ma dobrego powodu .

w najgorszym przypadku eval() sprawia, że ​​Twoja aplikacja jest podatna na ataki wstrzykiwania, a także jest bardzo powolna. Trochę badań ujawnia wiele powodów, dla których ewaluacja jest wielkim nie-nie.

Nie zapisuj swojego kodu obliczeniowego w bazie danych

Jeśli to zrobisz i chcesz przełączyć się z PHP na inny język, nadal będziesz mieć kod PHP w swojej bazie danych. To bardzo utrudnia migrację języków. Zawsze powinieneś starać się, aby jak najwięcej części swojej aplikacji było jak najbardziej niezależnych.

W takim przypadku należy ściśle powiązać używany język z bazą danych. To zła praktyka.

Jedyną możliwością uruchomienia obliczeń z bazy danych byłoby również ich oszacowanie (co jest złe, patrz wyżej) lub rozłożenie łańcucha za pomocą operacji na łańcuchu lub wyrażenia regularnego, co powoduje niepotrzebny wysiłek.

Chodzi o Strategię

Aby rozwiązać swój problem, musisz wykonać kod zależny od potrzebnych obliczeń. Można to zrobić za pomocą instrukcji switch-case-statements lub if-statements. Ale to też nie jest zbyt eleganckie rozwiązanie. Wyobraź sobie, że musisz wykonać inne operacje przed obliczeniami w przyszłości lub rozszerzyć funkcjonalność. Będziesz musiał zaktualizować wszystkie swoje przypadki lub oświadczenia warunkowe.

Istnieje ładny wzór projektu, który nazywa się Wzorzec strategii . Wzorzec strategii rozwiązuje problemy, gdy jeden przypadek użycia może być obsłużony inaczej, co prawdopodobnie jest tym, czego chcesz.

Chcesz coś obliczyć (przypadek użycia) i istnieją różne typy obliczeń (różne strategie)

Jak to działa

Aby zaimplementować wzorzec Strategia, potrzebujesz trzech rzeczy.

  • Zajęcia, w których wprowadzasz swoje strategie. To w zasadzie opakowanie dla twoich zadań strategicznych.
  • Interfejs, który zostanie zaimplementowany przez Twoje strategie
  • Twoje strategie

Twój interfejs może wyglądać tak:

<?php
interface CalculatableInterface {
    
    public function calculate();

}

Interfejs zapewni, że wszystkie Twoje strategie zapewnią metodę rzeczywistego przeprowadzenia obliczeń. Nic specjalnego.

Następnie możesz chcieć mieć klasę bazową, która pobiera operatory obliczeń jako argumenty konstruktorów i przechowuje je we właściwościach.

<?php
abstract class Calculatable {

    protected $valueA;
    protected $valueB;

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

}

Teraz robi się poważnie. Wdrażamy nasze strategie.

<?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';
    }

}

Oczywiście możesz to trochę posprzątać, ale chciałbym tutaj zwrócić uwagę na deklarację klasy.

Rozszerzamy naszą Calculatable klasy, dzięki czemu możemy przekazać operacje arytmetyczne przez konstruktor i implementujemy CalculatableInterface który mówi naszej klasie:„Hej! Musisz podać metodę obliczania, nie obchodzi mnie, czy chcesz, czy nie.

Zobaczymy później, dlaczego jest to integralna część wzorca.

Mamy więc dwie konkretne klasy, które zawierają rzeczywisty kod dla rzeczywistej operacji arytmetycznej. Jeśli kiedykolwiek będziesz potrzebować, możesz to łatwo zmienić, jak widzisz.Aby dodać więcej operacji, po prostu dodaj kolejną klasę.

Teraz stworzymy klasę, do której będziemy mogli wstrzykiwać nasze strategie. Później utworzysz instancję obiektu tej klasy i będziesz z nim pracować.

Oto jak to wygląda:

<?php 
class Calculator {

    protected $calculatable;

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

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

}

Najważniejszą częścią jest tutaj konstruktor. Zobacz, jak piszemy w naszym interfejsie tutaj. Robiąc to, upewniamy się, że tylko obiekt może zostać wstrzyknięty (Wstrzykiwanie zależności ), którego klasa implementuje interfejs . Nie potrzebujemy tutaj konkretnej klasy. To jest tutaj kluczowy punkt.

Jest tam również metoda obliczeniowa. To tylko opakowanie dla naszej strategii, aby wykonać metodę obliczeniową.

Zawijanie

Więc teraz musimy tylko stworzyć obiekt naszego Calculator i przekazać obiekt jednej z naszych klas strategii (zawierających kod dla operacji arytmetycznych).

<?php
//The corresponding string is stored in your DB
$calculatable = 'Division';

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

Spróbuj zastąpić ciąg przechowywany w $calculatable na Percentage i zobaczysz, że operacja obliczania wartości procentowej zostanie wykonana.

Wniosek

Wzorzec strategii umożliwił stworzenie przejrzystego interfejsu do pracy z zadaniami dynamicznymi, które są skonkretyzowane tylko w czasie wykonywania. Ani Twoja baza danych nie musi wiedzieć, jak obliczamy rzeczy, ani Twój rzeczywisty kalkulator. Jedyne, czego musimy się upewnić, to kodowanie w interfejsie która zapewnia metodę pozwalającą nam obliczyć rzeczy.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przekaż tablicę PHP przez jQuery Ajax

  2. Jak znaleźć wiersze z równymi kolumnami?

  3. Konfiguracja Spring Boot Docker i Mysql

  4. Indeksy wielojęzyczne z Laravel Scout i Algolia

  5. Czy jest jakiś powód, aby nadal używać wielkości węża do tabel i kolumn bazy danych?