Libraries dürfen nichts anderes als Funktionen erhalten

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Libraries dürfen nichts anderes als Funktionen erhalten

    Hi,

    ich glaube ich bin auf eines meiner größten Denkprobleme gestoßen seit ich PHP verwende. Vielleicht kennt ihr ja EyeOS (Google-Suche hilft..). Da gibt es beispielsweise die Möglichkeit in einem Ordner Applikationen zu schreiben. Wenn aber in einer Application oder einem Service z.B. ein echo 'Test'; oder ein die('Error'); oder ein fehlerhafter Code wie 'ech 'Hall;' steht, dann wird die Datei sozusagen ignoriert. Also das Script läuft ohne dies weiter.
    Ich meine, dass ich eine Datei includen will, die z.B. so aussehen kann:
    write.php

    Quellcode

    1. <?php
    2. function write_run(){
    3.    //Meine Funktion zum Schreiben
    4. }
    5. ?>

    Nun darf aber vor und hinter der Funktion nichts anderes stehen außer andere Funktionen. Das heißt das Script soll selber nichts machen können außer Funktionen (vllt. auch Klassen) zu definieren. Ich kenne die Funktionen is_callable - damit kann ich abfragen, ob die Funktion aufrufbar ist (oder mit function_exists ob sie überhaupt existiert), aber ich kann nicht sagen, dass ich die Datei nur includen will, wenn sozusagen nur Funktionen definiert sind.

    Bisher war mein einzigster Gedanke, die Datei mit regulären Ausdrücken zu "parsen" und somit festzustellen, ob sie gültig ist (also ob sie echos oder ähnliches enthält / einem bestimmten Schema entspricht) aber ich erachte das als etwas komplex und ziemlich performance-lastig. Wisst ihr zufällig wie das bei EyeOS gemacht wird bzw wie man so etwas anstellen könnte?


    Gruß
  • Ich kenne das system zwar nicht und weiß auch nichts darüber, aber kann die den Sinn erklären :)

    Mann kann zwar in einer Funktion echo blabla schreiben, macht es aber nicht, sowie ich das verstehen (was du geschrieben hast) hört sich das nach einem Model-View-Controller prinzip an, was bewirkt das dein Code strikt von der Anwendung getrennt wird. Bzw du arbeitest somit 100%ig OOP.

    MVC ist etwas Resourcen lastiger gebe ich zu, jeodch lohnt sich das, wenn beknackte schleifen baust sind die auch Resourcen lastig, Ich gebe gerne Resourcen aus, wenn es sich lohnt! Außerdem sollte man abwegen, Sicherheit Perfomance. Keine Abfragen keine Auslastung, aber das thema lassen wir mal, denn das schreit nach FlameWar :)

    Wenn EyeOS so arbeitet, dann arbeite dich da ruig rein, es lohnt sich!
    Erst wenn der letzte FTP Server kostenpflichtig, der letzte GNU-Sourcecode verkauft, der letzte Algorithmus patentiert, der letzte Netzknoten kommerzialisiert, die letzte Newsgroup moderiert wird, werdet Ihr merken, dass man mit Geld allein nicht programmieren kann.
  • Damit arbeite ich im Prinzip bereits und das meinte ich auch nicht :)
    Hatte ich mich so schlecht ausgedrückt? xD

    Ich meinte.. nunja, sagen wir es gibt eine index.php. In diese möchte ich die functions.php includen, aber nur, wenn diese nichts anderes als Funktionen enthält, also wenn z.B. der php-Code in functions.php einen Fehler erzeugen würde, wird sie nicht included.
    Ich wüsste jetzt nicht, wie ich es lösen sollte =/
  • Ich hinke auch etwas hinterher, was genau deine Frage ist.
    Du willst auch ein so schönes Error Handling wie in EyeOS? Korrekt?

    Also bis auf Syntaxfehler kannst du alles mit den mitteln von PHP abfangen und "bunt" handeln.
    • [phpdoc]errorfunc[/phpdoc]
    • [phpdoc]error-reporting[/phpdoc]
    Alles weitere wird bestimmt in einer Sandbox ausgeführt. Also ein eigenständiger Apache mit strengen Regeln was Ausführungszeit, Schreibzugriff, etc betrifft wird dein PHP evaluieren und das original Script wartet dessen Ausgabe ab.

    Um darauf zurückzukommen, dass nur Funktionen in einer Datei sein dürfen. Darauf hat PHP bestimmt keinen Einfluss. Das lässt sich aber mit einem einfachen regulären Ausdruck bei der ersten Verwendung feststellen. Und wenn dein Code durch den Pattern gematcht und "freigeschaltet" wurde, muss auch nichts mehr getestet werden, bis du wieder etwas an der Funktion änderst.
    Es kostet also nicht bei jedem Scriptaufruf Performance.
  • Hi,

    hatte die Funktion noch auf meinem PC, da ich mal die gleiche Idee hatte. Weis nicht mehr genau woher ich sie habe, aber denke sie hilft.

    Quellcode

    1. <?php
    2. function check_syntax($code) // Den Code übergeben, vielleicht vorher eine Datei einlesen
    3. {
    4. $b = 0;
    5. foreach (token_get_all($code) as $token) // spaltet den Text auf
    6. {
    7. if ('{' == $token) ++$b;
    8. else if ('}' == $token) --$b;
    9. }
    10. if ($b) return false; // Wenn die Klammern falsch gesetzt sind, gibt er ein false zurück
    11. else
    12. {
    13. ob_start(); // Speichert Error Meldungen
    14. $code = eval('if(0){' . $code . '}'); // Öffnet den Code in einer Sandbox und lässt ihn unausgeführt laufen
    15. ob_end_clean();
    16. return false !== $code;
    17. }
    18. }
    19. ?>
    Alles anzeigen


    Der prüft ob der Code einen Fehler erzeugt.

    Matthze
  • Bei sowas empfehle ich die eine richtige Sandbox, weil mit php basis mitteln kann man zwar einiges machen, jedoch bist du in eine eigenen, abgeschotteten Sanbbox besser bedient.

    SeBa schrieb:

    Never trust the client
    All incoming data is evil


    PS: finde die Signatur von SeBa einfach nur geil :)
    Erst wenn der letzte FTP Server kostenpflichtig, der letzte GNU-Sourcecode verkauft, der letzte Algorithmus patentiert, der letzte Netzknoten kommerzialisiert, die letzte Newsgroup moderiert wird, werdet Ihr merken, dass man mit Geld allein nicht programmieren kann.
  • Ich will nicht, dass User Scripte hochladen können, sondern ich möchte eine Art Konsole (klingt jetzt im ersten Moment mit php sicher lächerlich) schreiben, bei der ich eben Systemfunktionen schreibe. Habe jetzt auch eine Lösung:

    Quellcode

    1. function service($file, $name){
    2. if(!checkLoaded($name)){
    3. $file = str_replace('..', '', $file);
    4. $file = str_replace('/', '', $file);
    5. $tokens = sandbox(ICOMMAND_ROOT . '/' . SYSTEM_DIR . '/' . SERVICE_DIR . '/' . $file);
    6. if(!check_syntax($tokens)){
    7. return false;
    8. }
    9. @require_once(ICOMMAND_ROOT . '/' . SYSTEM_DIR . '/' . SERVICE_DIR . '/' . $file);
    10. $init = $name . '_init';
    11. if(function_exists($init) && is_callable($init)){
    12. $init();
    13. }
    14. setLoaded($name);
    15. }
    16. else{
    17. return false;
    18. }
    19. return true;
    20. }
    Alles anzeigen

    Quellcode

    1. function check_syntax($tokens){
    2. if(!is_array($tokens)){
    3. return false;
    4. }
    5. foreach($tokens as $token){
    6. list($id, $text) = $token;
    7. switch($id){
    8. case T_ECHO:
    9. case T_EXIT:
    10. case T_GLOBAL:
    11. case T_INCLUDE:
    12. case T_INCLUDE_ONCE:
    13. case T_INLINE_HTML:
    14. case T_REQUIRE:
    15. case T_REQUIRE_ONCE:
    16. case T_PRINT:
    17. //alle unerwünschten Teile melden
    18. return false;
    19. default:
    20. // alle anderen unverändert beibehalten
    21. break;
    22. }
    23. }
    24. return true;
    25. }
    Alles anzeigen


    Damit garantiere ich, dass keine Ausgaben stattfinden (oder Beendigungen) und gleichzeitig tritt durch das "@" kein Fehler auf =)



    lG