KingCrunchs kleine Welt

Gedanken über PHP und was mich sonst bewegt…

4. Juli 2012
von KingCrunch
Keine Kommentare

Symfony 2.1 und Swiftmailer: swift_init.php not found or invalid function name

Yeah, ein Beitrag! Auch nur was Kurzes, aber weil ich zu meinem Problem nur etwas auf Russisch(?) finden konnte, dachte ich mir, ich gebe eine kurze Zusammenfassung der Google-Translate-Übersetzung zum Besten.

Diese Fehlermeldung kam bei mir bei beim Aufruf von composer.phar update mit dem Ziel die neuste Variante von Symfony 2.1 zu aktualisieren.

Warning: call_user_func() expects parameter 1 to be a valid callback, function '.../vendor/swiftmailer/swiftmailer/lib/swift_init.php' not found or invalid function name in .../vendor/swiftmailer/swiftmailer/lib/classes/Swift.php line 62 

Schon klar: Wer bleeding edge-Technologien einsetzt, muss damit rechnen (nicht einsetzt: Ich spiel doch bloß). Doof nur, dass hier Composer tatsächlich nur diese eine kurze Meldung von sich gab. OK, also Zusammenfassung des Herren aus Russland: Das Problem liegt in der eigenen app/autoload.php. Dort wurde in den letzten 2 Zeilen der “spezielle Swiftmailer”-Autoloader initialisiert, der offenbar nicht mehr notwendig ist und sogar Fehler verursacht. Ergo: Weg musser!

// Swiftmailer needs a special autoloader to allow
// the lazy loading of the init file (which is expensive)
require_once __DIR__.'/../vendor/swiftmailer/swiftmailer/lib/classes/Swift.php';
Swift::registerAutoload(__DIR__.'/../vendor/swiftmailer/swiftmailer/lib/swift_init.php');

9. Oktober 2011
von KingCrunch
4 Kommentare

PHP5.4: Erweiterte Closures

Die Beta1 von PHP5.4 habe ich hier nicht auch noch angekündigt, das haben andere schon zur Genüge getan und wirklich was Neues dazu gekommen, ist ja nun auch nicht. Denkste, stellte ich heute fest, denn fast unscheinbar gibt es in der NEWS einen kleinen Eintrag:

15 Sep 2011, PHP 5.4.0 Beta

  • Implemented closure rebinding as parameter to bindTo. (Gustavo Lopes)

Als ich das gelesen habe, dachte ich mir: “Is ja niedlich, endlich geht das lange überfällige feature function () use ($this) {} (im Objekt-Kontext), aber so einfach ist das nun doch nicht. Heute bin ich auf eine Mail von der Internals-Mailinglist gestoßen.

  • Closures can now have an associated scope
  • Closures can now have a bound object
  • Closures can now be either static or non-static
  • Closures defined in a place with an active scope are scoped accordingly
  • Closures defined inside an instance method (or bound closure) have a bound object (namely $this)
  • Closures are static if defined within a static method or with the static keyword (static function() { … })

static => !bound
(but it’s false that !static => bound)
bound => scoped
!static && scoped => bound
(i.e., if !static, scoped < => bound)

The bound instance and the scoped can be freely changed with Closure::bind
and $closure->bindTo, subject to these constraints.

“Statische Closures”? Nanu? Das musste ich mir nun doch noch etwas genauer anschauen, aber die Beschreibung im RFC ist auch nicht sooo dermaßen hilfreich. Also einfach mal bisschen rumgespielt und das bisherige Fazit ist ganz nett ausgefallen

  1. function () use ($this) {} geht tatsächlich weiterhin nicht. Stattdessen werden nun alle Closures an den Sichtbarkeitsbereich (“Scope”) gebunden, in dem sie definiert wurden.
    class A {
        public function getClosure () {
          return function () {
            echo var_dump($this);
          };
        }
    }
    $a = new A;
    $f = $a->getClosure();
    $f();
    // object(A)#1 (0) {
    // }
  2. Will man dieses Verhalten explizit nicht, kann man jetzt auch statische Closures (d.h. Closures ohne Bindung zu einem Scope) erstellen
    class A {
        public function getClosure () {
          return static function () {
            echo var_dump($this);
          };
        }
    }
    $a = new A;
    $f = $a->getClosure();
    $f();
    // NULL
  3. Der Vorteil davon ist logischerweise, dass die Closures nun auch auf protected- und private-Methoden/-Eigenschaften zugreifen können
    class A {
        public function getClosure () {
          return function () {
            $this->sayHello();
          };
        }
        private function sayHello () {
            echo "Hello World\n";
        }
    }
    $a = new A;
    $f = $a->getClosure();
    $f();
    // Hello World

    Ergibt auch Sinn, sonst gäbe es ja keinen Vorteil zu bisherigen “Workarounds” (was jetzt zwar auch funktioniert, aber überflüssig geworden ist).

    class A {
        public function getClosure () {
          $that = $this;
          return function () use ($that) {
            $that->sayHello();
          };
        }
        private function sayHello () {
            echo "Hello World\n";
        }
    }
    $a = new A;
    $f = $a->getClosure();
    $f();
    // Hello World

Etwas unheimlich ist das letzte Beispiel, dass heraus kommt, wenn man das RFC etwas durchschaut hat, denn die Zuweisung von $this und die Bestimmung des Sichtbarkeitsbereiches geschieht nicht — wie man annehmen mag — “automatisch” wärend der Erstellung, sondern durch die fast schon traditionelle Magie über spezielle Methoden. Zur Erinnerung: Ein Closure ist genau genommen ein Objekt der Klasse Closure, dass seinerseits __invoke() so implementiert, dass der Code des Closures ausgeführt wird, und wenn man nun “die Klasse” als Funktion aufruft, wird wie von Geisterhand Closure::__invoke() aufgerufen (das geht auch mit eigenen Klassen, die __invoke() implementieren). Genau genommen ist $x = function () {} also nur eine Instanzierung einer Klasse mit einem kleinen Extra. Für das neue Feature implementiert Closure nun zusätzlich bind($to[, $scope]) (bzw statisch bindTo($closure, $to[,$scope)]), wobei die Methode ein Klon des Closures liefert, das an $to gebunden ist und die Sichtbarkeit auf $scope setzt. Klingt etwas verwirrend, deshalb ein Beispiel

class A {
    public function getClosure () {
      return function () {
        $this->sayHello();
      };
    }
}
class B {
    private function sayHello () {
        echo "Hello World\n";
    }
}
class C extends B {
}
$a = new A;
$c = new C;
$f = $a->getClosure();
$g = $f->bindTo($c, 'B');
$g();
// Hello World

Der erste Parameter setzt $this = $c, der zweite sorgt dafür, dass sich der Closure im Kontext der Klasse B befindet und somit auf alle privaten und geschützten Elemente von B zugreifen kann. Unheimlich ist es deshalb, weil es nun ohne Verrenkungen möglich ist die Kapselung einzelner Klassen aufzubrechen und Code direkt zu injezieren. Aber wer wird schon in seiner eigenen Anwendung seine Klassen “hacken” ;)? Speziell für Unit-Tests kann das sicherlich auch sehr sinnvoll sein, weil das nun testen von privaten und geschützten Methoden auffällig erleichert

$f = function () {
    return $this->privateMethodToTest();
};
$g = $f->bind($testObject, 'Classname');
$this->assertEquals('Expected', $g());

18. August 2011
von KingCrunch
6 Kommentare

Gegen Mikrooptimierung: Zwei Schleifen sind schlecht?

PHP5.4 ist kurz vor der Beta, dass heißt die große Zeit der Neuvorstellungen ist erstmal vorbei, und solange ich nun darüber nachdenke, welchem Thema ich mir als Nächstes annehme, habe ich heute etwas Blog-Tuning betrieben. Das unsägliche Javascript der diversen Social-Bla sind statischen Links gewichen (und sowas). Statt 400kB sind es jetzt nur noch 250kB ohne und 25kB mit Cache.

Als kleine Brücke bis zum nächsten interessanten (?) Beitrag und damit Besucher ein Grund haben den ungeahnten Speed (und die Werbung *hust* :X) zu genießen, gibt es jetzt nur ein kleines Rätsel: Welches von Beiden ist schneller?

for ($i = 0; $i < = 1000000; $i++) {
    $array[$i] = $array[$i] * $array[$i];
    $array[$i] = base_convert($array[$i], 10, 16);
}
for ($i = 0; $i < 1000000; $i++) {
    $array[$i] = $array[$i] * $array[$i];
}
for ($i = 0; $i < 1000000; $i++) {
    $array[$i] = base_convert($array[$i], 10, 16);
}

Weiterlesen →

7. August 2011
von KingCrunch
7 Kommentare

PHP5.4: Alpha3

Das Groß der Änderungen kam traditionsgemäß mit der ersten alpha-Version, aber trotzdem lohnt sich der Blick auf die alpha3, denn mit ihr kommen 2 “ganz nette” und eine interessante Syntaxerweiterungen (“Syntactic Sugar”) dazu. Aber fangen wir mit dem langweiligen Teil an: Diesmal fiel der “Removed”-Keule die unleidlichen Funktionalitäten rund um die Magic-Quotes zum Opfer. Die INI-Einstellungen magic_quotes_gpc, magic_quotes_runtime und magic_quotes_sybase entfallen ersatzlos, die Funktionen get_magic_quotes_gpc() und get_magic_quotes_runtime() liefern immer nur noch false und die Funktion set_magic_quotes_runtione() wirft von nun an ein E_CORE_ERROR. Ein hoch auf die Putzfrau.

Weiterlesen →

1. August 2011
von KingCrunch
3 Kommentare

PHP5.4: Traits aka “Horizontal Reuse”

Eigentlich schon seit fast 3 Jahren angekündigt und meines Erachtens die sinnvollste Neuerung in PHP seit Einführung der Objektorientierung: “Traits” (oder “Mixins“, dazu später mehr). Als OOP eingeführt wurde, entschied man sich zu einfacher Vererbung (“Single Inheritance“), weils einfacher umzusetzen ist und weil man davon ausging, dass man damit die meisten Use-Cases abdecken könne. Das kann man auch, aber eben nicht alles und vorallem nicht unbedingt alles besonders schön.

Hinter dem Schlagwort “Horizontal Reuse” verbirgt sich ein Konzept, bei dem es darum geht Methoden zwischen Klassen wiederverwendbar zu machen, die nicht, oder nur sehr entfernt verwandt sind, bzw “verwandt gemacht werden können”. Ein Hund kann hüpfen, ein Lowrider auch. Problem ist nun, dass diese beiden Klassen schwer in einem Vererbungsbaum unterzubringen sind, zumindest so, dass es Sinn ergibt. Um trotzdem nicht die Methode zwei mal implementieren zu müssen, gibt es jetzt die Traits.

Weiterlesen →

27. Juli 2011
von KingCrunch
1 Kommentar

Eingebauter Webserver

Bevor morgen die alpha3 erscheint, noch schnell ein Hinweis auf den mit der alpha2 — still und heimlich released am 14.07. (Download, oder per SVN — eingeführten eingebauten Webserver. Die Erklärung ist schnell gemacht, denn so praktisch er ist, so unspektakulär ist seine Bedienung

php-cli -S localhost:8080 -t /path/to/docRoot

-S definiert die Adresse und den Port und -t den Document-Root. Beides sollte jeden bekannt sein. Interessanter ist der Router.

php-cli -S localhost:8080 /path/to/Router

Hierbei ist der Order, in dem sich der Router befindet, das Wurzelverzeichnis. Ob man das zusammen mit -t verwenden kann, habe ich nicht ausprobiert, finde ich aber auch nicht erheblich. Der Router liefert false, wenn der Webserver sich doch um die Auflösung der Datei kümmern soll, oder er kümmert sich selbst um Verarbeitung. Ich sags ja: Einfach.

<?php
if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"]))
    return false;
else
    runApp();

Der Webserver wird explizit nur für “Test-/Entwicklungszwecke” angepriesen, was auch Sinn ergibt, denn die jahrelang gewachsenen, abgesicherten und optimierten “echten” Webserver wird er kaum das Wasser reichen können. Trotzdem scheint der kleine Einsatzzweck etwas Verschwendung zu sein. So seh ich ihn für mich schon als Plattform für Desktop-Anwendungen mit Browser-GUI: Es gibt voraussichtlich nur immer genau ein (und höchstens eine überschaubare Anzahl) “Besucher” und wer sich in die Anwendung hackt, hackt im Grunde genommen sein eigenes System.

23. Juli 2011
von KingCrunch
2 Kommentare

PHP 5.4 entwickelt sich

Man könnte den Einleitungssatz aus meinem alten Beitrag “PHP 5.3 entwickelt sich” nahezu eins-zu-eins übernehmen, denn auch diesmal vergingen vom Release von PHP 5.3 bis zum Release von PHP 5.4-alpha1 fast exakt 2 Jahre (2 Tage daneben ;)). Aber in Zukunft soll dann alles besser werden, das legt zumindest der RFC zum Releaseprozess nahe. Egal welche Variante man dort betrachtet, jede sieht eine neue x.y+1.0-Version pro Jahr vor (und gemeint ist damit tatsächlich der Stable-Release). Die Gesamtliste über die Änderungen enthält viel, wobei vieles die üblichen kleineren Änderungen sind. Ich werde das etwas raffen und zwar auf die Dinge, bei den ich denke, dass sie interessant sind ;) Ausser der Reihe interessant ist, dass es einige Performance-Optimierungen von einem Fork in den Core geschafft haben.

Dieser Artikel bezieht sich ausschließlich auf die alpha1, aber auch diesmal gibt es neben der Liste der bereits integrierten Änderungen noch eine offizielle TODO. In der Warteliste steht noch so manches Schmankerl, aber dazu wenns es soweit ist.

Weiterlesen →

14. Juli 2011
von KingCrunch
Keine Kommentare

Assertions

Assertions ist ein nicht so häufig beachtetes Feature von PHP, dass allerdings — richtig eingesetzt — sehr hilfreich sein kann. Dabei geht es um Behauptungen über den logischen Zustand zum entsprechenden Zeitpunkt (der Wikipedia-Artikel liefert eine nette Beschreibung). Anders als bei der Prüfung von Benutzereingaben, bei dem man lieber nicht mit “Logik” rechnen sollte, geht man also davon aus, dass die Assertion nie fehlschlägt, zumindest solange man richtig mit diesem Code umgeht. Das es letzten Endes genau darum geht, zeige ich noch anhand eines kurzen Beispiels.

Assertions in PHP bestehen einzig aus der Funktion assert() und einer handvoll Optionen. assert() macht nun nichts anderes, als den übergebenen Parameter auszuwerten und je nachdem eine Warnung zu liefern, das Skript abzubrechen, oder eine definierte callback aufzurufen. Auf die technischen Details verzichte ich hier, denn diese lassen sich im Manual nachlesen. Was kann man nun mit Assertions anfangen?

Weiterlesen →

11. Juli 2011
von KingCrunch
4 Kommentare

Neues Theme: Yoko (Update: Und share/like/+1)

Linux und Ich brachte mich darauf: Ein anderes Theme kann mal wieder gut tun. Wie man sieht, ist es bloß die Standardinstallation, Optimierungen folgen. Es fühlt sich aber jetzt schon nen Zacken schneller an und das war das Primärziel. Das es dazu noch aufgeräumter und irgendwie stimmiger wirkt, nehm ich noch gerne als Bonus mit dazu :)

Update: Gleich hinterher “Tweet, Like, Google +1 and Share“. Wenn man mich fragt, dann reichen die 4 Buttons (für 3 Dienste, FB hat da nen kleinen Vorteil ;)) vollkommmen. Ich denke, sie sind nicht zu penetrant.

Und ja: Auch diesmal war es nicht der erste Beitrag auf Englisch. Der nächste aber bestimmt ;)

Bad Behavior has blocked 248 access attempts in the last 7 days.

Page optimized by WP Minify WordPress Plugin