Impressum · Kontakt · Hilfe
Besucher online · Mitglieder



Portal > Foren > Ankündigungen, News und Feedback > Tutorials > [PHP] Objekt-Persistenz
Antwort
 
Themen-Optionen
Alt 15.09.2005, 00:52   Nach oben    #1
Benutzer
 
Benutzerbild von Guradia
 
Registriert seit: 18.08.2005
Ort: Düsseldorf
Beiträge: 57
Standard [PHP] Objekt-Persistenz

Objekt-Persistenz; PHP Session Fruits

- Von unvollständigen Klassen

PHP bietet uns ein Session-Management. Feine Sache, um Variablen oder auch ganze
Arrays darin abzuladen. Doch leider krankt das System bei Objekten. Nicht etwa,
weil es nicht könnte, sondern einfach, weil PHPs Architektur es nicht hergibt.

Keine Probleme bereiten Objekte aus internen Klassen wie stdClass oder dir. Doch
Objekte in PHP geschriebener Klassen kann das SessionManagement nicht wieder
herstellen. Die Objekte degenerieren hierbei zu "unvollständigen Klassen", die
zwar wie eine stdClass alle Eigenschaften behalten haben, aber um jegliche Methoden
beraubt sind.

Warum dies geschieht ist schnell erklärt, der Quellcode der Klassen ist zum
Zeitpunkt des Aufrufs von session_start() nicht verfügbar und PHP ist nicht bekannt, wie das Objekt
zu rekonstruieren ist. Die Lösung des Problems ist eigentlich sehr simpel. Die
Klassen müssen inkludiert werden, bevor session_start() aufgerufen wird.

Mit wachsendem Ausmaß des Projekts, steigt allerdings auch die Menge der genutzen
Klassen und somit auch der Overhead, der zu inkludierenen Quelldateien. Natürlich
kann man diesen Overhead dahingehen reduzieren, dass nur benötigte Klassen der
Session zur Verfügung gestellt werden, doch zum einen ist dies höchst vermutlich
sehr variabel, zum anderen ein leicht intransparent werdender Verwaltungsaufwand.

- Einsatz für __autoload()

PHP5 bietet allerdings eine gänzlich unscheinbare neue Funktion, die hier so richtig
schön auftrumpfen kann: __autoload(). Der Zweck ist einfach beschrieben: Wird
eine Klasse instanziiert, die nicht deklariert ist, erhält __autoload() deren
Namen als einzigen Parameter. Das ist es eigentlich schon. Was wir nun innerhalb
__autoload() anstellen, bleibt uns überlassen.

Natürlich geht es nun darum, die Quelldatei der vermissten Klasse zu inkludieren.
Da wir als Parameter aber nur den Klassennamen haben, müssen wir von diesem
irgendwie auf die Datei schliessen und diese inkludieren. Hierbei führen uns
viele Wege ans Ziel, im Rahmen des Tutorials werde ich im folgenden aber eine
Möglichkeit mitsamt zugehörendem Layout im Dateisystem vorstellen.

- PHP Session Fruits

Das Layout der Applikation im Dateisystem ist wichtig, um generisch anhand von
Klassennamen deren Dateien finden zu können. Einfach wäre es, alle
Datein in einem Verzeichnis aufzubewaren, und gleich ihrer Klasse zu benennen.
Das verliert aber für die meisten Entwickler sehr schnell an Übersicht.

Eine praktikable Stuktur findet sich in PEAR. Hier werden Klassen thematisch in
Ordnern abgelegt. Diese Ordner finden sich in den Klassennamen wieder:
Code:
# Dateien
DB.php
HTML/QuickForm.php
Mail/mime.php

# Klassen
DB
HTML_QuickForm
Mail_mime
Wir imitieren diese Strukur einmal in einer völlig albernen foo/bar-Applikation:
Code:
index.php
Foo.php
Foo/Bar.php
index.php sorgt für den Aufruf der Objekte und beinhaltet die __autoload()-Implementation.
Foo.php enthält die Klasse Foo, welche nur einen recht primmitiven Zähler darstelt.
Foo/Bar.php mit Klasse Foo_Bar erweitert Foo um ... noch einen Zähler.
Innerhalb der index.php wird nur Foo_Bar instanziiert, __autoload wird selbständig
beide nötigen Dateien laden.
Ein simples echo triggert __toString(), welches ein paar Informationen ausspuckt,
die verdeutlichen, dass soeben persitente Objekte enstanden sind. Die "PHP Session Fruits" ^^


index.php

PHP-Code:
<?php


/**
 * Übersetzt Klassennamen in einen Pfad und versucht die Klasse zu laden
 * 
 * @param string $ClassName zu ladende Klasse
 */
function __autoload($ClassName)
{
    
/* Aufbrechen des Klassennamens anhand von Unterstrichen
     * 
     * Foo resultiert in
     * array {
     *     [0] => 'Foo'
     * }
     * 
     * Foo_Bar resultiert in
     * array {
     *     [0] => 'Foo'
     *     [1] => 'Bar'
     * }
     */
    
$ClassName explode('_'$ClassName);
    
    
/* Zusammensetzen zu Verzeichnispfad
     * 
     * Foo wird unverändert wieder zu Foo
     * Foo_Bar heisst nun Foo/Bar
     */
    
$ClassName implode('/'$ClassName);
    
    
/* File-Extension angehägt und schon haben wir unsere passende Datei:
     * Foo.php
     * Foo/Bar.php
     */
    
require_once $ClassName '.php';
}

/* Beginn der Session */
session_start();

/* eine kleine Überprüfung, ob das Objekt noch erstellt werden muss */
if (!isset($_SESSION['FooBar']))
    if (!
is_object($_SESSION['FooBar']))
        
$_SESSION['FooBar'] = new Foo_Bar();

/* Ausgabe des Objekts über __toString() */
echo $_SESSION['FooBar'];

?>

Foo.php

PHP-Code:
<?php

class Foo
{
    protected 
$WakeUpCounter 0;
    protected 
$ConstructCounter 0;
    
    public function 
__construct()
    {
        
$this->ConstructCounter++;
    }
    
    public function 
__wakeup()
    {
        
$this->WakeUpCounter++;
    }
    
    public function 
__toString()
    {
        return
            
'Foo wurde '.$this->ConstructCounter.' x konstruiert<br />'."\n" .
            
'und '.$this->WakeUpCounter.' x aus dem Schlaf gerissen<br />'."\n";
    }
}

?>


Foo/Bar.php

PHP-Code:
<?php

class Foo_Bar extends Foo
{
    protected 
$BarWakeCounter 0;

    public function 
__wakeup()
    {
        
$this->BarWakeCounter++;
        
parent::__wakeup();
    }
    
    public function 
__toString()
    {
        return
            
parent::__toString() .
            
'und hat dabei Bar '.$this->BarWakeCounter.' x nicht weiterschlafen lassen<br />'."\n";
    }
}

?>

Geändert von Guradia (15.09.2005 um 13:17 Uhr).
Guradia ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.09.2005, 12:50   Nach oben    #2
BIN EIN KRASSA HELD!!!111
 
Benutzerbild von robo47
 
Registriert seit: 02.06.2005
Ort: weiher im tiefsten Odenwald
Beiträge: 1.185
Standard

Schönes Tutorial, vor allem gut geschrieben wie ich finde. Ich speichere zwar nie irgendwelche Objekte in Sessions, aber jetzt weis ich wenigstens wie ich sauber vorgehen muss wenn ich das wollte.

mfg
robo47
robo47 ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.09.2005, 13:36   Nach oben    #3
Verplanter Benutzer
 
Registriert seit: 14.12.2004
Beiträge: 220
Standard

Hi,

das hatte ich auch schonmal gefragt aber es wurde abgeraten, frage wo
liegen die Vorteile bei Objecten in Sessions und wenn nicht warum ?

Finde das gehört noch dazu.
(Nein ich wüsste es nicht wirklich)

Aber sehr schön verständlich zu lesen !
DasMööp ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.09.2005, 13:40   Nach oben    #4
Erfahrener Benutzer
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 662
Standard

ICh denke mal, dass der Vorteil einfach darin liegt, dass man den letzten Status des Objektes direkt wiederherstellen kann. Sprich: Eine Datenbank-Verbindung würde bestehen bleiben, bei einer Template-Klasse würden die Templates bereits geladen sein, etc. etc.
MrNiceGuy ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.09.2005, 13:49   Nach oben    #5
Benutzer
 
Benutzerbild von Guradia
 
Registriert seit: 18.08.2005
Ort: Düsseldorf
Beiträge: 57
Standard

Zitat:
Zitat von DasMööp
das hatte ich auch schonmal gefragt aber es wurde abgeraten, !
Da wüsste ich doch gerne, was du tatsächlich gefragt hast und was dann die begründung war.

Vermutlich deckt sich das ganz gut mit meiner Einleitung ^^
Guradia ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.09.2005, 14:06   Nach oben    #6
Verplanter Benutzer
 
Registriert seit: 14.12.2004
Beiträge: 220
Standard

Phu ... da bin ich nicht so tief drin hab mich dann umgestellt da es nur ein versuch
war bis dahin kannte ich auch __autoload noch nicht.

Hatte mir selbst eine funktion gebastellt die alle klassen geladen hatte die
vorhanden waren und in $_SESSION['class'][$classname'] gespeichert und
auch so angesprochen wenn ich diese benötigt hatte.
http://forum.developers-guide.net/thread196.html

Muss das hier auch erstmal noch aufarbeiten ...
DasMööp ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.09.2005, 14:48   Nach oben    #7
Benutzer
 
Benutzerbild von Guradia
 
Registriert seit: 18.08.2005
Ort: Düsseldorf
Beiträge: 57
Standard

Zitat:
Zitat von DasMööp
Hatte mir selbst eine funktion gebastellt die alle klassen geladen hatte die
vorhanden waren und in $_SESSION['class'][$classname'] gespeichert und
auch so angesprochen wenn ich diese benötigt hatte.
http://forum.developers-guide.net/thread196.html
Ahh .. hab den Thread damals gesehen, aber nicht wirklich verstanden, wie du von Sichtbarkeit plötzlich auf Persitenz übergingst ... ^^
Guradia ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.09.2005, 15:01   Nach oben    #8
Verplanter Benutzer
 
Registriert seit: 14.12.2004
Beiträge: 220
Standard

Zitat:
wie du von Sichtbarkeit plötzlich auf Persitenz übergingst ... ^^
äh was !?
DasMööp ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.09.2005, 20:45   Nach oben    #9
BIN EIN KRASSA HELD!!!111
 
Benutzerbild von robo47
 
Registriert seit: 02.06.2005
Ort: weiher im tiefsten Odenwald
Beiträge: 1.185
Standard

Zitat:
Zitat von MrNiceGuy
ICh denke mal, dass der Vorteil einfach darin liegt, dass man den letzten Status des Objektes direkt wiederherstellen kann. Sprich: Eine Datenbank-Verbindung würde bestehen bleiben, bei einer Template-Klasse würden die Templates bereits geladen sein, etc. etc.
Also die Datenbankverbindugn bleibt würde ich behaupten nur bestehen wenn eh eine persistente verbindung besteht, weil wenn ich

www.php.net/mysql_close
Zitat:
Using mysql_close() isn't usually necessary, as non-persistent open links are automatically closed at the end of the script's execution. See also freeing resources.
http://www.php.net/manual/en/languag....self-destruct
Zitat:
Due to the reference-counting system introduced with PHP 4's Zend Engine, it is automatically detected when a resource is no longer referred to (just like Java). When this is the case, all resources that were in use for this resource are made free by the garbage collector. For this reason, it is rarely ever necessary to free the memory manually by using some free_result function.

Note: Persistent database links are special, they are not destroyed by the garbage collector. See also the section about persistent connections.
Hier stellt sich jetzt die Frage ob PHP erkennt, dass eine Mysql-Klasse mit aktiver Mysql-Verbindung in ner Session gespeichert wird und diese Verbindung dann eben nicht schließt.

Aber ich lasse mich gerne eines besseren belehren

mfg
robo47
robo47 ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.09.2005, 21:22   Nach oben    #10
Waq
Erfahrener Benutzer
 
Registriert seit: 18.08.2005
Beiträge: 108
Standard

Datenbankverbindungen überleben keine Session, auch nicht persistente. Persistenten Verbindungen lassen sich zwar wiederverwenden, allerdings
- muss man dazu ein connect machen, um die persistente Verbindung "auszugraben"
- ist nicht von der Session abhängig, welche Verbindung wiederverwendet wird, sondern vom Apache-Prozess

Geändert von Waq (15.09.2005 um 21:25 Uhr).
Waq ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.09.2005, 21:34   Nach oben    #11
Erfahrener Benutzer
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 662
Standard

OK, zugegeben: Schlechtes Beispiel mit der DB-Verbindung. Hätte da auch an eine persistente Verbindung gedacht, aber vermutlich wird selbst die beendet beim Beenden des Scripts.
MrNiceGuy ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.09.2005, 22:50   Nach oben    #12
me pro ok?
 
Benutzerbild von Lars
 
Registriert seit: 07.09.2005
Ort: Pulheim bei Köln
Beiträge: 964
Standard

Persistente Verbindungen kann man afaik doch nur auf die harte Tour, also den Prozess killen, beenden.
mysql_close() wirkt jedenfalls nur auf normale Verbindungen.
Lars ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 16.09.2005, 10:08   Nach oben    #13
Benutzer
 
Benutzerbild von Guradia
 
Registriert seit: 18.08.2005
Ort: Düsseldorf
Beiträge: 57
Standard

Objekte = Datenstrukturen
String/Int/Float = Daten
Dateien/Datenbanken/Sockets etc. = Ressourcen

Session = persistenter Speicher für Daten und -strukturen

Damit dürfte gesagt sein, was in eine Session passt und was nicht.

__wakeup() bietet aber eine Implementationsmöglichkeit, Ressourcen wiederherzustellen.
Guradia ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist An.
Smileys sind An.
[IMG] Code ist An.
HTML-Code ist Aus.
Trackbacks are An
Pingbacks are An
Refbacks are Aus

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Existiert ein gewisses Objekt im Sichtbarkeitsbereich? Ben PHP-Programmierung 7 08.03.2007 07:47
Herausfinden, wie ein existierendes Objekt heißt Ben PHP-Programmierung 7 08.03.2006 18:34
Klassenname vom HTMLElement Objekt beny_mcde JavaScript und AJAX 3 18.01.2006 15:36
Objekt Array am82 Allgemeine Java-Programmierung 9 12.12.2005 19:01
FileForm Objekt in Oracle Datenbank Riddick Datenbanken 1 12.10.2004 13:38


Alle Zeitangaben in WEZ +2. Es ist jetzt 13:10 Uhr.

Nach oben
Wir nutzen das Zend Framework, vBulletin (vBulletin v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0) und vBSEO.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44