php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > PHP Developer Forum
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Fragen zu Laravel, YII oder anderen PHP-Frameworks.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 21-11-2008, 19:12
Dennis79
 Newbie
Links : Onlinestatus : Dennis79 ist offline
Registriert seit: Jul 2006
Beiträge: 73
Dennis79 ist zur Zeit noch ein unbeschriebenes Blatt
Standard [PHP5] Start mit OOP / Frage zu Klassenstruktur

Hallo,

ich habe vor, meine private Seite neu zu machen, und zwar objektorientierter, also mit Klassen.

Im Moment gibt es einfach nur eine riesige Sammlung an Funktionen, und das soll sich jetzt ändern, bzw. es soll strukturierter werden.
Deswegen wende ich mich mal an die Allgemeinheit.

Problem: was packe ich in welche Klasse?

Die Webseite ist rein privat mit Authenitifizierung/Login.
Hauptbestandteil: ein Bundesliga-Tippspiel.
Sonstiges: kleines Forum, Fotos.

Ich baue die Klasse user. Da rein kommen Eigenschaften wie die User-ID, der Username, der richtige Name etc.

Tippspieler benötigen außerdem Eigenschaften wie z.B. aktueller Tabellenplatz oder aktuelle Form, aber auch z.B. Funktionen die überprüfen ob der aktuelle Spieltag schon getippt wurde, Verabeitung der Tipps etc.

Frage: würdet ihr die ganzen Tippspiel-Klamotten mit in die User-Klasse packen, oder eine sep. Klasse verwenden?

Ich tendiere ja zu zwei Klassen...


Mein viel größeres Problem:
ich verwende das PEAR-Package "MDB2" für alle Datenbankoperationen.

Dabei wird anfangs ein Objekt erzeugt, welches die Verbindung zur Datenbank aufbaut und z.B. Abfragen ausführen kann.

Darauf muss ich in verschiedenen Klassen bei verschiedenen Funktionen zurückgreifen können.
Im Moment binde ich es per "global" in die Funktionen ein - gibt es da keinen besseren Weg?

Gruß,
Dennis
Mit Zitat antworten
  #2 (permalink)  
Alt 21-11-2008, 21:21
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zu der Frage bezüglich des Datenbank-Objekts:
PHP-Code:
class IrgendeineKlasse
{
    protected 
$_database null;

    public function 
__construct(MDB2 $database_object)
    {
        
$this->_database $database_object;
    }

Ist PEARs MDB2 eigentlich als Singleton implementiert? Falls ja, kannst du auch global über MDB2::getInstance() (oder ähnliches) darauf zugreifen und kannst dir die Übergabe an den Klassenkonstruktor sparen. Sauberer ist allerdings ersteres.


Grüße

Geändert von Griecherus (21-11-2008 um 21:36 Uhr)
Mit Zitat antworten
  #3 (permalink)  
Alt 21-11-2008, 22:37
ghostgambler
 Master
Links : Onlinestatus : ghostgambler ist offline
Registriert seit: Jul 2004
Ort: DE - NRW
Beiträge: 4.620
ghostgambler ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von Griecherus
Sauberer ist allerdings ersteres.
Geschmackssache. Ich finde letzteres sauberer.
Mit Zitat antworten
  #4 (permalink)  
Alt 21-11-2008, 22:55
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von ghostgambler
Geschmackssache. Ich finde letzteres sauberer.
Inwiefern?
Mit Zitat antworten
  #5 (permalink)  
Alt 21-11-2008, 23:57
PHP-Desaster
 PHP Expert
Links : Onlinestatus : PHP-Desaster ist offline
Registriert seit: Mar 2006
Beiträge: 3.105
PHP-Desaster befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Geschmackssache.
Dem kann ich mich nur anschließen. Am geschicktesten ist sogar noch, beides zu ermöglichen, zum Beispiel auf folgendem Wege:
PHP-Code:
class Foo {
    private 
$_db=NULL;
    public function 
__construct(DB $db=NULL) {
        if(
$db!==NULL) {
             
$this->setDB($db);
        }
    }
    public function 
getDB() {
        if(
$this->_db===NULL) {
            
$this->_db=Registry::get('DB');
        }
        return 
$this->_db;
    }
    public function 
setDB(DB $db) {
        
$this->_db=$db;
    }

So kannst du die zu verwendende Instanz von außen konfigurieren (über die Registry) oder direkt an der Instanz setzen. Erlaubt einerseits die generische Erstellung zum Beispiel durch eine Factory und ist andererseits nicht total von der Konfiguration abhängig.
Mit Zitat antworten
  #6 (permalink)  
Alt 22-11-2008, 11:01
Dennis79
 Newbie
Links : Onlinestatus : Dennis79 ist offline
Registriert seit: Jul 2006
Beiträge: 73
Dennis79 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Guten Morgen,

vielen Dank für die Antworten!!!

Scheint mir eine Lösung zu sein, auf die ich auch hätte selber kommen können...
Und trotzdem klappt es nicht.

Folgendes (verkürzt):
PHP-Code:
<?php
    
class bla{
        
        private 
$mydb=null;
        
            function 
set_mydb($foo){
                
$this->mydb=$foo;
            }
        
            function 
sql_irgendwas(){
                
$res $this->mydb->query('SELECT * FROM blabla');
            }
    }
    
    
    
$mdb2 =& MDB2::connect($dsn$options);
    
    
$x=new bla();
    
$x->set_mydb($mdb2);
    
    
$x->sql_irgendwas();
?>
Die letzte Zeile sorgt für eine Fehlermeldung, weil in der Funktion sql_irgendwas "$this->mdb2" nicht definiert ist.

Warum nicht? Was mache ich falsch?

Wenn ich die Funktion so veränder:
PHP-Code:
            function sql_irgendwas(){
                
$mydb=$this->mydb;
                
$res $mydb->query('SELECT * FROM blabla');
            } 
...funktioniert's ...

Versteh ich nicht...

Edit: Danke für den Hinweis (Posting hier drunter), hab's geändert.
Hatte das Beispiel nur zum Posten zusammengetippt, war quasi ein "Tippfehler" - Problemstellung bleibt aber gleich.

Geändert von Dennis79 (22-11-2008 um 11:56 Uhr)
Mit Zitat antworten
  #7 (permalink)  
Alt 22-11-2008, 11:09
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.576
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Verwechselst du nicht mydb mit mdb2?
Mit Zitat antworten
  #8 (permalink)  
Alt 22-11-2008, 12:50
Benutzerbild von onemorenerd onemorenerd
  Moderator
Links : Onlinestatus : onemorenerd ist offline
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
onemorenerd wird schon bald berühmt werdenonemorenerd wird schon bald berühmt werden
Standard

Du erzeugst $mdb2 als Referenz. Warum?
Mit Zitat antworten
  #9 (permalink)  
Alt 24-11-2008, 19:55
Dennis79
 Newbie
Links : Onlinestatus : Dennis79 ist offline
Registriert seit: Jul 2006
Beiträge: 73
Dennis79 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Hallo,

ich muss gestehen, dass ich mit der Gegenfrage von onemorenerd nix anfangen kann.

Der Einstieg in die Welt der Klassen gestaltet sich weiterhin schwierig. Zwar glaube ich das Werkzeug dafür mittlerweile halbwegs zu kennen, aber ich weiß es nicht richtig einzusetzen.

Peter (kropff) hat mir zudem geflüstert, dass das sowieso der falsche Weg sei, weil man seine SQl-Abfragen in einer Klasse zusammen hält.

Danach hab ich wirklich lange überlegt, wie das denn wohl machen könnte.

Folgender, sehr bescheidener Versuch ist dabei herum gekommen:

PHP-Code:
class dbc{
    
     public 
$mdb2;

     public function 
__construct() {

     require_once 
'MDB2.php';
        
$dsn = array(
            
'phptype'  => 'mysql',
            
'username' => 'root',
            
'password' => '',
            
'hostspec' => 'localhost',
            
'database' => 'de1180838',
        );
        
$options = array(
            
'debug'       => 1,
            
'portability' => MDB2_PORTABILITY_ALL,
        );
    
        
// uses MDB2::factory() to create the instance
        // and also attempts to connect to the host
        
$mdb2 =& MDB2::connect($dsn$options);
        
$this->mdb2 $mdb2;
        if (
PEAR::isError($mdb2)) {
            die(
$mdb2->getMessage());
        }
     
     }
     
         public function 
get_user(){
         
$res =& $this->mdb2->query('SELECT * FROM user_auth WHERE (user_auth.pk_user=1)');

            return 
$res->fetchAll(MDB2_FETCHMODE_ASSOC);
         }
}

class 
testobj{
    private 
$mdb2;

         public function 
__construct() {
             
$this->mdb2=new dbc();
             
         }
         
         public function 
whois(){
             return 
$this->mdb2->get_user();
         }
         

}

$bla=new testobj();
var_dump($bla->whois()); 
Das funktioniert sogar!

Aber ist das so korrekt, dass ich in der Klasse testobj die Klasse dbc aufrufe?

Oder wie macht man's richtig?

Die Funktion "get_user" muss natürlich noch allgemeiner gehalten werden. Das war jetzt nur für einen ersten Test so angelegt.


Warum sind Konstruktoren eigentlich public? Würde da ein "private" nicht völlig ausreichen?
Ich hab das jetzt nur so gemacht, weil es in vielen Beispielen auch so war...

Gruß,
Dennis
Mit Zitat antworten
  #10 (permalink)  
Alt 24-11-2008, 20:51
Benutzerbild von onemorenerd onemorenerd
  Moderator
Links : Onlinestatus : onemorenerd ist offline
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
onemorenerd wird schon bald berühmt werdenonemorenerd wird schon bald berühmt werden
Standard

MDB2 ist ein PEAR-Paket. Das sollte mit autoloading/include_path von selbst geladen werden.

Die Klasse DBC ist ein Zwitter - einerseits kapselt sie deine DB-Schnittstelle (MDB2 macht auch nichts anderes), andererseits ist sie ein Datenobjekt (von außen sieht es aus, als trüge sie die Userdaten in sich).

Frage dich ...
Was willst du eigentlich machen?
Welche Entitäten sind daran beteiligt?
Wie agieren die Entitäten miteinander?
Was ist das Ergebnis?


Wenn Konstruktoren private wären, könnte man sie von außen nicht aufrufen - das ist ja der Sinn von private. Wenn man den Konstruktor von außen nicht aufrufen kann, wie erzeugt man dann ein Objekt?
Mit Zitat antworten
  #11 (permalink)  
Alt 24-11-2008, 21:25
Dennis79
 Newbie
Links : Onlinestatus : Dennis79 ist offline
Registriert seit: Jul 2006
Beiträge: 73
Dennis79 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Hi,

das "require_once 'MDB2.php';" steht da nur mit drin, weil ich eine einfache Testdatei erstellt habe.

Ich hoffe, Du meintest das überhaupt.
Jedenfalls kommt diese Zeile später nicht mit in die Klasse.

Deine Fragen habe ich mir alle schon gestellt.
Auf 2 & 3 zu antworten, würde wahrscheinlich zu weit gehen.
Es handelt sich halt um ein Tippspiel.
Es gibt User. Diese können Tippspieler sein. Tippspieler sind aktiv oder inaktiv, haben einen Platz in der ewigen Rangliste und bei aktivem Status auch einen Platz in der aktuellen Tabelle, haben den nächsten Spieltag schon getippt oder nicht, usw usw.
Saisons, Tipps, Rangliste etc. sind natürlich auch schon wieder eigenständige Objekte.
Kurz: es würde zu weit gehen.

Frage 1 & 4 hängen irgendwie zusammen.

Also es gibt da dies
e private Seite - meine private Seite.
Der aktuelle Stand ist der, dass z.B. Code & Content nicht sauber voneinander getrennt sind. Teilweise noch schlicht runtergeschrieben, größtenteils aber in Funktionen "ausgelagert".

Was ich vor allem machen will, ist den Umgang mit Klassen zu lernen.
Deswegen nehme ich mir vor: $private_homepage = new homepage();

Die reine Trennung von PHP und HTML hab ich eigentlich schon gesichert (Template Engine).
Jetzt möchte ich aber auch eine ordentliche PHP-Struktur haben, und dafür erscheinen mir Klassen als sinnvoll.
Außerdem erspart es auf lange Sicht viel Schreibarbeit.

Und da ich mir "keinen abbrechen" will, und nicht am Ende feststellen möchte, dass man alles auch viel einfacher/besser machen könnte, frag ich lieber gleich am Anfang nach.

Gruß,
Dennis
Mit Zitat antworten
  #12 (permalink)  
Alt 24-11-2008, 21:27
combie
 PHP Expert
Links : Onlinestatus : combie ist offline
Registriert seit: May 2006
Beiträge: 3.296
combie wird schon bald berühmt werden
Standard

Private Konstruktoren machen bei Singletons durchaus Sinn! Wobei sich im Gegenzug aber auch sofort die Frage auftut, ob Singletons an sich überhaupt sinnvoll sind.

Und wofür sind die & da?
Ich denke, das ist doch PHP5 Code!

Schau mal bei Google nach "OOP Design Pattern".
Insbesondere das "Dependency Injection Pattern" erlaubt eine lose Bindung der Objekte.
__________________
Wir werden alle sterben

Geändert von combie (24-11-2008 um 21:30 Uhr)
Mit Zitat antworten
  #13 (permalink)  
Alt 24-11-2008, 22:27
phpguru42
 Newbie
Links : Onlinestatus : phpguru42 ist offline
Registriert seit: Oct 2008
Beiträge: 71
phpguru42 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von combie
Wobei sich im Gegenzug aber auch sofort die Frage auftut, ob Singletons an sich überhaupt sinnvoll sind.
Wie willst Du sonst sicherstellen, dass ein Objekt dem Highlander-Prinzip gehorcht?
Mit Zitat antworten
  #14 (permalink)  
Alt 24-11-2008, 22:48
combie
 PHP Expert
Links : Onlinestatus : combie ist offline
Registriert seit: May 2006
Beiträge: 3.296
combie wird schon bald berühmt werden
Standard

Ja genau!!
Wozu soll das auch gut sein?

Warum die Notwendigkeit "es darf nur einen geben" in der Klasse selber festlegen?
Das wäre Unsinn!

Irgendwann brauchst du einen 2ten Druckerport/Datenbankverbindung/Prozessor/Festplatte oder was auch immer.
Und dann? Die Klasse umbauen?

Die Singleton Eigenschaft einer Klasse ist unter PHP<5.3 nicht vererbbar. Du machst dir damit also große Teile der OOP kaputt.
Und das ohne wirkliche Not!

Nein!
Singleton: Obwohl ich es auch ab und an aus Bequemlichkeit nutze, halte ich es für ein anti Pattern. Fast auf gleichem Level wie globale Variablen.

Setze stattdessen z.B. das Registry Pattern ein. Dann bleibt die Einschränkung in der Applikation und nicht in der HelferKlasse, wo sie nichts zu suchen hat.
__________________
Wir werden alle sterben

Geändert von combie (24-11-2008 um 23:03 Uhr)
Mit Zitat antworten
  #15 (permalink)  
Alt 24-11-2008, 23:14
phpguru42
 Newbie
Links : Onlinestatus : phpguru42 ist offline
Registriert seit: Oct 2008
Beiträge: 71
phpguru42 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von combie
Setze stattdessen z.B. das Registry Pattern ein. Dann bleibt die Einschränkung in der Applikation und nicht in der HelferKlasse, wo sie nichts zu suchen hat.
Wenn man allein an einem Projekt arbeitet, mag das ja ok sein.
Aber stell' Dir mal ein größeres Projekt vor, mit neuen, unerfahrenen Entwicklern, die ins Team kommen. Wie willst Du dann verhindern, das eine neue Instanz mit new() erzeugt wird?
Mit Zitat antworten
Antwort

Lesezeichen


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

Themen-Optionen
Thema bewerten
Thema bewerten:

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 an


PHP News

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni

Wissensbestand in Unternehmen
Wissensbestand in UnternehmenLebenslanges Lernen und Weiterbilden sichert Wissensbestand in Unternehmen

25.05.2018 | Berni


 

Aktuelle PHP Scripte

PHP Server Monitor

PHP Server Monitor ist ein Skript, das prüft, ob Ihre Websites und Server betriebsbereit sind.

11.09.2018 Berni | Kategorie: PHP/ Security
PHP WEB STATISTIK ansehen PHP WEB STATISTIK

Die PHP Web Statistik bietet Ihnen ein einfach zu konfigurierendes Script zur Aufzeichnung und grafischen und textuellen Auswertung der Besuchern Ihrer Webseite. Folgende zeitlichen Module sind verfügbar: Jahr, Monat, Tag, Wochentag, Stunde Folgende son

28.08.2018 phpwebstat | Kategorie: PHP/ Counter
Affilinator - Affilinet XML Produktlisten Skript

Die Affilinator Affilinet XML Edition ist ein vollautomatisches Skript zum einlesen und darstellen der Affili.net (Partnerprogramm Netzwerk) Produktlisten und Produktdaten. Im Grunde gibt der Webmaster seine Affilinet PartnerID ein und hat dann unmittelb

27.08.2018 freefrank@ | Kategorie: PHP/ Partnerprogramme
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 09:40 Uhr.