mod: Konstruktor: Klasse erst später definiert

0 55

Konstruktor: Klasse erst später definiert

mod
  • php
  1. 0
    mod
  2. 0
    dedlfix
    1. 0
      mod
      1. 0
        mod
        1. 1
          Sven Rautenberg
          1. 0
            mod
          2. 0
            mod
            1. 0
              dedlfix
              1. 0
                mod
                1. 0
                  Sven Rautenberg
                  1. 0
                    mod
                    1. 0
                      dedlfix
            2. 0
              Sven Rautenberg
              1. 0
                hotti
                1. 0
                  Sven Rautenberg
                  1. 0
                    hotti
                    1. 2
                      Sven Rautenberg
              2. 0
                mod
        2. 0
          dedlfix
          1. 0
            mod
            1. 0
              hotti
              1. 0
                mod
                1. 0
                  hotti
                  1. 0
                    dedlfix
                    1. 0
                      hotti
                      1. 0
                        dedlfix
                        1. 0
                          hotti
                          1. 0
                            dedlfix
                            1. 0
                              Sven Rautenberg
                              1. 0
                                hotti
                                1. 0
                                  dedlfix
                                  1. 0
                                    hotti
                                    1. 0
                                      dedlfix
                              2. 0
                                asdf
                            2. 0
                              hotti
                              1. 0
                                Sven Rautenberg
                                1. 0
                                  hotti
                                  1. 1
                                    Sven Rautenberg
                                    1. 0
                                      hotti
                                2. 1
                                  asdf
                              2. 0
                                dedlfix
                                1. 0
                                  hotti
                                  1. 0
                                    dedlfix
                                    1. 0
                                      hotti
                                      1. 1
                                        Sven Rautenberg
            2. 0
              dedlfix
      2. 0
        dedlfix
        1. 0
          Tom
          1. 0
            dedlfix
  3. 0
    hotti
    1. 0

      @mod Vorsicht

      Christopher
      1. 0
        hotti
        1. 0
          Tom
          1. 0
            hotti

Hallo,

Ich habe ein Klasse head, wo ich per Konstruktor andere Variablen und Klassen hereinlade. Mein Problem ist, dass die Klasse head später im Programm eine andere Klasse namens underClass benötigt und mit dieser auch arbeitet! Diese kann ich ja nicht wie bei der Definition von head hereinladen, da diese noch nicht existent ist. underClass benötigt wiederum die Klasse $head selber.

Ein Beispiel: Forum - Rechte

Mit einer Klasse 'Forum' werden erstmal Foren-IDs gesammelt. Diese benötigt die Klasse 'Rechte' um die zu den Foren-IDs passenden Rechte zu laden. Die Klasse 'Rechte' wird widerum in der Klasse 'Forum' wieder benötigt um Foren-Features wie Themabewertung, Umfragen bspw. an- oder auszuschalten.

$forum = new Forum ( $config, ... );
...
$rechte = new Rechte ( $forum, ... )

Wie kann ich die Klasse 'Rechte' jetzt SAUBER in die Klasse 'Forum' per Referenz reinladen ?

Gruß mod

  1. Dieser Thread baut auf dem Thread: (PHP) Auf Variablen innerhalb einer Objektkomposition zu greifen - http://forum.de.selfhtml.org/?t=208957&m=1421668 auf.

  2. Tach!

    Ich habe ein Klasse head, wo ich per Konstruktor andere Variablen und Klassen hereinlade. Mein Problem ist, dass die Klasse head später im Programm eine andere Klasse namens underClass benötigt und mit dieser auch arbeitet! Diese kann ich ja nicht wie bei der Definition von head hereinladen, da diese noch nicht existent ist. underClass benötigt wiederum die Klasse $head selber.

    Definiere "noch nicht existent". Unterscheide bitte außerdem zwischen Klasse und Objekt.

    PHP macht zunächst einen Compilierlauf, bevor es mit der Ausführung anfängt. Klassen und Funktionen, die später im Script stehen, sind bereits "weiter oben" bekannt. Zudem ist es kein großer Akt, Klassen und Funktionen zuerst zudefinieren oder die Dateien zu inkludieren, in denen sie stehen. Klassen sind also immer da. Anders sieht das eventuell mit Objekten aus, also Instanzen der Klassen.

    Ein Beispiel: Forum - Rechte

    Erklär zu dem Beispiel bitte die Anforderung ohne auf technische Implementierungsdetails einzugehen. Vielleicht kann man den Knoten ja anderweitig entwirren. Zum Beispiel so, dass ein Rechte-Objekt einmalig für den aktuellen User angelegt wird und dieses dann an die Komponenten weitergereicht wird, die es benötigen.

    Mit einer Klasse 'Forum' werden erstmal Foren-IDs gesammelt. Diese benötigt die Klasse 'Rechte' um die zu den Foren-IDs passenden Rechte zu laden. Die Klasse 'Rechte' wird widerum in der Klasse 'Forum' wieder benötigt um Foren-Features wie Themabewertung, Umfragen bspw. an- oder auszuschalten.

    Das hört sich so an, als ob zu deiner Rechte-Klasse lediglich eine einzelne Instanz benötigt wird, die Rechteabfrage also mehr oder weniger statisch erfolgt.

    Wie kann ich die Klasse 'Rechte' jetzt SAUBER in die Klasse 'Forum' per Referenz reinladen ?

    Um Referenzen musst du dir im Prinzip keine Gedanken machen. Sie werden bei Objekten ab PHP5 immer verwendet, wenn du nicht explizit gegen sie arbeitest. Sobald du also eine Variable hast, die auf ein Objekt verweist, hast du eine Referenz.

    dedlfix.

    1. Ich habe ein Klasse head, wo ich per Konstruktor andere Variablen und Klassen hereinlade. Mein Problem ist, dass die Klasse head später im Programm eine andere Klasse namens underClass benötigt und mit dieser auch arbeitet! Diese kann ich ja nicht wie bei der Definition von head hereinladen, da diese noch nicht existent ist. underClass benötigt wiederum die Klasse $head selber.

      Definiere "noch nicht existent". Unterscheide bitte außerdem zwischen Klasse und Objekt.

      Ich meine ein Objekt, dass ich in einem anderen Objekt verwenden möchte.

      PHP macht zunächst einen Compilierlauf, bevor es mit der Ausführung anfängt. Klassen und Funktionen, die später im Script stehen, sind bereits "weiter oben" bekannt. Zudem ist es kein großer Akt, Klassen und Funktionen zuerst zudefinieren oder die Dateien zu inkludieren, in denen sie stehen. Klassen sind also immer da. Anders sieht das eventuell mit Objekten aus, also Instanzen der Klassen.

      Ein Beispiel: Forum - Rechte

      Erklär zu dem Beispiel bitte die Anforderung ohne auf technische Implementierungsdetails einzugehen. Vielleicht kann man den Knoten ja anderweitig entwirren. Zum Beispiel so, dass ein Rechte-Objekt einmalig für den aktuellen User angelegt wird und dieses dann an die Komponenten weitergereicht wird, die es benötigen.

      Ich wollte wie du es bereits im letzten Thread gesagt hast, das komplette Objekt in ein anderess Objekt per Referenz inkludieren.

      1. hier mal das Skript, aber am Beispiel von Session und Zeitzone, im Sinne das gleiche Problem.

        $time = new Time( $cfg, $session ); // Konfiguration $cfg einlesen, $session gebraucht um lokale Zeit-Zone zu setzen. <-- NOTICE-Meldung, dass es nicht existiert.
        $output = new Output( $cfg ); // Template-System starten
        $db = new MySQL( $output ); // Datenbank-Start
        $db->start();
        $session = new Session( $cfg, $db, $output, $time ); // Start der Sitzung
        $session->start(); // lokale Zeitzone des Users wird geladen.
        $time->configurate(); // $session wird benötigt um lokale Zeit-Zone, Zeitverschiebung zu setzen.

        1. Moin!

          hier mal das Skript, aber am Beispiel von Session und Zeitzone, im Sinne das gleiche Problem.

          $time = new Time( $cfg, $session ); // Konfiguration $cfg einlesen, $session gebraucht um lokale Zeit-Zone zu setzen. <-- NOTICE-Meldung, dass es nicht existiert.
          $output = new Output( $cfg ); // Template-System starten
          $db = new MySQL( $output ); // Datenbank-Start
          $db->start();
          $session = new Session( $cfg, $db, $output, $time ); // Start der Sitzung
          $session->start(); // lokale Zeitzone des Users wird geladen.
          $time->configurate(); // $session wird benötigt um lokale Zeit-Zone, Zeitverschiebung zu setzen.

          Mal ganz ehrlich: Deine Abhängigkeiten sind doch eher abstrus, das würde ich so nicht bauen wollen.

          Nur so als Beispiel: Deine Datenbankanbindung braucht das Template-System? WTF? Datenbank und Templates haben nach meiner Ansicht nichts miteinander zu tun. Datenbanken liefern Daten. Templates konsumieren Daten. Der Controller sorgt dafür, dass die Daten aus der DB kommen und ins Template geschoben werden.

          Dasselbe gilt für die Session. Bestenfalls braucht die Session eine Datenbank zum Wegspeichern - das ist aber nicht dieselbe Datenbank, die man sonst noch so braucht, um Daten ins Template zu tun. Und das Template gehört ganz sicher auch nicht in die Session. Allenfalls gehören Daten aus der Session in das Template - das regelt dann der Controller oder irgendeine Komponente, die pauschal immer bei jedem Aufruf läuft - und an dieser Stelle würde man z.B. auch gleich die Rechte checken, mit einer ACL-Komponente.

          Insofern besteht deshalb auch keine technische Notwendigkeit, das dein Time-Objekt auf das Session-Objekt zugreifen muss. Damit würdest du dir tatsächlich eine zirkuläre Referenzkette aufbauen - du kämst von Time auf Session, und von dort wieder auf Time.

          Zirkuläre Referenzen sind immer ein Zeichen von mangelhafter Architektur. Du solltest das dringend überarbeiten.

          - Sven Rautenberg

          1. Hallo Sven,

            du hast leider komplett Recht. Ich werde wahrscheinlich alle Klassen voneinander trennen und die Variablen/Abhängigkeiten, die benötigt werden in die Funktionen eines Objektes einfügen in denen sie auch gebraucht werden.

            Die von dedlfix vorgestellte Methode alle Abhängigkeiten per Referenz über den Konstruktor reinzuladen ist die beste und 'sauberste' Methode.

            Meine Architektur sieht wie folgt aus

            DB(Datenbank-Anbindung)
            TIME(Zeit & Zeitzone)
            OUTPUT(Template)
            SESSION(Sitzungsdaten, Forenfeatures bzgl einer Sitzung)
            FORUM(Themen, Beiträge, Umfragen ...)
            RIGHTS(Rechte zu allen Foreninstanzen und Mitgliedern- und gruppen)

            und alle Abhängigkeiten per $objekt->function( $var1[, $var2 ...] ) inkludieren.

            $cfg als Variable und $db als Datenbank kann man gut per Konstruktor reinladen, aber das Andere scheint mir unspezifisch.

          2. Nur so als Beispiel: Deine Datenbankanbindung braucht das Template-System? WTF? Datenbank und Templates haben nach meiner Ansicht nichts miteinander zu tun. Datenbanken liefern Daten. Templates konsumieren Daten. Der Controller sorgt dafür, dass die Daten aus der DB kommen und ins Template geschoben werden.

            Wie könnte man SQL-Fehlermeldungen aus DB an OUTPUT übergeben ohne OUTPUT in DB einzufügen?

            1. Tach!

              Wie könnte man SQL-Fehlermeldungen aus DB an OUTPUT übergeben ohne OUTPUT in DB einzufügen?

              Was willst du damit in der Ausgabe? Fehlermeldungen, die irgendetwas über das System preisgeben, gehören ins Log für den Administrator. Fehlerzustände werden an den Aufrufer signalisiert (beispielsweise mit einer Exception) und der ändert dann den Text der Ausgabe in eine für den jeweiligen Anwendungsfall und für den Anwender möglichst sinnvolle Variante.

              dedlfix.

              1. Das Fehlerausgabesystem ist Teil des Template-Systems und springt an wenn ein beispielsweise ein DB-Fehler auftritt, deshalb wird das Template-System mit in die DB-Klasse geladen und das Script sofort beendet.

                [code=php]

                class MySQL {
                public $count = 0;
                    public $error = 'ERROR_SQL';
                    public $fields = array();
                    public $linkID = 0;
                    public $output = '';
                    public $result = '';

                function __construct( $output )
                    {
                        $this->setOutput( $output );
                    }

                function setOutput( $output )
                    {
                        $this->output = $output;
                    }

                function connect()
                    {
                        $this->linkID = @mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );

                if ( ! $this->linkID ) {
                            $this->output->createMessage( $this->error, 'DB_NO_CONNECTION' );
                        }
                    }

                function errno()
                    {
                        return mysql_errno( $this->linkID );
                    }

                function error()
                    {
                        return mysql_error( $this->linkID );
                    }

                function start()  
                {  
                	$this->connect();  
                	$this->selectDatabase();  
                }  
                

                }

                $output = new Output( $cfg );
                $db = new MySQL( $output );
                $db->start();[/code]

                1. Moin!

                  Das Fehlerausgabesystem ist Teil des Template-Systems und springt an wenn ein beispielsweise ein DB-Fehler auftritt, deshalb wird das Template-System mit in die DB-Klasse geladen und das Script sofort beendet.

                  An dem Code ist einiges kritikwürdig.

                  Erstens: Die Datenbank-Klasse sollte von keinerlei Template-System wissen.
                  Zweitens: Die Datenbank-Klasse sollte keinen Aufruf "start()" erfordern. Eine DB-Verbindung stellt man dann her, wenn man den ersten Query verarbeitet, oder pauschal einfach beim Instanziieren der Klasse im Konstruktor.

                  In meiner Welt hat eine DB-Klasse sich ganz am Rand des Klassenbaumes einzusortieren. Zum einen muss die Klasse mit externen Systemen kommunizieren (die Datenbank), schon allein deshalb gehört die Klasse mit keiner weiteren Abhängigkeit belastet, sondern muss ausschließlich nur DB-Dinge tun. Denn das muss ja auch getestet werden, und so ein Test, der eine lauffähige Datenbank erfordert, ist immer aufwendig zu programmieren.

                  - Sven Rautenberg

                  1. An dem Code ist einiges kritikwürdig.

                    Deswegen habe ich ihn auch gepostet. Nur aus Fehlern lernt man!

                    Erstens: Die Datenbank-Klasse sollte von keinerlei Template-System wissen.

                    Sehe ich vollkommen auch so! Jede Klasse sollte möglichst ohne den Einfluss anderer Klassen arbeiten. Könntest du mir bitte an einem Code-Beispiel zeigen, wie du bspw. eine fehlgeschlagene Verbindung aus einem DB-Objekt an ein ErrorHandling-Objekt senden würdest, damit dies die passende Aktion durchführt.

                    Zweitens: Die Datenbank-Klasse sollte keinen Aufruf "start()" erfordern.

                    Gut da gehe ich mit.

                    Eine DB-Verbindung stellt man dann her, wenn man den ersten Query verarbeitet

                    Ich persönlich mag das nicht, dass die Fehlermeldung aus einem anderem Objekt kommt, in der ein DB-Query stattfindet.

                    oder pauschal einfach beim Instanziieren der Klasse im Konstruktor.

                    ... der Klasse DB - gut, aber nirgendwo anders.

                    Mit deinen Vorschlägen:

                    class MySQL {
                    public $count = 0;
                        public $errorMessage = '';
                        public $errorType = 'ERROR_SQL';
                        public $fields = array();
                        public $linkID = 0;
                        public $output = '';
                        public $result = '';

                    function __construct( $output )
                        {
                             $this->connect();
                             $this->selectDatabase();
                        }

                    function connect()
                        {
                            $this->linkID = @mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );

                    if ( ! $this->linkID ) {
                                $this->setError( 'DB_NO_CONNECTION' );
                            }
                        }

                    function errno()
                        {
                            return mysql_errno( $this->linkID );
                        }

                    function error()
                        {
                            return mysql_error( $this->linkID );
                        }

                    function setError( $type )
                        {
                             $this->errorMessage = $type;
                        }
                    }

                    Wie würdest du die Fehlermeldung an ein ErrorHandling-Objekt übergeben?

                    1. Tach!

                      Ich persönlich mag das nicht, dass die Fehlermeldung aus einem anderem Objekt kommt, in der ein DB-Query stattfindet.

                      Das einzige Standardverhalten in einem Fehlerfall wäre das Logging für den Administrator, und auch das ist nicht bei jedem Fehler notwendig. Alle weiteren Fehler müssen individuell beim Aufrufenden behandelt werden. Die Datenbank-Klasse weiß nicht, ob zum Beispiel ein mit einer Unique-Constraint-Verletzung beendetes Insert ein Fehler ist oder vom Aufrufer so beabsichtigt war. Deren Aufgabe ist nur, den Fehler an den Aufrufer zu melden. Der weiß besser, wie er darauf reagieren soll. Insofern wirft die Datenbankklasse lediglich eine Exception und fertig ist ihre Fehlerbehandlung. Die aufrufende Stelle hingegen fängt sie ab und reagiert für ihren Anwendungsfall angemessen - oder delegiert die Behandlung weiter nach oben, indem sie die Exception neu wirft, sie dazu vielleicht umpackt oder sie einfach ungefangen nach oben durchlässt. Das muss man jeweils individuell entscheiden.

                      Damit wäre prinzipiell auch diese Frage geklärt:

                      Sehe ich vollkommen auch so! Jede Klasse sollte möglichst ohne den Einfluss anderer Klassen arbeiten. Könntest du mir bitte an einem Code-Beispiel zeigen, wie du bspw. eine fehlgeschlagene Verbindung aus einem DB-Objekt an ein ErrorHandling-Objekt senden würdest, damit dies die passende Aktion durchführt.

                      Wirf eine Exception.

                      Dazu aber eine Warnung. Exceptions sind kein Allheilmittel. Wenn beispielsweise ein Teilstring in einem String nicht gefunden wird, kann das eine Ausnahme sein, muss aber nicht. In der Regel wird man das durch ein entsprechendes Funktionsergebnis (false statt Position) und nicht mit einer Exception signalisieren. Auch für das Beispiel von oben lässt sich sicher streiten, ob das nun eine Ausnahme war oder ob man dieses beabsichtigte Auflaufen auf diesen Fehler vielleicht der Datenbank-Klasse als normales Verhalten beibringt. Der Hintergrund für die beabsichtigte Unique-Constraint-Verletzung ist, ein TOCTTOU-Problem zu vermeiden. Wenn man sicherstellen möchte, dass ein Name (vielleicht ein Login) nur einmal auftritt, legt man besser einen Unique-Index auf das Feld und lässt Inserts ohne weitere Prüfung in diese Tabelle laufen. Bei Dopplungen gibt es den erwähnten Fehler, ansonsten läuft das Insert rein. Vorher das DBMS zu befragen, ob ein solcher Name bereits vorhanden ist, ist ungünstig, denn zwischen der Abfrage und dem Eintragen könnte sich jemand anderes drängeln. Nicht immer also ist ein Fehler auch eine Ausnahme.

                      dedlfix.

            2. Moin!

              Nur so als Beispiel: Deine Datenbankanbindung braucht das Template-System? WTF? Datenbank und Templates haben nach meiner Ansicht nichts miteinander zu tun. Datenbanken liefern Daten. Templates konsumieren Daten. Der Controller sorgt dafür, dass die Daten aus der DB kommen und ins Template geschoben werden.

              Wie könnte man SQL-Fehlermeldungen aus DB an OUTPUT übergeben ohne OUTPUT in DB einzufügen?

              Ich erweitere die Fragestellung mal: Wie könnte man Fehler, die IRGENDWO auftreten, und die nicht ignorierbar oder mit Default-Werten heilbar sind, für den Admin und den User so melden, dass der Admin das Problem im Logfile sieht, und der User eine hilfreiche, aber nicht zu konkrete Fehlermeldung kriegt?

              Antwort: Exceptions werfen und fangen.

              Objektorientiertes Programmieren ohne Exceptions ist wie Radfahren mit platten Reifen: Es geht zwar, aber man kommt irgendwie nicht wirklich vorwärts. :)

              Das letzte Mal über Klassenstrukturen und Exceptions diskutiert hatte ich vermutlich hier.

              - Sven Rautenberg

              1. hi Sven,

                Objektorientiertes Programmieren ohne Exceptions ist wie Radfahren mit platten Reifen: Es geht zwar, aber man kommt irgendwie nicht wirklich vorwärts. :)

                Das gefällt mir außerordentlich gut ;)

                Da komme ich gerne zurück auf Deine Aussage, dass sich ein Perl-Programmierer um jeden Scheis selber kümmern muss, gerade das ist nämlich in Perl ganz einfach, guck:

                  
                # Controller, dem URL http://example.com/admintools.html zugeordnet  
                sub admintools{  
                  my $self = shift;  
                  die "Nicht angemeldet!\n" if $self->{LOGIN_GROUP} ne $self->{REQUIRED_GROUP};  
                }  
                
                

                Dahinter steckt Perl's Exception-Model: Ich werfe in der Methode eine Exception, die ich später auffange, um mit der eigens notierten Meldung eine klar verständliche Fehlerseite ausgeben zu können (beachte das \n am Ende der Meldung, das unterdrückt den Backtrace, weil diese Meldung für den Besucher bestimmt ist und nicht für den Programmierer).

                Aber das ist nicht alles. Perl gibt mit dem Modul 'UNIVERSAL' dem Programmierer die Möglichkeit, abzufragen, ob es in der Klasse eine bestimmte Methode gibt:

                  
                my $code = $self->can('admintools');  
                
                

                Habe ich den $code, kann ich den ausführen und dabei auf Exceptions testen:

                  
                eval{$self->$code};  
                
                

                Ist eine Exception aufgetreten, steht der Fehlertext in $@, Seite ausgeben, fertig.

                Hotti

                1. Moin!

                  Da komme ich gerne zurück auf Deine Aussage, dass sich ein Perl-Programmierer um jeden Scheis selber kümmern muss, gerade das ist nämlich in Perl ganz einfach, guck:

                  Controller, dem URL http://example.com/admintools.html zugeordnet

                  sub admintools{
                    my $self = shift;
                    die "Nicht angemeldet!\n" if $self->{LOGIN_GROUP} ne $self->{REQUIRED_GROUP};
                  }

                  
                  >   
                  > Dahinter steckt Perl's Exception-Model: Ich werfe in der Methode eine Exception, die ich später auffange, um mit der eigens notierten Meldung eine klar verständliche Fehlerseite ausgeben zu können (beachte das \n am Ende der Meldung, das unterdrückt den Backtrace, weil diese Meldung für den Besucher bestimmt ist und nicht für den Programmierer).  
                    
                  Ich sehe nicht, dass da irgendwas geworfen oder gefangen wird.  
                    
                  
                  > Aber das ist nicht alles. Perl gibt mit dem Modul 'UNIVERSAL' dem Programmierer die Möglichkeit, abzufragen, ob es in der Klasse eine bestimmte Methode gibt:  
                  >   
                  > ~~~perl
                    
                  
                  > my $code = $self->can('admintools');  
                  > 
                  
                  

                  Kann Perl keine Interfaces und keine typisierten Parameter?

                  In PHP geht sowas nämlich ohne dumme Prüfung:

                  function (Admintools_Interface $admintools) {  
                     $admintools->makeSomeAdminStuff();  
                  }
                  

                  Aber natürlich kann man auch manuell prüfen:

                  if (method_exists($admintools, 'makeSomeAdminStuff')) { /*...*/ }

                  Habe ich den $code, kann ich den ausführen und dabei auf Exceptions testen:

                  eval{$self->$code};

                    
                  "eval is evil!"  
                    
                   - Sven Rautenberg
                  
                  1. hi,

                    Kann Perl keine Interfaces und keine typisierten Parameter?

                    Typisierte Parameter? Wir reden hier von HTTP. Wenn es da Parameter gibt, sind das immer Scalare.

                    Ich sehe nicht, dass da irgendwas geworfen oder gefangen wird.

                    Die Perl-Funktion die(); wirft eine Exception, eval{} fängt sie auf und die Prüfung, ob es eine gab, beschränkt sich darauf, $@ zu fragen. Wenn es keine Exception gab, ist $@ leer.

                    Hotti

                    1. Moin!

                      Kann Perl keine Interfaces und keine typisierten Parameter?

                      Typisierte Parameter? Wir reden hier von HTTP. Wenn es da Parameter gibt, sind das immer Scalare.

                      Du beweist wieder einmal, dass du von OOP in PHP nicht die leiseste Ahnung hast.

                      Ich sehe nicht, dass da irgendwas geworfen oder gefangen wird.

                      Die Perl-Funktion die(); wirft eine Exception, eval{} fängt sie auf und die Prüfung, ob es eine gab, beschränkt sich darauf, $@ zu fragen. Wenn es keine Exception gab, ist $@ leer.

                      Ich finde es interessant, dass du hier das altertümlichste Exception-Handling vorträgst, das Perl zu bieten hat. Man könnte Exception-Objekte werfen, wenn man wüsste, wie - Google hilft.

                      Man kommt dann aber auch zu der Erkenntnis, dass Perl eigentlich kein wirklich schönes Exception-Handling hat. die() ist eben nicht throw, und eval/if ist nicht try/catch.

                      Ich halte mal fest: Perl ist, was OOP angeht, nie aus dem Sonderling-Status rausgekommen. Und das, was Perl an OOP kann, ist mit keiner anderen Sprache, die auch OOP kann, vergleichbar. Insofern wäre es gut, wenn du dich bei Diskussionen zu OOP, die nicht Perl betreffen, einfach zurückhalten würdest. Du hast offenbar keine Ahnung von PHP, also führe die Fragesteller nicht mutwillig in die Irre. Danke!

                      - Sven Rautenberg

              2. Hallo,

                dann ist es die beste Lösung, wenn ich das Fehlersystem aus dem Template-System herauslöse, es als eigenes Objekt/Klasse definiere und nur das neue ERRORHandling-Objekt in die Objekte lade. Später gibt es mehr

        2. Tach!

          hier mal das Skript, aber am Beispiel von Session und Zeitzone, im Sinne das gleiche Problem.

          $time = new Time( $cfg, $session ); // Konfiguration $cfg einlesen, $session gebraucht um lokale Zeit-Zone zu setzen. <-- NOTICE-Meldung, dass es nicht existiert.
          $session = new Session( $cfg, $db, $output, $time ); // Start der Sitzung
          $session->start(); // lokale Zeitzone des Users wird geladen.
          $time->configurate(); // $session wird benötigt um lokale Zeit-Zone, Zeitverschiebung zu setzen.

          Du hast hier also einen zirkulären Bezug. Die Zeit benötigt eine Session für die Zeitzone, die Session benötigt eine Zeit für ihre Startzeit, die Startzeit braucht aber wieder eine Zeitzone aus der Session ... Diesen Konflikt kannst du auflösen, indem du die Zeit als UTC ablegst und die Zeitzone erst bei der Ausgabe berücksichtigst.

          Ansonsten benötigt Time ja keine komplette Session sondern lediglich die Zeitzoneninformation. Also würde ich da auch nur diese eine Information übergeben. Und damit kannst du sie separat ermitteln, wenn du sie in der Session noch nicht verfügbar hast.

          dedlfix.

          1. Genau so ist es: Im Objekt $time befindet sich coreTime, die Zeit als UTC, wie du es sagtest. Diese Zeit $time->coreTime benötigt das Objekt $session um alte Sitzungen zu löschen und eine Session anzulegen, deren Verfallsdauer etc festzulegen. Dann werden Info's zum User und der aktuellen Sitzung geladen: lokale Zeitzone und diese benötigt $time->configurate um Zeitverschiebung zu ermitteln.
            Es geht mir jetzt darum eine einheitliche Methode zu finden, Daten eines Objektes in ein anderes Objekt zu inkludieren. Entweder komplette Verbindung mit Instanzen also $time als Instanz von $session: $session->time oder komplette Trennung der Klassen und inkludieren aller benötigten Abhängigkeiten in Funktionen, in denen sie gebraucht werden.

            1. Genau so ist es: Im Objekt $time befindet sich coreTime, die Zeit als UTC, wie du es sagtest. Diese Zeit $time->coreTime benötigt das Objekt $session um alte Sitzungen zu löschen und eine Session anzulegen, deren Verfallsdauer etc festzulegen. Dann werden Info's zum User und der aktuellen Sitzung geladen: lokale Zeitzone und diese benötigt $time->configurate um Zeitverschiebung zu ermitteln.

              Zu Löschen verfallener Sessions bietet sich der Destruktor an.

              Es geht mir jetzt darum eine einheitliche Methode zu finden, Daten eines Objektes in ein anderes Objekt zu inkludieren. Entweder komplette Verbindung mit Instanzen also $time als Instanz von $session: $session->time oder komplette Trennung der Klassen und inkludieren aller benötigten Abhängigkeiten in Funktionen, in denen sie gebraucht werden.

              Frage: Warum jede Session speichern? Es genügt vollauf, die erfolgreichen Logins zu speichern, über die Instanz einer unabhängigen Login-Class, dessen Destruktor die Login-Table selbstständig aufräumt (zeitlich verfallene Logins löschen).

              Sessions, zu denen kein Login vorliegt, müssen überhaupt nicht gespeichert werden, wozu auch.

              Nichts spricht jedoch dagegen, eine Instanz der Login-Class an das 'main-Object' zu binden, also an das Objekt, über welches die gesamte Anwendung controlliert wird.

              Hotti

              --
              Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
              1. Zu Löschen verfallener Sessions bietet sich der Destruktor an.

                Ich meine damit nicht die Session als Objekt/Klasse an sich, sondern alte Sitzungsdaten innerhalb der DB, die älter als x Tage sind.

                Frage: Warum jede Session speichern? Es genügt vollauf, die erfolgreichen Logins zu speichern, über die Instanz einer unabhängigen Login-Class, dessen Destruktor die Login-Table selbstständig aufräumt (zeitlich verfallene Logins löschen).

                Per Rechte-Klasse erlaube ich Gästen an Umfragen, Themenbewertungen in bestimmten Foren teilzunehmen. Das sollte sich natürlich nicht wiederholen. Außer wenn er sich irgendwie ne neue Session-ID besorgt hat. ;-)

                Nichts spricht jedoch dagegen, eine Instanz der Login-Class an das 'main-Object' zu binden, also an das Objekt, über welches die gesamte Anwendung controlliert wird.

                Das Login-System ist bereits in der Klasse Session direkt mitinbegriffen.

                1. Zu Löschen verfallener Sessions bietet sich der Destruktor an.

                  Ich meine damit nicht die Session als Objekt/Klasse an sich, sondern alte Sitzungsdaten innerhalb der DB, die älter als x Tage sind.

                  Der Speicherort einer Session ist eine abstrakte Größe. Eine Session, zu der kein Login vorliegt, beinhaltet lediglich die Session-ID und einen Zeitstempel. Bis dahin ist eine Session uninteressant für serverseitige Prozesse und nicht wert, serverseitig gespeichert zu werden. Eine Session wird erst in dem Moment interessant, wenn bestimmte Benutzeraktionen erfolgen, z.B. ein Login: In dem Moment, wo die Credentials gesendet werden, schickt der Browser auch die SID und erst jetzt gibt es einen Grund für serverseitiges Speichern. Aber auch hier, im Fall eines erfolgreichen Login, gibt es keinen Grund die Session zu speichern, sondern einen Grund, den Erfolg des Login-Prozesses zu speichern.

                  Das Login-System ist bereits in der Klasse Session direkt mitinbegriffen.

                  Mein Vorschlag: Unterscheide in Deiner Anwendung zwischen Login und Session.

                  Hotti

                  1. Tach!

                    Eine Session, zu der kein Login vorliegt, beinhaltet lediglich die Session-ID und einen Zeitstempel. Bis dahin ist eine Session uninteressant für serverseitige Prozesse und nicht wert, serverseitig gespeichert zu werden.

                    Solche uninteressanten Dinge wie einen Warenkorb, muss man sich wirklich nicht merken. Herrn hottis Laden gestattet es erst dann Waren auszusuchen, wenn sich der Benutzer zu erkennen gegeben hat. Schließlich muss man ja auch das Verhalten im Laden einem Kunden zuordnen können und nicht nur das, was er letzlich bestellt hat.

                    Mein Vorschlag: Unterscheide in Deiner Anwendung zwischen Login und Session.

                    Genau das macht er ja bereits. Eine Session hat die Aufgabe, den Client wiederzuerkennen und die für ihn relevanten Daten festzuhalten. Das muss auch dann funktionieren, wenn sich die Person hinter dem Client noch nicht zu erkennen gegeben hat.

                    dedlfix.

                    1. hi,

                      Eine Session, zu der kein Login vorliegt, beinhaltet lediglich die Session-ID und einen Zeitstempel. Bis dahin ist eine Session uninteressant für serverseitige Prozesse und nicht wert, serverseitig gespeichert zu werden.

                      Solche uninteressanten Dinge wie einen Warenkorb, muss man sich wirklich nicht merken. Herrn hottis Laden gestattet es erst dann Waren auszusuchen, wenn sich der Benutzer zu erkennen gegeben hat. Schließlich muss man ja auch das Verhalten im Laden einem Kunden zuordnen können und nicht nur das, was er letzlich bestellt hat.

                      Was für ein Stuss. Informiere Dich bitte, bevor Du solch einen Schwachsinn schreibst.

                      Hotti

                      1. Tach!

                        Eine Session, zu der kein Login vorliegt, beinhaltet lediglich die Session-ID und einen Zeitstempel. Bis dahin ist eine Session uninteressant für serverseitige Prozesse und nicht wert, serverseitig gespeichert zu werden.

                        Solche uninteressanten Dinge wie einen Warenkorb, muss man sich wirklich nicht merken. Herrn hottis Laden gestattet es erst dann Waren auszusuchen, wenn sich der Benutzer zu erkennen gegeben hat. Schließlich muss man ja auch das Verhalten im Laden einem Kunden zuordnen können und nicht nur das, was er letzlich bestellt hat.

                        Was für ein Stuss. Informiere Dich bitte, bevor Du solch einen Schwachsinn schreibst.

                        Ich bekomme schon genug Unfug lesen, den du hier im Forum absonderst, da muss ich mir nicht noch deine Seiten antun. So wusste ich leider nicht, dass ich deinen Stuss mit deinem eigenen Shopsystem hätte widerlegen können, ohne mir einen imaginären Laden ausdenken zu müssen. Tja, manchmal mach ich halt solche Fehler.

                        dedlfix.

                        1. hi,

                          Ich bekomme schon genug Unfug lesen, den du hier im Forum absonderst, da muss ich mir nicht noch deine Seiten antun. So wusste ich leider nicht, dass ich deinen Stuss mit deinem eigenen Shopsystem hätte widerlegen können, ohne mir einen imaginären Laden ausdenken zu müssen. Tja, manchmal mach ich halt solche Fehler.

                          Kein Problem. Gerne erkläre ich Dir auch, wie das in meinem Shop funktioniert, ohne Sessions zu speichern: Es wird der Warenkorb gespeichert, an einem Ort, wo er hingehört: In der Warenkorb-Tabelle.

                          Bei einem Login wird auch nicht die Session gespeichert, sondern der Login, an einem Ort, wo er hingehört: In der Login-Tabelle.

                          Beides sind Dinge, die ich in meiner Anwendung klar voneinander trenne. Und um den Bezug zur Session herzustellen: Ja, eine Session ist dazu notwendig. Aber es ist nicht notwendig, jede Session zu speichern. Letztendlich kann das zwar jeder halten wie er will, aber ich fahre sehr gut damit, diese Dinge klar voneinander zu trennen, sowohl abstrakt als auch programmiertechnisch.

                          Viele Grüße!

                          1. Tach!

                            Gerne erkläre ich Dir auch, wie das in meinem Shop funktioniert, ohne Sessions zu speichern: Es wird der Warenkorb gespeichert, an einem Ort, wo er hingehört: In der Warenkorb-Tabelle.
                            Bei einem Login wird auch nicht die Session gespeichert, sondern der Login, an einem Ort, wo er hingehört: In der Login-Tabelle.

                            Du gibt dem Kind nur andere Namen. Es ist kein prinzipieller Unterschied, ob du den Warenkorb und das Login nun in eigenen Tabellen oder einer eigenen Zweigen einer Session-Datei speicherst. In beiden Fälle musst du eine Client-Wiedererkennung (mit eindeutiger ID über ein Cookie oder ähnlich) haben und einen temporären Speicher, den du irgendwann aufräumst.

                            Beides sind Dinge, die ich in meiner Anwendung klar voneinander trenne. Und um den Bezug zur Session herzustellen: Ja, eine Session ist dazu notwendig. Aber es ist nicht notwendig, jede Session zu speichern.

                            Definiere "Session (nicht) speichern". Eine Session ist ein Speicher zwischen mehreren Requests. Sie existiert nicht ohne zu speichern.

                            dedlfix.

                            1. Moin!

                              Gerne erkläre ich Dir auch, wie das in meinem Shop funktioniert, ohne Sessions zu speichern: Es wird der Warenkorb gespeichert, an einem Ort, wo er hingehört: In der Warenkorb-Tabelle.
                              Bei einem Login wird auch nicht die Session gespeichert, sondern der Login, an einem Ort, wo er hingehört: In der Login-Tabelle.

                              Du gibt dem Kind nur andere Namen. Es ist kein prinzipieller Unterschied, ob du den Warenkorb und das Login nun in eigenen Tabellen oder einer eigenen Zweigen einer Session-Datei speicherst. In beiden Fälle musst du eine Client-Wiedererkennung (mit eindeutiger ID über ein Cookie oder ähnlich) haben und einen temporären Speicher, den du irgendwann aufräumst.

                              Anzumerken ist außerdem, dass "hotti" nur Perl kann, und eigentlich versprochen hatte, zu PHP-Themen zu schweigen. Alle seine Äußerungen zu PHP sind deshalb leider mit extremer Vorsicht zu genießen, weil sie oftmals an den konkreten Features von PHP, die man ohne Probleme nutzen kann und sollte, vorbeigehen.

                              - Sven Rautenberg

                              1. moin,

                                Anzumerken ist außerdem, dass "hotti" nur Perl kann, und eigentlich versprochen hatte, zu PHP-Themen zu schweigen. Alle seine Äußerungen zu PHP sind deshalb leider mit extremer Vorsicht zu genießen, weil sie oftmals an den konkreten Features von PHP, die man ohne Probleme nutzen kann und sollte, vorbeigehen.

                                Ich breche mein Versprechen, wenn es um Sessions geht ;)

                                In PHP ist das Programmieren von Session-basierten Anwendungen unnnötig kompliziert, ich habe vorhin mal nachgeschaut, wieviele Built-In-Funktionen es dazu gibt. Unnötig CPU- und IO-lastig ist es denn auch, jede Session-ID, zu der keine Benutzeraktion vorliegt, serverseitig zu speichern.

                                Bei einem Berechtigungssystem ist alles, was gebraucht wird:

                                • Benutzername
                                • Benutzergruppe
                                • Zeitstempel
                                • ggf. weitere Anwendunsspezifische Felder
                                  aber  nicht die komplette Login- und schon gar nicht eine Session-Tabelle.

                                Und weils so schön ist:

                                  
                                sub gehaltsliste{  
                                  my $self = shift;  
                                  if( $self->{LOGIN_GROUP} ne $self->{REQUIRED_GROUP} ){  
                                    $self->errpush("Nicht angemeldet!");  
                                    return;  
                                  }  
                                }  
                                
                                

                                Tja, so einfach kann es sein ;)

                                Hotti

                                1. Tach!

                                  In PHP ist das Programmieren von Session-basierten Anwendungen unnnötig kompliziert, ich habe vorhin mal nachgeschaut, wieviele Built-In-Funktionen es dazu gibt. Unnötig CPU- und IO-lastig ist es denn auch, jede Session-ID, zu der keine Benutzeraktion vorliegt, serverseitig zu speichern.

                                  Es gibt einige Session-Funktionen, die vertaltet sind (register/unregister), aber immer noch mitgeschleift werden. Andere Funktionen werden für Spezialfälle verwendet. Für Wald- und Wiesen-Anwendungen kommt man mit einem session_start() und dem Zugriff auf das $_SESSION-Array aus. Einfacher geht es nicht. Und die CPU- und IO-Belastung hast du sicherlich gemessen, um eine solche Aussage treffen zu können ... Zudem wird niemand gezwungen, das session_start() aufzurufen, wenn man es in einem konkreten Script nicht benötigt, beziehungsweise seinen Aufruf solange zu verzögern, bis fest steht, dass die Session benötigt wird.

                                  Bei einem Berechtigungssystem ist alles, was gebraucht wird:
                                  [...]
                                  aber  nicht die komplette Login- und schon gar nicht eine Session-Tabelle.

                                  Session-Tabelle? Gehst du wieder von Perl aus? Werden da Session-Daten generell in einem DBMS abgelegt?

                                  dedlfix.

                                  1. hi,

                                    Session-Tabelle? Gehst du wieder von Perl aus? Werden da Session-Daten generell in einem DBMS abgelegt?

                                    Guck mal weiter oben, was ich schrieb: Der Speicherort ist eine abstrakte Größe. Das kann ein DBMS sein oder eine Datei, in Perl kann ich mir das aussuchen und in PHP kann ich das wahrscheinlich auch festlegen.

                                    Eine Abstrake Größe ist jedoch in der Anwendung selbst uninteressant: Beim Vergleichen der für eine http-Ressource erforderlichen Benutzergruppe mit der in der Browsersitzung vorliegenden Login-Gruppe ist es völlig Wurscht, welchen Wert die Session-ID hat (siehe Code in meinen anderen Posts). Und letztere gibt es bereits zu dem Zeitpunkt, wo ich mich darauf festgelegt habe, dass meine Anwendung Session-basiert ist.

                                    Hotti

                                    1. Tach!

                                      Session-Tabelle? Gehst du wieder von Perl aus? Werden da Session-Daten generell in einem DBMS abgelegt?

                                      Guck mal weiter oben, was ich schrieb: Der Speicherort ist eine abstrakte Größe. Das kann ein DBMS sein oder eine Datei, in Perl kann ich mir das aussuchen und in PHP kann ich das wahrscheinlich auch festlegen.

                                      Man kann sich einen eigenen Session-Handler schreiben und ganz am vorhandenen Session-Mechanismus vorbeiprogrammieren. Letzteres hat dann den Nachteil, dass man sich um das Aufräumen selbst kümmern muss.

                                      Eine Abstrake Größe ist jedoch in der Anwendung selbst uninteressant: Beim Vergleichen der für eine http-Ressource erforderlichen Benutzergruppe mit der in der Browsersitzung vorliegenden Login-Gruppe ist es völlig Wurscht, welchen Wert die Session-ID hat (siehe Code in meinen anderen Posts).

                                      Wieder ein Satz, dessen Sinn mir unverständlich bleibt.

                                      Wozu ist es wichtig, den Speicherort als abstrakte Größe zu betrachten, beziehungsweise hervorzuheben, dass der Speicherort für die Betrachtung, was eine Session ist, nebensächlich ist?

                                      "für eine http-Ressource erforderlichen Benutzergruppe" scheine ich noch verstanden zu haben. Diese Seite gibt es nur, bei entsprechender Berechtigung.

                                      "in der Browsersitzung" - was ist eine Browsersitzung, wenn nicht eine Session?

                                      "vorliegenden Login-Gruppe" - soll vermutlich eine Berechtigungsgruppe sein und konkret ein Wert in den Session-Daten.

                                      Und wieso ist die Session-ID uninteressant? Wird der Wert nicht benötigt, um die Session-Daten zu finden?

                                      Dein Perl-Code nützt kaum etwas. Wenn du damit etwas zu erklären/beweisen versuchst, geht das in der Regel ins Leere, weil den Diskussionsteilnehmern die notwendigen Perl-Kenntnisse fehlen.

                                      Was ist nun die Aussage? Werden deine über mehrere Requests hinweg benötigten Daten nun mit einem eindeutigen Wiedererkennungswert verknüpft gespeichert oder nicht?

                                      Und letztere gibt es bereits zu dem Zeitpunkt, wo ich mich darauf festgelegt habe, dass meine Anwendung Session-basiert ist.

                                      Wenn dir das Nicht-Anlegen einer Session-Datei wichtig ist, du aber trotzdem eine Session-ID mit dir rumschleppen möchtest, so wäre das mit der Selbstverwaltung in einem Cookie und explizitem Setzen über session_id() auch in PHP keine Unmöglichkeit. Ich sehe da nur kein positives Ergebnis im Verhältnis von (Mehr-)Aufwand und Nutzen.

                                      dedlfix.

                              2. Hi,

                                auch alle seine Äußerungen zu Perl und "objektorientierung" sind SEHR mit Vorsicht zu genießen.

                                Hth

                            2. moin,

                              Gerne erkläre ich Dir auch, wie das in meinem Shop funktioniert, ohne Sessions zu speichern: Es wird der Warenkorb gespeichert, an einem Ort, wo er hingehört: In der Warenkorb-Tabelle.
                              Bei einem Login wird auch nicht die Session gespeichert, sondern der Login, an einem Ort, wo er hingehört: In der Login-Tabelle.

                              Du gibt dem Kind nur andere Namen. Es ist kein prinzipieller Unterschied, ob du den Warenkorb und das Login nun in eigenen Tabellen oder einer eigenen Zweigen einer Session-Datei speicherst.

                              Genau hier an dieser Stelle fehlt Dir das Verständnis für das, was ich Dir versuche, zu erklären: Bei mir gibt es keine Session-Datei.

                              Definiere "Session (nicht) speichern". Eine Session ist ein Speicher zwischen mehreren Requests. Sie existiert nicht ohne zu speichern.

                              Jetzt wirds interessant ;)

                              In meinen Anwendungen ist die "Session" lediglich eine eindeutige und über die Browsersitzung konstant bleibende ID, welche zwischen dem Browser und der Anwendung ausgehandelt wird.

                              Schönen Sonntag,
                              Hotti

                              1. Moin!

                                Definiere "Session (nicht) speichern". Eine Session ist ein Speicher zwischen mehreren Requests. Sie existiert nicht ohne zu speichern.

                                Jetzt wirds interessant ;)

                                In meinen Anwendungen ist die "Session" lediglich eine eindeutige und über die Browsersitzung konstant bleibende ID, welche zwischen dem Browser und der Anwendung ausgehandelt wird.

                                Und wenn ein Warenkorb zu speichern ist, speicherst du die zugehörige ID zum Warenkorb mit ab, oder?

                                Ergo: Session wird gespeichert.

                                Dass man sich in Perl um jeden Scheiß einzeln kümmern muss, kannst du PHP ja nicht anlasten. Da geht sowas deutlich komfortabler automatisch.

                                - Sven Rautenberg

                                1. hi,

                                  Und wenn ein Warenkorb zu speichern ist, speicherst du die zugehörige ID zum Warenkorb mit ab, oder?

                                  Ja klar, wassn sonst ;)

                                  Ergo: Session wird gespeichert.

                                  Nein. Es wird der _Warenkorb_ gespeichert unter _Verwendung_ der Session-ID.

                                  Hotti

                                  1. Moin!

                                    hi,

                                    Und wenn ein Warenkorb zu speichern ist, speicherst du die zugehörige ID zum Warenkorb mit ab, oder?

                                    Ja klar, wassn sonst ;)

                                    Ergo: Session wird gespeichert.

                                    Nein. Es wird der _Warenkorb_ gespeichert unter _Verwendung_ der Session-ID.

                                    Und wenn du auf einer späteren, beispielsweise der nächsten, Seite dem User anzeigen willst, wieviele Produkte er in seinem Warenkorb hat, und wieviel ihn das kosten wird, dann...

                                    ...suchst du sicherlich mit der Session-ID als Schlüssel in der Warenkorbtabelle nach einem passenden Eintrag. Wenn du keinen findest, zeigst du "0 Produkte, 0,00 Euro" an.

                                    Wo ist da jetzt der Unterschied zu PHP? Wenn ich dort einen Warenkorb anlegen will, tu ich den unter einem geeigneten Key in mein Array $_SESSION, und wenn ich das anzeigen will, sehe ich nach, ob so ein Array-Key existiert. Ansonsten zeige ich "0 Produkte, 0,00 Euro" an.

                                    Bei deinem Vorgehen musst du pro Request in allen Tabellen nachforschen, die für die aktuelle Seite ggf. Session-Informationen bereithalten könnten. Nicht sonderlich effizient, würde ich meinen, denn das sind im Zweifel mehr als EIN Request zum Laden der gesamten Session-Infos. Und genau das tut PHP: EINE Datei (DB geht natürlich auch) mit allen Infos wird zwar immer geladen und wieder weggespeichert, aber immerhin steht damit auch alles an Infos zur Verfügung.

                                    - Sven Rautenberg

                                    1. hi Sven,

                                      Bei deinem Vorgehen musst du pro Request in allen Tabellen nachforschen, die für die aktuelle Seite ggf. Session-Informationen bereithalten könnten.

                                      Verwirrende Frage. Die SID schickt der UA im Request mit (auch in PHP).

                                      Nicht sonderlich effizient, würde ich meinen, denn das sind im Zweifel mehr als EIN Request zum Laden der gesamten Session-Infos.

                                      Welche Session-Info's? Ich habe die SID, mehr brauche ich nicht.

                                      Und genau das tut PHP: EINE Datei (DB geht natürlich auch) mit allen Infos wird zwar immer geladen und wieder weggespeichert, aber immerhin steht damit auch alles an Infos zur Verfügung.

                                      Genau darauf zielt ja mein Vorschlag von gestern abend: Eben Nicht alles zusammen in einer Tabelle (Datei) zu speichern, sondern nur mit der SID in die dazu vorgesehenen "Datentöpfe" reinzuschauen, z.B. in eine Login-Tabelle oder in eine Warenkorb-Tabelle und das nur bei Bedarf. In der Anwendung 'mitgeschleift' wird nur die SID, wenn die gebraucht wird, steht sie sofort zur Verfügung.

                                      In einer Anwendung, die von vornherein mit Berechtigungen arbeitet, vereinfacht sich der spätere Code, wenn über die SID bereits im Konstruktor, Benutzername, Benutzergruppe (ggf. weitere Felder) ausgelesen werden. Diese Session-Infos müssen dann, in den entsprechenden Methoden nicht erst über die SID ermittelt werden, sondern stehen sofort zur Verfügung.

                                      Hotti

                                2. Hi,

                                  die Debatte besteht hier nicht zwischen Perl und PHP.

                                  In Perl muss man sich auch nicht um jeden Scheiß einzeln kümmern. Hotti tut immer nur so, indem er a) eigene Designmissgeburten anpreist, und b) dort Sachen anwendet, die seit 1880 bei Perl als crap angesehen werden, und c) bereits peer-erarbeitete Lösungen (siehe CPAN) ignoriert.

                                  Hth

                              2. Tach!

                                Genau hier an dieser Stelle fehlt Dir das Verständnis für das, was ich Dir versuche, zu erklären: Bei mir gibt es keine Session-Datei.

                                Ja, es gelingt mir nicht dein Verständnis von den Dingen und die damit einhergehende unübliche Verwendung von Fachbegriffen zu durchschauen. Somit kommt es immer wieder zu Missverständnissen zwischen dem Üblichen und deinen Ausführungen.

                                Eine Session ist nicht zwingend an eine einzelne Datei gebunden. Bei PHP ist das lediglich die Default-Implementierung. Wenn du es gern komplexer haben möchtest, kannst du auch deine Session-Daten individuell speichern. Es wird jedoch sicher nicht performanter werden, wenn du ein DBMS bemühst anstatt einer einfachen Datei.

                                Definiere "Session (nicht) speichern". Eine Session ist ein Speicher zwischen mehreren Requests. Sie existiert nicht ohne zu speichern.
                                In meinen Anwendungen ist die "Session" lediglich eine eindeutige und über die Browsersitzung konstant bleibende ID, welche zwischen dem Browser und der Anwendung ausgehandelt wird.

                                Das ist nach herkömmlichen Verständnis eine Session-ID. Alle Daten, die du damit verknüpfst, sind weiterhin Session-Daten, egal, wie du es nennst.

                                dedlfix.

                                1. hi,

                                  Eine Session ist nicht zwingend an eine einzelne Datei gebunden. Bei PHP ist das lediglich die Default-Implementierung. Wenn du es gern komplexer haben möchtest, kannst du auch deine Session-Daten individuell speichern. Es wird jedoch sicher nicht performanter werden, wenn du ein DBMS bemühst anstatt einer einfachen Datei.

                                  Das mag ein PHP-Programierer so sehen. Ich sehe das so: Es kommt auf den Verwendungszweck an und es gibt immer Kompromisse einzugehen zwischen IO, RAM und CPU bezüglich Performance.

                                  Einen Warenkorb speichere ich in einem RDBMS, weil es zum einen einfache Abfragen (für die Darstellung) ermöglicht und zum Anderen die Übernahme der Warenkorb-Daten in die Order bevorsteht: Das ist eine Transaktion, die atomar sein muss. So habe ich die Schnittstelle zum Warenkorb in derselben Klasse, welche die Schnittstelle zur Bestellung realisiert und Bestellungen in einer Datei zu speichern, ist nicht empfehlenswert (Mann, da stehen Kundendaten *G).

                                  Der Zugriff auf den Warenkorb wird nur dann benötigt, wenn diesbezügliche Benutzeraktivitäten vorliegen.

                                  Anders bei einem Berechtigungssystem (Login): Über die gesamte Anwendung hinweg muss es möglich sein, das für die HTTP-Ressource erforderliche Level (Benutzergruppe) mit dem in der Browsersitzung gegebenen Level vergleichen zu können. Von daher bevorzuge ich zum Speichern des "Login" eine Datei und die Schnittstelle zu dieser Datei ist eine abstrakte Klasse.

                                  In meinen Anwendungen ist die "Session" lediglich eine eindeutige und über die Browsersitzung konstant bleibende ID, welche zwischen dem Browser und der Anwendung ausgehandelt wird.

                                  Das ist nach herkömmlichen Verständnis eine Session-ID. Alle Daten, die du damit verknüpfst, sind weiterhin Session-Daten, egal, wie du es nennst.

                                  Ja.

                                  Schöne Grüße,
                                  Hotti

                                  1. Tach!

                                    Einen Warenkorb speichere ich in einem RDBMS, weil es zum einen einfache Abfragen (für die Darstellung) ermöglicht

                                    Ich sehe keinen gravierenden Unterschied, ob ich über ein Resultset oder ein Array iteriere. Das Resultset muss aber erstmal erarbeitet werden.

                                    und zum Anderen die Übernahme der Warenkorb-Daten in die Order bevorsteht: Das ist eine Transaktion, die atomar sein muss.

                                    Eine Transaction im DBMS-Sinne kann man auch mit externen Daten durchführen. Sie ist nicht auf das Umkopieren zwischen Tabellen beschränkt.

                                    So habe ich die Schnittstelle zum Warenkorb in derselben Klasse, welche die Schnittstelle zur Bestellung realisiert und Bestellungen in einer Datei zu speichern, ist nicht empfehlenswert (Mann, da stehen Kundendaten *G).

                                    Ein DBMS speichert ebenfalls nur in Dateien. Wo ist der Unterschied, ob ich Daten in einer Datei speichere oder über ein DBMS in einer Datei speichern lasse?

                                    Der Zugriff auf den Warenkorb wird nur dann benötigt, wenn diesbezügliche Benutzeraktivitäten vorliegen.

                                    Das wäre noch zu klären, ob der DBMS-Zugriff oder das Lesen der Session-Datei, wenn nur andere Daten benötigt werden, teurer ist (nebst dem Aufwand beim Code-Erstellen), beziehungsweise ob der Unterschied am Ende überhaupt relevant ist.

                                    dedlfix.

                                    1. hi,

                                      Eine Transaction im DBMS-Sinne kann man auch mit externen Daten durchführen. Sie ist nicht auf das Umkopieren zwischen Tabellen beschränkt.

                                      Das ist richtig. Aber wenn die Schnittstellen über verschiedene Klassen beschrieben sind, muss eine Beziehung zwischen Klassen hergestellt werden, das ist genau das Thema um welches es hier geht :)

                                      Ein DBMS speichert ebenfalls nur in Dateien. Wo ist der Unterschied, ob ich Daten in einer Datei speichere oder über ein DBMS in einer Datei speichern lasse?

                                      Aus der Sicht der Application gibt es keinen Unterschied, die greift in einen abstraction layer und was der macht, ist der Anwendung egal ;)

                                      Das wäre noch zu klären, ob der DBMS-Zugriff oder das Lesen der Session-Datei, wenn nur andere Daten benötigt werden, teurer ist (nebst dem Aufwand beim Code-Erstellen), beziehungsweise ob der Unterschied am Ende überhaupt relevant ist.

                                      Ja, zum x-ten Mal: Teuer wirds, wenn jede SessionID gespeichert wird, also auch SID's zu denen keine Benutzeraktionen vorliegen.

                                      Hotti

                                      1. Moin!

                                        Das wäre noch zu klären, ob der DBMS-Zugriff oder das Lesen der Session-Datei, wenn nur andere Daten benötigt werden, teurer ist (nebst dem Aufwand beim Code-Erstellen), beziehungsweise ob der Unterschied am Ende überhaupt relevant ist.

                                        Ja, zum x-ten Mal: Teuer wirds, wenn jede SessionID gespeichert wird, also auch SID's zu denen keine Benutzeraktionen vorliegen.

                                        Gähn...

                                        Meinst du nicht, dass du dich für heute schon genug in die Nesseln gesetzt hast? Jetzt machst du auch noch krude Aussagen über irgendeinen Performancevorteil. Mag ja sein, dass dein Perl-Stil so grausig ist, dass die DB da sofort in die Knie geht. Deshalb aber solche abstrusen Ideen zum Thema Session-Handling zu verbreiten, ist nicht nett.

                                        - Sven Rautenberg

            2. Tach!

              Genau so ist es: Im Objekt $time befindet sich coreTime, die Zeit als UTC, wie du es sagtest. Diese Zeit $time->coreTime benötigt das Objekt $session um alte Sitzungen zu löschen und eine Session anzulegen, deren Verfallsdauer etc festzulegen.

              Das kann alles in UTC oder der Serverzeit passieren, dazu brauchst du keine Zeitzoneninformation. Vermutlich brauchst du gar keine Zeitzoneinformation in deiner Time-Klasse. Ich würde intern nur die UTC festhalten und toLocalTime($zone) implementieren sowie einen Konstruktor, der die Zeit in UTC oder optional lokal mit Zeitzoneninformation entgegennimmt. Die Zeitzone braucht der Konstruktor nur zum Umrechnen und kann sie dann vergessen. Und selbst wenn die Time-Klasse sich die Zeitzone aus irgendeinem Grunde merken können soll, so braucht sie dazu keine Session sondern nur diese eine Information zur Zeitzone.

              Es geht mir jetzt darum eine einheitliche Methode zu finden, Daten eines Objektes in ein anderes Objekt zu inkludieren.

              Aufgrund von individuellen Anforderungen ist das ein recht müßiger Versuch, sich das Leben zu vereinfachen. Am Ende wirst du eher unflexibel und treibst vielleicht unnötigen Mehraufwand, nur um deine Einheitlichkeits-Policy zu gewährleisten. Du musst nicht alles objektorientiert machen, skalare Werte sind auch in der OOP nicht verpönt. Also überleg dir genau, was du brauchst und versuch so wenig wie möglich Abhängigkeiten zu schaffen. Reicht ein skalarer Wert, dann übergib diesen statt eines kompletten Objekts, von dem du nur eine Eigenschaft nutzt.

              Entweder komplette Verbindung mit Instanzen also $time als Instanz von $session: $session->time oder komplette Trennung der Klassen und inkludieren aller benötigten Abhängigkeiten in Funktionen, in denen sie gebraucht werden.

              Sowohl als auch, je nachdem, was für den konkreten Fall sinnvoll ist.

              dedlfix.

      2. Tach!

        Ich habe ein Klasse head, wo ich per Konstruktor andere Variablen und Klassen hereinlade. Mein Problem ist, dass die Klasse head später im Programm eine andere Klasse namens underClass benötigt und mit dieser auch arbeitet! Diese kann ich ja nicht wie bei der Definition von head hereinladen, da diese noch nicht existent ist. underClass benötigt wiederum die Klasse $head selber.
        Definiere "noch nicht existent". Unterscheide bitte außerdem zwischen Klasse und Objekt.
        Ich meine ein Objekt, dass ich in einem anderen Objekt verwenden möchte.

        Dann hast du also das Problem, dass das benötigte Objekt noch nicht existiert. Was spricht dagegen, es bereits zu diesem Zeitpunkt angelegt zu haben?

        dedlfix.

        1. Hello,

          Dann hast du also das Problem, dass das benötigte Objekt noch nicht existiert. Was spricht dagegen, es bereits zu diesem Zeitpunkt angelegt zu haben?

          Was spräche dagegen, das Objekt (B) erst in dem entsprechenden Objekt (A) anzulegen, wenn es nur dort gebraucht wird? Damit würde es auch mit dem Objekt (A) wieder verschwinden können.

          Betrachtet werden muss doch zuerst die Frage, ob ein eindeutiges Objekt (B) in jeder Instanz von Objekt (A.x) genau gleich benötigt wird, oder ob jede Instanz (A.x) ein eigenes Objekt (B von A.x) benötigt, also (B.a.x).

          Erst nach dieser Antwort kann man doch entscheiden, wann die Instanz von (B) gebildet werden muss.

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
          1. Tach!

            Dann hast du also das Problem, dass das benötigte Objekt noch nicht existiert. Was spricht dagegen, es bereits zu diesem Zeitpunkt angelegt zu haben?
            Was spräche dagegen, das Objekt (B) erst in dem entsprechenden Objekt (A) anzulegen, wenn es nur dort gebraucht wird? Damit würde es auch mit dem Objekt (A) wieder verschwinden können.

            Der entscheidende Punkt dabei ist deine wenn-Einschränkung. So wie ich das Problem des OP verstanden habe, braucht er die Rechte aber auch noch an anderen Stellen, womit B dann nicht nur ein Teil von A ist, sondern dem A und später noch C, D und E übergeben werden soll.

            dedlfix.

  3. Hallo,

    Ich habe ein Klasse head, wo ich per Konstruktor andere Variablen und Klassen hereinlade. Mein Problem ist, dass die Klasse head später im Programm eine andere Klasse namens underClass benötigt und mit dieser auch arbeitet! Diese kann ich ja nicht wie bei der Definition von head hereinladen, da diese noch nicht existent ist. underClass benötigt wiederum die Klasse $head selber.

    Ganz schlechter Ansatz (s. Anm.). Sorge dafür, dass _alle_ Klassen, die im Laufe der Anwendung gebraucht werden, von Anfang an zur Verfügung stehen (im Konstruktor Deiner Klasse 'head'). Nutze ggf. Vererbung oder Delegierung von Methoden anderer Klassen an die Instanz der eigenen Klasse.

    Anmerkung: Solche Abhängigkeiten führen zu einem schwer durchschaubaren und außerordentlich wartungsunfreundlichen Code, kurzum: Chaos.

    Ein Beispiel: Forum - Rechte

    Mein Tipp hierzu: Ausgehend davon, dass ein Login vorliegt, steht die Berechtigungsgruppe in der Login- bzw. Sessiontable mit der SessionID als Primary Key. Mit der SID wird die Session ausgelesen und als Attribut an die Instanz der eigenen Klasse gebunden. Damit steht praktisch über die gesamte Anwendung hinweg zur Verfügung:

    • Login-Name
    • Benutzergruppe
    • ggf. weitere Felder

    Hotti

    1. Hallo mod,

      ich moechte nur noch mal erwaehnen, dass du die Postings vom Hotti bitte nicht allzu ernst nehmen solltest.. er bemueht sich zwar immer, aber selten kommt da etwas Brauchbares bei rum. Um dich selbst davon zu ueberzeugen schau dir an was er zu Themen wie OOP, RAM,IO etc, Server, REST, DB/Files, Super-CGI zu erzaehlen hat. Ich denke danach haben sich seine Postings fuer dich erledigt.

      Grusz,
      Christopher

      1. hi,

        unglaublich, was Du für Energien entwickelst, meine Hilfestellung schlecht zu machen. Mit Energie des Verstehens hat das nichts zu tun.

        Dein Gesicht möchte ich sehen, wenn das jemand mit Dir machen würde.

        Hotti

        1. Hello,

          unglaublich, was Du für Energien entwickelst, meine Hilfestellung schlecht zu machen. Mit Energie des Verstehens hat das nichts zu tun.

          Dein Gesicht möchte ich sehen, wenn das jemand mit Dir machen würde.

          Hattest Du "Freunde" bei der Stasi? Das ist doch typisch für solche Leute!

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
          1. hi Tom,

            Hattest Du "Freunde" bei der Stasi? Das ist doch typisch für solche Leute!

            Kurze Antwort: Egal.
            Lange Antwort: Scheisegal.

            Tu mir'n Gefallen: Teste die Features meiner Seite, die auf einer Session basieren (Login, Warenkorb).

            Viele Grüße,
            Hotti