Frage

Ab Version 5.3 unterstützt PHP späte Bindung für statische Methoden. Während es eine zweifellos nützliche Funktion ist, gibt es nur wenige Fälle, in denen die Verwendung wirklich notwendig ist (zum Beispiel des Active Record).

Beachten Sie auch diese Beispiele:

1. Convenience Bauer (::create())

class SimpleObject
{
    public function __construct() { /* ... */ }

    public static function create()
    {
        return new static; // or: return new self;
    }
}

Wenn diese Klasse kann verlängert werden (jedoch ist es nicht von einer Klasse im selben Paket erweitert), sollte spät statisch nur um es einfacher zu machen, verwendet wird Bindung erstreckt (ohne dass die ::create() Methode neu zu schreiben, und, was noch wichtiger ist, ohne zu bedenken, dass zu tun)?

Hinweis: dieses Idiom verwendet wird, um die Unmöglichkeit zu arbeiten gerade konstruierten Objekte aufrufen Methoden auf. new SimpleObject()->doStuff() in PHP ist ungültig


2. Klassenkonstanten

class TagMatcher
{
    const TAG_PATTERN = '/\<([a-z\-]+?)\>/i';

    private $subject;

    public function construct($subject) { $this->subject = $subject; }

    public function getAllTags()
    {
        $pattern = static::TAG_PATTERN;
        preg_match_all($pattern, $this->subject);
        return $pattern[1];
    }
}

Der Grund static:: in diesem Beispiel zu verwenden, ist ähnlich wie die vorherigen. Es wird verwendet, nur weil diese Klasse kann unterschiedlich ausgebildet Tags nur durch sie und die ständigen Überschreiben erstreckt anzupassen gemacht werden.


Also, wickeln sie alle auf, sind diese Nutzungen (und ähnliche) in der letzten statischen Bindung sind zuviel des Guten? Gibt es einen spürbaren Leistungseinbußen? Auch dann, wenn häufige Verwendung von später Bindung der Gesamtleistungssteigerung von Opcode Caches gegeben reduzieren?

War es hilfreich?

Lösung

  

Also, wickeln sie alle auf, sind diese Nutzungen (und ähnliche) in der letzten statischen Bindung sind zuviel des Guten? Gibt es einen spürbaren Leistungseinbußen? Auch dann, wenn häufige Verwendung von später Bindung der Gesamtleistungssteigerung von Opcode Caches gegeben reduzieren?

Die Einführung der späten statische Bindung behebt einen Fehler in PHP-Objektmodell. Es geht nicht um Leistung, es geht um Semantik.

Zum Beispiel, wie ich statische Methoden verwenden, wenn die Durchführung des Verfahrens nicht $this verwenden ist. Nur weil eine Methode statisch ist, bedeutet nicht, zu sagen, dass Sie wollen es nicht manchmal außer Kraft setzen. Vor PHP 5.3 war das Verhalten, dass kein Fehler angezeigt wurde, wenn Sie eine statische Methode overrode, aber PHP würde einfach weitermachen und leise die Eltern-Version. Zum Beispiel 5.3 der folgende Code druckt ‚A‘ vor PHP. Das ist sehr unerwartetes Verhalten.

Späte statische Bindung fixiert, und jetzt den gleichen Code druckt ‚B‘.

<?php
class A {
  public static function who() {
    echo __CLASS__;
  }
  public static function test() {
    static::who();
  }
}

class B extends A {
  public static function who() {
    echo __CLASS__;
  }
}

B::test();
?>

Andere Tipps

statische Methoden (früh- oder spät-bound) schaffen eine enge Kopplung und (somit) reduzieren Testbarkeit. Sie können als ein paar statischen Anrufe ohne mehr mit großen Programme in PHP erstellen. für mich sind spät statische Methoden eine nicht-Funktion.

Bearbeiten Marco Demaio Frage, wie statische Methode reduzieren Testbarkeit zu beantworten?

Es tut mir leid, wenn dies alles offensichtlich zu Ihnen, statischen Elementen (beiden Daten und Methoden) ist nützlich und keinen Schaden anrichten, wenn verantwortungsvoll genutzt, i ihren vorherrschenden Missbrauch anspielte.

sagen Sie eine Web-Anwendung, die eine SQL-Datenbank verwendet. Ihre Business-Objekte Abrufen von Daten kann eine statische Schnittstelle oder durch Polymorphismus. entweder

class MyBusinessObject
extends...
{
  public function doThisOrThat(...)
  {
    $results = db::query('sql string...');
    ...
  }
}

oder

class MyBusinessObject
extends...
{
  public function __construct(dbconn $db)
  {
    $this->db = $db;
  }
  private $db;
  public function doThisOrThat(...)
  {
    $results = $this->db->query('sql string...');
    ...
  }
}

ist diese einfacher zu testen (wie in: i testen wollen, dass die SQL-Zeichenfolge aufgebaut aus so und solche Eingaben ist so und so), weil es einfacher ist, eine weitere Implementierung der dbconn Schnittstelle zu schaffen, als es ist die Bedeutung von db:: zu ändern. warum werden Sie entweder wollen? weil Sie das SQL-Komponieren Verhalten zu testen, und in der Tat keine wirkliche Datenbank benötigen ist es einfacher für zu testen, ohne eine echte Datenbank. auch ist es einfacher, die SQL-Verbraucher Stub wenn Ihre Tests mit einem anderen Aspekt der CUT (-Code Under Test) betroffen sind.

Tests immer impliziert über seine Mitarbeiter auf den getesteten Code liegen und bei Enthaltung von statischen Schnittstellen (das „doublecolon“ oder „quadridot“) bedeutet, dass die Lüge nicht eine massive Operation sein muss, was ein Plus ist, da je weiter die getestet Code ist aus dem Produktionscode, die weniger aussagekräftig sind die Testergebnisse.

Wo ich eine Notwendigkeit finde spät statisch verwenden Bindung ist mit PHPUnit spöttisch von statischen Methoden für Unit-Tests zu ermöglichen. Das Problem, das ich habe ist, dass Ich mag keinen Code zu ändern streng spöttisch zu erlauben, aber ich kann über das bekommen.

Um Ihre Frage zu beantworten, aber ich würde wetten, dass, was auch immer die Leistung Kosten diese trägt, ist es im Vergleich zu den meisten Programmlaufzeiten blass wird. Mit anderen Worten, es wird nicht einen spürbaren Unterschied machen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top