Felix Riesterer: Bug oder Feature?

Liebe PHP'ler,

in PHP4 habe ich für meine Klasse immer eine Funktion gleichen Namens als Konstruktor geschrieben, wobei ich immer die Groß-/Kleinschreibung beachtet habe:

class Search {  
    var data;  
  
    function Search () {  
        // ich bin der Konstruktor  
    }  
  
    function load_data () {  
    }  
}

In PHP5 habe ich mir angewöhnt, __construct() als Konstruktor zu notieren:

class Search {  
    private data;  
  
    public function __construct () {  
        // ich bin der Konstruktor  
    }  
  
    private function load_data () {  
    }  
  
    private function search () {  
        // ich bin nicht der Konstruktor!  
    }  
}

Nun nutze ich aber (zum ersten Mal, daher wahrscheinlich meine Frage) Vererbung, um "don't repeat yourself" umzusetzen:

abstract class Plugin {  
    public  i18n;  
  
    public  function __construct () {  
        // ich bin der Konstruktor  
        $this->i18n = array(  
            'de' => array(),  
            'en' => array()  
        );  
    }  
  
    public  function translate ($s) {  
    }  
}  
  
class Search extends Plugin {  
    private data;  
  
    // Konstruktor steht in der Elternklasse  
  
    private function load_data () {  
    }  
  
    private function search () {  
        // ich soll jetzt ein Konstruktor sein?!?  
    }  
}

Da in der Klasse "Search" die Konstruktorfunktion "__construct" nicht mehr explizit notiert ist (sie steht ja jetzt in der Elternklasse "Plugin"), versucht PHP5 wie seinerzeit in PHP 4 die anscheinend gleichlautende private Funktion "search" als Konstruktorfunktion zu verwenden, auch wenn die Groß-/Kleinschreibung sich unterscheidet und obwohl durch die Vererbung eine explizite Konstruktorfunktion namens "__construct" gegeben ist.

Um die Kompatibilität zu PHP4 zu erhalten kann ich schon nachvollziehen, dass bei Nichtvorhandensein einer explizit notierten Funktion "__construct" eine gleichlautende Funktion als Konstruktorersatz gesucht wird. Aber muss das in PHP5 auch noch case-insensitive erfolgen?

Also: Ist das ein Bug oder ein Feature von PHP5?

Liebe Grüße,

Felix Riesterer.

--
ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
  1. Tach!

    Um die Kompatibilität zu PHP4 zu erhalten kann ich schon nachvollziehen, dass bei Nichtvorhandensein einer explizit notierten Funktion "__construct" eine gleichlautende Funktion als Konstruktorersatz gesucht wird. Aber muss das in PHP5 auch noch case-insensitive erfolgen?

    Ja, Klassen- und Funktions-/Methodenbezeichner sind case-insensitive. (Variablennamen hingegen nicht.)

    dedlfix.

    1. Lieber dedlfix,

      Ja, Klassen- und Funktions-/Methodenbezeichner sind case-insensitive.

      danke für die Klarstellung. Das bedeutet, dass $xml->addChild() dasselbe ist wie $xml->AdDcHiLd(). Mögen muss ich das aber nicht... *grrr*

      (Variablennamen hingegen nicht.)

      Das macht PHP so unsympathisch. Weder CaMeL-cAsE noch die Konvention mit dem Unterstrich wird konstant beibehalten. Wenn ich wie oben $xml->AdDcHiLd() notieren kann, dann sollte wenigstens $xml->AdD_cHiLd() notwendig sein, da ja case-insensitive. Aber was rege ich mich auf. PHP ist trotz seiner z.T. echt dämlichen Konstrukte aus der Anfangszeit (man denke an die Reihenfolge von Parametern in String-Funktionen: erst den String und dann die jeweiligen Parameter, oder den String doch zuletzt?) eine der populärsten serverseitigen Scriptsprachen "für den kleinen Mann" geworden. Und ich habe auch damit angefangen... hätt' ich doch bloß 'was anständiges gelernt (wie man hier im Süden sagt)!

      Liebe Grüße,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
  2. hi,

    Da in der Klasse "Search" die Konstruktorfunktion "__construct" nicht mehr explizit notiert ist (sie steht ja jetzt in der Elternklasse "Plugin"), versucht PHP5 wie seinerzeit in PHP 4 die anscheinend gleichlautende private Funktion "search" als Konstruktorfunktion zu verwenden, auch wenn die Groß-/Kleinschreibung sich unterscheidet und obwohl durch die Vererbung eine explizite Konstruktorfunktion namens "__construct" gegeben ist.

    Komisch. Ich dachte, dass man 1. keine Konstruktorfunktion braucht und 2. die des Parent explizit aufgerufen werden müsste ...; dass alles CaseSensitive ist, hat dedlfix ja geschrieben. Ansonsten: http://php.net/manual/de/language.oop5.decon.php, da steht ja alles im Grunde:

    " Aus Gründen der Abwärtskompatibilität sucht PHP 5, falls die Klasse keine __construct() Methode beistzt, nach einem Konstruktur des alten Stils, d.h. einer Methode mit dem selben Namen wie die Klasse. Der einzige Fall in dem somit Kompatibilitätsprobleme auftreten können, ist wenn die Klasse eine Methode __construct() definiert, welche jedoch für andere Zwecke benutzt wird.

    Im Gegensatz zu anderen Methoden, generiert PHP keinen E_STRICT Fehler, wenn __construct() in einer Kindklasse andere Parameter definiert, als die __construct() Methode der Elternklasse.

    Seit PHP 5.3.3 werden Methoden, welche mit dem Klassennamen übereinstimmen, nicht länger als Konstruktoren behandelt, wenn die Klasse sich in einem Namespace befindet. Klassen, welche sich nicht in einem Namespace befinden, betrifft dies jedoch nicht. "

    mfg

    tami

    1. Om nah hoo pez nyeetz, tami!

      dass alles CaseSensitive ist, hat dedlfix ja geschrieben.

      Klassen- und Funktions-/Methodenbezeichner sind case-insensitive.

      ^^
      Variablennamen hingegen sind casesensitive.

      Matthias

      --
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Hebe und Hebelgesetz.

      1. Lieber Matthias Apsel,

        Klassen- und Funktions-/Methodenbezeichner sind case-insensitive.
                                                                   ^^
        Variablennamen hingegen sind casesensitive.

        ist das nicht toll? Ich finde das toll (wie in tollwütig oder Tollhaus)!

        Liebe Grüße,

        Felix Riesterer.

        --
        ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
    2. Lieber Robert,

      Komisch. Ich dachte, dass man 1. keine Konstruktorfunktion braucht und 2. die des Parent explizit aufgerufen werden müsste ...;

      aus meinen obigen Beispielen kannst Du nicht ersehen, was meine Klasse im Konstruktor bereits alles regelt. Daher verstehst Du 1. für meinen speziellen Fall nicht.

      Aber danke für den Versuch einer hilfreichen Antwort.

      http://php.net/manual/de/language.oop5.decon.php

      Da steht im Hinweiskasten, dass die Konstruktorfunktion der Vaterklasse nur dann nicht implizit aufgerufen wird, wenn die Kindklasse selbst eine definiert. Aber diese tut das ja (absichtlich!) nicht! Daher wurde ja (leider) die gleichnamige Methode stattdessen als solche (fälschlicherweise - aber eben nur meiner Meinung nach) genutzt. So erklärt sich Dein Irrtum bezüglich 2. für mein Beispiel.

      Liebe Grüße,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
      1. hi Felix,

        Aber danke für den Versuch einer hilfreichen Antwort.

        Jaja, er "versuchte" pünktlich zu sein ... ;-)

        Da steht im Hinweiskasten, dass die Konstruktorfunktion der Vaterklasse nur dann nicht implizit aufgerufen wird, wenn die Kindklasse selbst eine definiert. Aber diese tut das ja (absichtlich!) nicht! Daher wurde ja (leider) die gleichnamige Methode stattdessen als solche (fälschlicherweise - aber eben nur meiner Meinung nach) genutzt. So erklärt sich Dein Irrtum bezüglich 2. für mein Beispiel.

        Ja danke, selber was dazugelernt. Hatte zuerst wohl nicht ganz konzentriert gelesen und nicht verstanden, dass Methoden caseINsensitiv sind. Is ja wie bei Windows Dateinamen ;-). Hat mich irgendwann vor Jahren mal bestimmt über ne Stunde gekostet, bis ich rausbekommen habe, dass *.JPG auf dem heimischen Windows nicht das selbe wie auf einem Linux-Server ist ...;

        mfg

        tami