Neuigkeiten
  • Die modified eCommerce Shopsoftware ist kostenlos, aber nicht umsonst.
    Spenden
  • Damit wir die modified eCommerce Shopsoftware auch zukünftig kostenlos anbieten können:
    Spenden
  • Thema: Doppelte Funktionsnamen abfangen?

    webald

    • modified Team
    • Beiträge: 2.791
    Doppelte Funktionsnamen abfangen?
    am: 09. Juli 2015, 17:17:39
    Gegeben sind 2 Dateien.

    datei2.php:
    Code: PHP  [Auswählen]
    <?php
    function test(){
       echo 'test aus datei2';
    }
    ?>

    datei1.php:
    Code: PHP  [Auswählen]
    <?php
    function test(){
       echo 'test aus datei1';
    }
    try{
       include('datei2.php');
    }catch(exception $e){
       echo 'Fehler' . $e->getMessage();
    }
    test();
    ?>

    Das führt zu einem Fehler: Cannot redeclare .....

    Wie verhindert man den include, wenn die Funktion doppelt deklariert werden würde? Try/Catch fängt Fatal Errors nicht ab.

    Linkback: https://www.modified-shop.org/forum/index.php?topic=33317.0

    webald

    • modified Team
    • Beiträge: 2.791
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #1 am: 09. Juli 2015, 18:12:11
    Ich habe für datei1.php mal einen Ansatz, aber so ganz ist es das noch nicht:

    Code: PHP  [Auswählen]
    <?php
    namespace std{
            function test(){
                    echo 'test aus datei1';
            }
            $funcexistarr = get_defined_functions();
    }
    namespace LoadTest{
            try{
                    include('datei2.php');
            }catch(exception $e){
                    echo 'Fehler' . $e->getMessage();
            }
            $loadtestarr = get_defined_functions();
    }
    namespace std{
            test();
            $loadednewarr = array_diff($loadtestarr, $funcexistarr);
            if(count($loadednewarr)>0){
                    include('datei2.php');
            }
    }
    ?>

    Die Idee ist die zu includierende Datei erst mal in einen anderen Namespace laden und dann zu vergleichen ob in beiden Namespaces nun neue Funktionen sind. Nur wenn es keine Kollision gibt wird die Datei in den eigentlich richtigen Namespace geladen. Aber so ganz tut es noch nicht.

    Marcus Kreusch

    • Fördermitglied
    • Beiträge: 312
    • Geschlecht:
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #2 am: 09. Juli 2015, 19:07:47
    Hallo webald,

    ich denke, die einzig gute Antwort ist, dass in so einem Fall die Architektur und Dateistruktur überdacht werden sollte. Ich kann mir keinen einzigen Fall vorstellen, in dem so etwas tatsächlich vorkommen sollte.
    Wenn du mehr über den konkreten Fall schreibst, findet sich sicher auch eine saubere Lösung - ansonsten hilft wahrscheinlich nur noch ein

    Code: PHP  [Auswählen]
    if(!function_exists('test')){
        function test(){
            //...
        }
    }
     

    Viele Grüße
    Marcus

    webald

    • modified Team
    • Beiträge: 2.791
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #3 am: 09. Juli 2015, 19:30:36
    Deine Lösung geht nicht, da der Name der Funktion vorab nicht bekannt ist.

    Szenario:
    Erweiterungen im Shop durch Drittanbeiter. Eine Funktion wie etwa GetOrders() ist nicht unwahrscheinlich mehrfach genutzt zu werden. Und wenn nun zwei Erweiterungen die selbe Bezeichnung für ein Funktion haben funtioniert der Shop nicht mehr (Fatal Error).

    Da ganze könnte durch konsequente Umstellung auf OOP und Klassen gelöst werden, aber das ist dann ein anderer Shop und kompatibel zu heute ist da gar nix mehr.

    Marcus Kreusch

    • Fördermitglied
    • Beiträge: 312
    • Geschlecht:
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #4 am: 09. Juli 2015, 19:46:22
    Da hilft nur eines: Drittanbietern klare Regeln geben.

    Selbst wenn man den Fatal Error vermeiden könnte, ändert es ja alles nichts daran, dass die Funktion GetOrders() des einen Anbieters etwas ganz anderes macht als die des anderen und es allein dadurch Probleme gibt.

    Regeln könnten sein:

    Alle Funktionen müssen einen eindeutigen Präfix bekommen (wie z.B. Smarty-Funktionen "smarty_function_....").

    Oder: Keine Funktionen verwenden sonden nur statische Methoden - am besten mit namespace... Dafür muss sich am Shop nichts ändern....

    Oder: Nur eine Funktion pro Datei und der Dateiname muss dem Funktionsnamen entsprechen - dann könnte man mithilfe des Dateinamens vorher den function_exists()-Test machen... Hat nur den oben erwähnten Nachteil, dass es schnell Inkompatibilitäten geben kann, weil damit keine eindeutigen Namen erzwungen werden.

    Matt

    • Experte
    • Beiträge: 4.241
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #5 am: 09. Juli 2015, 20:22:05
    Frameworks lösen das genau über die Ansätze von MK. Und der Autoloader kümmert sich darum, dass es zu keinen Dubletten kommt. Sowas in modified zu integrieren erscheint mir weder sinnvoll noch mit vertretbarem Aufwand möglich.

    HHGAG

    • Frisch an Board
    • Beiträge: 61
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #6 am: 09. Juli 2015, 21:03:45
    Eigentlich müsste man mit Reflection arbeiten, aber dies ist bei einfachen Helperdateien nicht möglich, hier eine kleine Reflection für simple Dateien mit Funktionsdeklarationen
    Code: PHP  [Auswählen]
    <?php
    try {
        $fileName = 'datei2.php';
        $file = file_get_contents($fileName);

        preg_match_all('/function[\s\n]+(\S+)[\s\n]*\(/', $file, $matches);

        foreach ($matches[1] as $function) {
            if(function_exists($function)){
                throw new \Exception('Function ' . $function . ' already exists!');
            }
        }
       include($fileName);
    } catch(\Exception $e) {
       echo 'Error: ' . $e->getMessage();
    }  

    webald

    • modified Team
    • Beiträge: 2.791
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #7 am: 10. Juli 2015, 07:57:00
    @HHGAG:
    Könnte gehen, aber da werden auch auskommentirete Funktionen als vorhnden erkannt, oder?

    @MK:
    Oder: Keine Funktionen verwenden sonden nur statische Methoden - am besten mit namespace... Dafür muss sich am Shop nichts ändern....
    Man kann aber doch einen Namespace nur mitten in der Verarbeitun definieren, wenn von Anfang an mit Namespaces gearbeitet wird. Das wiederrum bedeutet dann doch Änderugen am Shop.
    Selbst wenn man den Fatal Error vermeiden könnte, ändert es ja alles nichts daran, dass die Funktion GetOrders() des einen Anbieters etwas ganz anderes macht als die des anderen und es allein dadurch Probleme gibt.
    Doch, wenn die Erweiterung im Falle doppelter Funktionsnamen nämlich gar nicht geladen wird und die Funktion aus der Erweiterung dann gar nicht vorhanden ist.

    @Matt:
    Der Aufwand lohnt und ist sogar wichtig. Wenn modified 2.x eine autoload-Möglichkeit bekommen soll muss nämlich genau das verhindert werden, dass Funktionen doppelt deklariert werden.

    HHGAG

    • Frisch an Board
    • Beiträge: 61
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #8 am: 10. Juli 2015, 08:37:29
    Ja, in diesem Fall würde es alle
    Code: PHP  [Auswählen]
    function
    Deklerationen ermitteln. Man müsste das soweit mit Überprüfungen versehen, bis lediglich aktive ermittelt werden. Denn im Moment würden sogar Methoden von Klassen erkannt und als normale Funktionen geprüft werden.

    Marcus Kreusch

    • Fördermitglied
    • Beiträge: 312
    • Geschlecht:
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #9 am: 10. Juli 2015, 13:33:00
    Wobei ja hoffentlich die Funktionen von den Klassen getrennt abgelegt werden und auch auskommentierte Funktionen haben ja in einer fertigen Erweiterung nichts zu suchen.

    Zum Thema Namespaces: Die kannst du ja beliebig einstreuen und entsprechend mit der Backslash-Syntax wieder verwenden. Führt aber vielleicht für modified zu weit, das verpflichtend zu machen.
    Ich würde daher dafür plädieren, Funktionen zu verbieten und stattdessen aussagekräftige Klassennamen mit statischen Methoden als Standard für Erweiterungen einzuführen. Jeden einzelnen Fall kannst du ja ohnehin nicht abfangen - spätestens wenn zwei Module den gleichen Namen tragen und daher auch die gleichen Verzeichnisnamen haben, muss einer sein Modul an die Gegebenheiten anpassen.

    Ansonsten glaube ich, dass allein dafür, dass modified seine zwei wichtigsten Alleinstellungsmerkmale, nämlich seine unschlagbare Geschwindigkeit und die selbst für Anfänger machbare Erweiterung des Codes, nicht verliert, eine zu komplexe Lösung mit zu vielen Prüfmechanismen fehl am Platz wäre. Wenn zwei Erweiterungen gleiche Funktionsnamen verwenden (und mal im Ernst: Wer einer Funktion einen namen, wie GetOrders() gibt, sollte keine Erweiterungen schreiben, die andere in ihrem Shop verwenden sollen), macht sich das ja eindeutig bemerkbar und dann ist der Entwickler gefordert, an seiner Namensgebung zu arbeiten.

    Viele Grüße
    Marcus

    webald

    • modified Team
    • Beiträge: 2.791
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #10 am: 10. Juli 2015, 13:59:56
    Genau für Einsteiger ist es wichtig, dass es im Shop eine Prüfroutine gibt, damit Erweiterungen problemlos funktionieren bzw. den Shop nicht abstürzen lassen. Die Prüfung soll im Core stattfinden und nicht in der Erweiterung.
    ... auskommentierte Funktionen haben ja in einer fertigen Erweiterung nichts zu suchen.
    Aber dafür echte Kommentare wie "... use this function to test if ..."

    Namespace - Dieser Code dürfte einen Fehler produzieren. Man kann also nicht einfach im Code einen Namespace definieren.
    Code: PHP  [Auswählen]
    <?php
    function test(){
            echo 'test aus datei1';
    }
    $funcexistarr = get_defined_functions();

    namespace LoadTest{
            try{
                    include('datei2.php');
            }catch(exception $e){
                    echo 'Fehler' . $e->getMessage();
            }
            $loadtestarr = get_defined_functions();
    }
    test();
    $loadednewarr = array_diff($loadtestarr, $funcexistarr);
    if(count($loadednewarr)>0){
            include('datei2.php');
    }
    ?>
    Möchte man mit Namespaces arbeiten, dann nur im kompletten Shop, was aber wieder größeres Know-How voraussetzt und ja nicht gewollt ist.

    Marcus Kreusch

    • Fördermitglied
    • Beiträge: 312
    • Geschlecht:
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #11 am: 10. Juli 2015, 14:45:37
    Genau für Einsteiger ist es wichtig, dass es im Shop eine Prüfroutine gibt, damit Erweiterungen problemlos funktionieren bzw. den Shop nicht abstürzen lassen. Die Prüfung soll im Core stattfinden und nicht in der Erweiterung.
    Das kann ich verstehen, auch wenn ich finde, dass es nicht zu modified passt und schade um die Performance ist... aber das ist natürlich Ansichtssache.

    Aber dafür echte Kommentare wie "... use this function to test if ..."

    Dann würde ich folgende Erweiterung von HHGAGs Regex vorschlagen:
    Code: PHP  [Auswählen]
    '/function[\s\n]+(\S+)[\s\n]*\([^\}]*\)[\s]*\{/s'
    Ist nicht für alle Eventualitäten getestet, sollte aber Fälle, wie dein Beispiel abfangen können.

    Wegen der Namespaces: Ich meinte die nicht in Verbindung mit Funktionen sondern mit Klassen und der "use" / "\" -Syntax.

    Viele Grüße
    Marcus

    hendrik

    • Experte
    • Beiträge: 2.038
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #12 am: 11. Juli 2015, 03:27:11
    ....das verpflichtend zu machen.
    Ich würde daher dafür plädieren, Funktionen zu verbieten und stattdessen aussagekräftige Klassennamen mit statischen Methoden als Standard für Erweiterungen einzuführen. Jeden einzelnen Fall kannst du ja ohnehin nicht abfangen - spätestens wenn zwei Module den gleichen Namen tragen und daher auch die gleichen Verzeichnisnamen haben, muss einer sein Modul an die Gegebenheiten anpassen.
    ....

    Verpflichten kannst du keinen zu irgendwas. Daran erkennt man halt die Erfahrung und die Qualität. Daß jemand darauf achtet, daß es zu keinen Namenskollisionen kommt. Man muß auch nicht jeden Sch... einbauen.

    Namenkollisionen in Modulen kommen selten vor. Wer Module schreibt muß das System schon anständig kennen. Und das setzt vorraus, daß man Erfahrung hat. Und wer Erfahrung hat weiß um die Problematik.
    Und wers nicht weiß, der weiß auch vieles andere nicht und dessen Produkte sind kaum von der Qualität daß man Lust hat sich eingehender damit zu beschäftigen um Namenskonflikte zu lösen.

    Gruß
    Hen

    webald

    • modified Team
    • Beiträge: 2.791
    Re: Doppelte Funktionsnamen abfangen?
    Antwort #13 am: 11. Juli 2015, 08:32:26
    Das hört sich an wie "so was braucht man nicht und wer ein Problem hat soll es irgendwie lösen". Ich finde aber, dass ein System, dass zukünftig Plug-Ins unterstützen soll/will eine robuste Schnittstelle hierfür haben soll, die eben Fehler in Modulen abfängt und den Shop weiter stabil hält.

    Namenkollisionen in Modulen kommen selten vor. Wer Module schreibt muß das System schon anständig kennen.

    Da würde ich sagen "derzeit". Wenn es eine einfach zu handelnde und funktionierende Plug-In-Lösung gibt, wird die Anzahl der Module/Lösungen (hoffentlich) steigen. Wenn man dann 3 verschiedene Statisktik-Module installiert (was ja sinnvoll sein kann), ist es doch nicht unwahrscheinlich, dass es da zu Namensgleichheiten kommen kann (z. B. GetTop10()).

    Den Shop zu kennen ist da ja nur ein Aspekt, aber man kann beim besten Willen nicht alle Module kennen. Oder der unerfahrenere User hat sich selbst ein Modul gebastelt und kauft dann beim Hen ein weiteres. Wenn es jetzt Fehler gibt, dann heißt das als erstes "seit ich das Modul vom Hen eingebaut habe geht nix mehr. Das Ding ist Mist."

    In jedem Fall ist aber eine Design-Richtlinie sinnvoll und kann auch die Benennung von Verzeichnissen (so diese überhaupt noch zusätzlich gebraucht werden), Dateien und Funktionen beinhalten. Einfache Variante: Jeder Datei und Funktion, die nicht Standard ist, wird der Forum-Name des Entwicklers vorangestellt. Also MK_neue_function() oder webald_schnapsidee() und wenn der Hen ein Kaufmodul anbietet, dann nimmt er dort halt auch hendrik_gekaufte_function() und wenn es Core-Dateien sind eben ohne Prefix.

    Ansonsten bleibt der Grundsatz: Mißtraue den Eingaben der User (und den Plug-Ins).
    1 Antworten
    907 Aufrufe
    05. November 2018, 17:35:52 von watty
    5 Antworten
    3223 Aufrufe
    19. August 2011, 14:03:58 von Tomcraft
    5 Antworten
    3137 Aufrufe
    10. April 2012, 15:53:21 von xeron
    15 Antworten
    7475 Aufrufe
    09. Juni 2013, 13:19:20 von MarcusS81