Ein Mitarbeiter hat den Befehl assert einige Male in unseren Bibliotheken an Stellen hinzugefügt, an denen ich eine if-Anweisung verwendet und eine Ausnahme ausgelöst hätte. (Ich hatte vorher noch nie davon gehört.) Hier ist ein Beispiel, wie er es benutzt hat:
assert('isset($this->records); /* Records must be set before this is called. */');
Ich hätte es getan:
if (!isset($this->records)) {
throw new Exception('Records must be set before this is called');
}
Nach dem Lesen der PHP-Dokumente zu assert wird empfohlen, sicherzustellen, dass assert aktiv ist, und einen Handler hinzuzufügen, bevor Sie assert verwenden. Ich kann keinen Ort finden, an dem er das getan hat.
Meine Frage ist also, ob die Verwendung von assert angesichts der obigen Ausführungen eine gute Idee ist und ob ich sie häufiger verwenden sollte, anstatt ob und Ausnahmen?
Ein weiterer Hinweis: Wir planen, diese Bibliotheken für eine Vielzahl von Projekten und Servern zu verwenden, einschließlich Projekten, an denen wir möglicherweise nicht einmal beteiligt sind (die Bibliotheken sind Open Source). Macht dies einen Unterschied bei der Verwendung von assert?
'isset
(die Codezeile mitassert
)? Nicht nurisset
(ohne das einfache Anführungszeichen'
)?Antworten:
Die Faustregel, die für die meisten Sprachen gilt (alles, was ich vage weiß), lautet, dass eine
assert
verwendet wird, um zu behaupten, dass eine Bedingung immer wahr ist, während eineif
angemessen ist, wenn es denkbar ist, dass sie manchmal fehlschlägt.In diesem Fall würde ich sagen, dass dies
assert
angemessen ist (basierend auf meinem schwachen Verständnis der Situation), darecords
es immer festgelegt werden sollte, bevor die angegebene Methode aufgerufen wird. Ein Fehler beim Festlegen des Datensatzes wäre also eher ein Fehler im Programm als eine Laufzeitbedingung. Hierassert
hilft das sicherzustellen (mit angemessenen Tests), dass es keinen möglichen Programmausführungspfad gibt, der dazu führen könnte, dass der Code, der mit dem geschützt wirdassert
, aufgerufen wird, ohnerecords
festgelegt worden zu sein.Der Vorteil der Verwendung
assert
im Gegensatz zuif
ist, dassassert
sie im Produktionscode im Allgemeinen deaktiviert werden kann, wodurch der Overhead reduziert wird. Die Art von Situationen, mit denen am besten umgegangen werden kann,if
kann möglicherweise zur Laufzeit im Produktionssystem auftreten, sodass nichts verloren geht, wenn sie nicht ausgeschaltet werden können.quelle
assert_options(ASSERT_BAIL)
. Es ist sowieso schneller als manuelle Problemumgehungen.Stellen Sie sich Behauptungen als "Machtkommentare" vor. Anstelle eines Kommentars wie:
verwenden:
Die Bedeutungen sind genau gleich und für genau das gleiche Publikum bestimmt, aber der erste Kommentar kann leicht vergessen oder ignoriert werden (egal wie viele Ausrufezeichen), während der "Machtkommentar" nicht nur für Menschen zum Lesen und Verstehen verfügbar ist. Es wird auch während der Entwicklung ständig maschinell getestet und nicht ignoriert, wenn Sie eine gute Assert-Behandlung im Code und in den Arbeitsgewohnheiten einrichten.
So gesehen sind Asserts ein völlig anderes Konzept als if (error) ... und Ausnahmen, und sie können nebeneinander existieren.
Ja, Sie sollten Ihren Code kommentieren, und ja, Sie sollten nach Möglichkeit "Power-Kommentare" (Asserts) verwenden.
quelle
Es hängt ganz von Ihrer Entwicklungsstrategie ab. Die meisten Entwickler kennen
assert()
und verwenden Downstream-Unit-Tests nicht. Proaktive und integrierte Testschemata können jedoch manchmal vorteilhaft sein.assert ist nützlich, da es aktiviert und deaktiviert werden kann. Die Leistung wird nicht beeinträchtigt, wenn kein solcher Assertion-Handler definiert ist. Ihr Kollege hat keinen, und Sie sollten einen Code entwickeln, der ihn vorübergehend in der Entwicklungsumgebung aktiviert (wenn E_NOTICE / E_WARNINGs aktiviert sind, sollte dies auch der Assertion-Handler sein). Ich benutze es gelegentlich, wenn mein Code gemischte Variablentypen nicht ertragen kann - ich schreibe normalerweise nicht streng in einem schwach typisierten PHP, aber es gibt zufällige Anwendungsfälle:
Dies würde beispielsweise das Fehlen von Typspezifizierern ausgleichen
string $a, array $b
. PHP5.4 wird sie unterstützen, aber nicht überprüfen.quelle
Assert ist kein Ersatz für normale Flusskontrollen
if
oder Ausnahmen, da es nur zum Debuggen während der Entwicklung verwendet werden soll.quelle
Ein wichtiger Hinweis zum Assert in PHP vor 7. Im Gegensatz zu anderen Sprachen mit einem Assert-Konstrukt wirft PHP Assert-Anweisungen nicht vollständig aus - es behandelt sie als Funktion (do debug_backtrace () in einer Funktion, die von einer Assertion aufgerufen wird). Das Ausschalten von Asserts scheint die Funktion nur dazu zu verdrahten, nichts im Motor zu tun. Beachten Sie, dass PHP 7 dieses Verhalten emulieren kann, indem zend.assertions auf 0 gesetzt wird, anstatt auf die normaleren Werte 1 (ein) oder -1 (aus).
Das Problem tritt darin auf, dass assert ein beliebiges Argument akzeptiert. Wenn das Argument jedoch keine Zeichenfolge ist, erhält assert die Ergebnisse des Ausdrucks, unabhängig davon, ob assert aktiviert oder deaktiviert ist. Sie können dies mit dem folgenden Codeblock überprüfen.
In Anbetracht der Absicht, dies zu behaupten, handelt es sich um einen Fehler, der seit langem in der Sprache ist, seit Assert in PHP 4 eingeführt wurde.
An Assert übergebene Zeichenfolgen werden mit allen damit verbundenen Auswirkungen auf die Leistung und den damit verbundenen Risiken bewertet. Dies ist jedoch die einzige Möglichkeit, Assert-Anweisungen so zu verwenden, wie sie in PHP funktionieren sollten (dieses Verhalten ist in PHP 7.2 veraltet).
BEARBEITEN: Oben geändert, um Änderungen in PHP 7 und 7.2 zu beachten
quelle
zend.assertions
Ini-Einstellung, um sie vollständig auszuschaltenassert()
.Assert sollte nur in der Entwicklung verwendet werden, da es für das Debuggen nützlich ist. Wenn Sie möchten, können Sie sie für die Entwicklung Ihrer Website verwenden. Sie sollten jedoch Ausnahmen für eine Live-Website verwenden.
quelle
Nein, Ihr Mitarbeiter sollte es nicht als allgemeine Fehlerbehandlungsroutine verwenden. Nach dem Handbuch:
Wenn Sie mit automatisierten Testsuiten vertraut sind, wird im Allgemeinen das Verb "assert" verwendet, um die Ausgabe einer Methode oder Funktion zu überprüfen. Beispielsweise:
Ihr Mitarbeiter sollte es nicht als allgemeine Fehlerbehandlungsroutine und in diesem Fall als Eingabeprüfung verwenden. Es sieht so aus, als ob das Datensatzfeld möglicherweise nicht von einem Benutzer Ihrer Bibliothek festgelegt wurde.
quelle
Ihr Mitarbeiter versucht wirklich, Design by Contract (DbC) aus der Eiffel-Sprache anzuwenden und basiert auf dem Buch: Object Oriented Software Construction, 2nd Edition.
Die Behauptung, wie er sie benutzte, wäre der {P} -Teil der Hoare-Logik oder des Hoare-Dreifach: {P} C {Q}, wobei {P} die Voraussetzung für die Behauptung (ion) s und {Q} ist die Nachbedingung behauptet (Ion) s.
Ich würde die Ratschläge zur Assert-Funktion in PHP mit Fehlern kritisch zur Kenntnis nehmen. Sie möchten keinen fehlerhaften Code verwenden. Was Sie wirklich wollen, sind die Hersteller von PHP, um den Fehler in der Behauptung zu beheben. Bis dahin können Sie den Assert verwenden, ihn jedoch unter Berücksichtigung des aktuellen Buggy-Status verwenden.
Wenn die Assert-Funktion fehlerhaft ist, sollten Sie sie nicht im Produktionscode verwenden. Trotzdem empfehle ich, dass Sie es gegebenenfalls in Entwicklungs- und Testcode verwenden.
Wenn Sie schließlich eine Vertragsstudie zum Entwurf durchführen, werden Sie feststellen, dass die Verwendung von Booleschen Behauptungen im Lichte der objektorientierten klassischen Vererbung Konsequenzen hat - das heißt, Sie dürfen niemals eine Vorbedingung oder eine Nachbedingung schwächen. Dies könnte für Ihre polymorphen Nachkommenobjekte, die miteinander interagieren, gefährlich sein. Bis Sie verstehen, was das bedeutet - ich würde es in Ruhe lassen!
Darüber hinaus empfehle ich den Herstellern von PHP dringend, eine umfassende Designstudie im Auftrag durchzuführen und zu versuchen, sie so schnell wie möglich in PHP zu integrieren! Dann können wir alle von einem DbC-fähigen Compiler / Interpreter profitieren, der die in den Antworten (oben) genannten Probleme behandelt:
HINWEIS: Selbst die Verwendung einer
if
Anweisung als Ersatz für die Behauptung (Vorbedingung) hat schwerwiegende Folgen, wenn sie zur Stärkung einer Vorbedingung oder zur Schwächung einer Nachbedingung verwendet wird. Um zu verstehen, was das bedeutet, müssen Sie Design vertraglich studieren, um es zu wissen! :-)Viel Spaß beim Lernen und Lernen.
quelle