Logo

Über den Umgang mit physikalischen Werten in PHP

„Ein wahrhaft großer Mensch verliert nie die Einfachheit eines Kindes.“ - Konfuzius

Physikalische Größen

Eine physikalische Größe ist eine allgemeine Eigenschaft, mit der wir die Welt und die Objekte in ihr beschreiben. Die Länge eines Gegenstands ist zum Beispiel eine physikalische Größe.

Die Länge eines Gegenstandes kann in Meter, Kilometer, Meile oder Ångström angegeben werden. Diese Einheiten sind alles Einheiten für die Größe „Länge“. Wir schreiben es dann so: A = {A} [A]. A ist das Symbol der Größe, {A} ist der Zahlenwert von A und [A] steht für die Einheit von A. Ein Beispiel einer Länge: L = 7 m

Damit wir alle die gleichen Einheiten verwenden, hat man das Système international d’unités geschaffen. Das Internationale Einheitensystem oder kurz SI definiert für alle Größen standardisierte Einheiten. Seit 2019 sind alle Größen über Naturkonstanten definiert.

Rechnen mit Einheiten

Schauen wir uns ein Beispiel an: Ein Papierstreifen hat die Form eines Rechtecks mit den Seitenlängen a = 30 cm und b = 2 m.

Rechteck mit Beamßung

Wir wollen nun den Umfang und die Fläche des Papierstreifens berechnen. Fangen wir mit dem Umfang an. Zuerst müssen wir die Seitenlängen auf eine gemeinsame Einheit bringen. Wir wählen als Einheit Zentimeter. Damit ergeben sich die Länge a = 30 cm und für b = 200 cm.

U = 2 × (a + b) = 2 × (30 cm + 200 cm) = 2 × 230 cm = 460 cm

Die Fläche berechnen wir mit

F = a × b = 30 cm × 200 cm = 6000 cm²

In PHP kann man die Formel einfach über die Zahlenwerte abbilden und folgendes schreiben:


$a=30;
$b=200;

// Umfang
$u=2*($a+$b);

echo $u." cm";
// 460 cm

// Fläche
$u=$a*$b;

echo $u." cm²";
// 6000 cm²


    

Ein Nachteil dieser Methode ist die fehlende Einheit. Wir wissen zwar per Definition, dass wir mit cm arbeiten, aber können wir uns darauf verlassen? Besser wäre es eine Klasse mit Einheit und Zahlenwert zu definieren. Ein einfaches Beispiel könnte folgendermaßen aussehen:


class Length {

    public $amount;
    public $unit;

    public function __construct(float $amount, string $unit) {
        $this->amount=$amount;
        $this->unit=$unit;
    }

}

$a=new Length(30, 'cm');
$a=new Length(2, 'm');

    

Genau das haben wir in unserem PHP-Framework gemacht. Wir haben Klassen für den Umgang mit physikalische Größen definiert. Die komplette Dokumentation zum Alvine PHP-Framework findet man in unserem Dokumentations-Portal . Das Framework selber kann auf der Downloadseite heruntergeladen werden.

Die Struktur der Klassen ist wie im folgenden UML-Diagramm. Im wesentlichen gibt es Klassen für die Einheiten Alvine\Measure\Unit, die Zahlenwerte Alvine\Measure\Amount, die Dimension Alvine\Measure\Dimension und für das Einheitensystem Alvine\Measure\SystemOfUnits.

UML-Diagramm

Das Einheitensystem definiert den Zusammenhang und die Umrechnung zwischen den einzelnen Einheiten. Es gibt zum Beispiel ein System für alle SI-Einheiten. Unter einer Dimension versteht man zum Beispiel alle Einheiten die zur Bestimmung einer Länge verwendet werden können. So gehören km, m, cm, miles zur Dimension Länge und kg, gr zur Dimension Gewicht.

Kommen wir jetzt zu unserem Beispiel zurück. Eine Größe wird über \Alvine\Measure\Amount::valueOf($number, $unit) definiert. Die Variable $number kann entweder vom Typ int oder float sein.

Für die meisten SI-Einheiten gibt es in der Klasse \Alvine\Measure\SI eine Hilfsmethode. So kann eine Instanz der Einheit Zentimeter über die Methode \Alvine\Measure\SI::centimeter() geholt werden.

Um eine Einheit umzurechnen, kann man die Methode \Alvine\Measure\Amount::to($unit) verwenden. In unserem Beispiel rechnen wir Meter in Zentimeter um.

Für die Addition der beiden Werte verwenden wir die Methode \Alvine\Measure\Amount::plus($amount) und für das Multiplizieren die Methode \Alvine\Measure\Amount::times($factor).


// Definition der Längen
$a=\Alvine\Measure\Amount::valueOf(30, \Alvine\Measure\SI::centimeter());
$b=\Alvine\Measure\Amount::valueOf(2, \Alvine\Measure\SI::meter())->to(\Alvine\Measure\SI::centimeter());

echo $a;
// 30 cm
echo $b;
// 2 m

echo (string) $a->plus($b)->times(2);
// (460.0000000000000000 ± 0.0) cm

echo (string) $a->times($b);
// 6000 cm²

    

Die Ausgabe des Umfangs sieht nicht schön aus. Hier kann man den UnitFormatter verwenden und alle Aspekte der Ausgabe steuern.


$formatter=\Alvine\Measure\Formatter\AmountFormatter::getDefaultFormatter()
    ->setFloatFormat('%amount$s %unit$s')
    ->setDecimalPoint(',')
    ->setPresicion(2);


echo $formatter->format($a->plus($b)->times(2));
// 460,00 cm

    

Zum Einheitensystem gehört auch das Rechnen mit Geldbeträgen und Währungen. Außerdem finden sich weitere Beispiel in der Dokumentation zum Framework.

Wie finden Sie diesen Ansatz?
Zusätzliche Schlüsselwörter und Phrasen: Physik, Meßwert, Stadardeinheit, Dimension