oke na uitstekende hulp zoals altijd hier van onder andere Wouter en Erwin heb ik maar even geprobeerd om zonder tutorials etc een class te bouwen. (wel kijken naar de linkjes van wouter) want het was idd nog een beetje kopieren en plakken met OOP maar ik ben nu wel op de goede weg denk ik. heb begin gemaakt met een class 'databaseConfig' hier staat de database configuratie in. dan heb ik vervolgens een class gemaakt genaamd 'databaseConnect' hier ga ik connecten met de database. maar nu. snap ik een paar dingen niet.
wat is het verschil tussen
abstract class ...
en
class ...
en moet ik nu de databaseConnect extenden uit de databaseConfig of moet ik hier de __construct gebruiken zoals __construct(databaseConfig)? of denk ik nu helemaal verkeerd?
hmm heb je hier een klein voorbeeldje van misschien erwin? hoe de interface er uit hoort te zien. dit ben ik nog niet tegengekomen in tutorials tot nu toe. althans dat denk ik.. ben wel dingen tegengekomen met
.... implements ... weet niet of dat het is?
edit: heb het even uitgevogelt op php.net dat is het inderdaad. maar hoe ziet zown implement er dan uit wanneer de database verschilt?
Reshad, je bent goed opweg. Alleen zeg je nu dat dbConfig de superklasse is en dbConnect de subklasse. Die relatie moet dan een IS_EEN relatie zijn, kan je zeggen dbConnect IS_EEN dbConfig? Nee toch? Dus moet je die relatie weghalen. Het is meer een HEEFT_EEN relatie (dat betekend niet meer dan een relatie in je hoofd en niet in de code). Want dbConnect HEEFT EEN dbConfig is wel juist.
Ook moet je even goed gaan nadenken. De dbConfig klasse slaat waardes op als user, pass, dbname, host, enz. Verschillen die per adapter?
En het maken van de verbinding in dbConnect, verschillen die per adapter?
Welke klasse moet dus meerdere subklassen hebben en welke niet?
[hr]
En nu wil ik nog even wat structuur aanbrengen in je tekeningen, aangezien dat heel belangrijk gaat worden. Dit doen we namelijk allemaal met UML diagrammen. Een voorbeeld tekening van mijn voorbeeld hierboven kun je hier vinden. Wat uitleg:
- Blokken bevatten eerst de klassenaam, is dit een abstracte klasse dan is deze cursief.
- Daarna komt de sectie met properties en eventuele types, vooraan staat de access (+ is public, # protected en - private).
- Dan de method met eventuele argumenten en access, abstracte methods zijn cursief
- een doorgetrokken lijn met een open hoek aan het eind is een IS_EEN (extend) relatie tussen klassen.
- een stippellijn met een open hoek aan het eind is een IMPLEMENTEERT (met interfaces) relatie.
- een doorgetrokken lijn met 2 streepjes als een hoek aan het eind is een HEEFT_EEN relatie.
- databaseConnect apart van de databaseConfig. maar het moet niet extend worden. terwijl de een de ander wel nodig heeft.
dit kan ik gewoon oproepen dmv de constructor. >> __construct(databaseconfig)
- dbconfig slaat waardes op maar dit zijn volgens mij voor elke database gelijk of het per adapter verschilt. ik denk het niet?
staan ze zo dan goed in hun eigen klasse of moeten ze dan op een andere manier verwerkt worden?
- het maken van een verbinding is volgens mij per adapter wel verschillend maar dit weet ik niet omdat ik tot op heden alleen met mysql gewerkt heb dus ik weet niet hoe het bij andere databases gaat en of ik daar dan dezelfde manier voor kan gebruiken.
al met al ben ik zover gekomen met de code afgeleid van wat ik op papier heb staan. --> http://pastebin.com/uXr6Y5Md
Jordi, het is geen regel, alleen alle standaarden houden zich eraan en schrijven het voor.
Ook doet Reshad het denken in objecten nu goed, qua connect apart. Je kan ook een Database klasse maken, maar dan heb je het niet meer over objecten maar over een verzameling functies. Ook handig soms, alleen Reshad wil nu OO leren.
Reshad, nee je bent niet goed bezig. Voor de helft zit je goed, voor de andere helft niet. De Configuratie verschilt niet per adapter, dat is dus 1 config klasse.
De connection verschilt wel per adapter. Je maakt dus 1 superklasse die alle methods pakt die gelijk zijn bij alle adapters. Vervolgens heb je subklassen die speciaal per adapter zijn. Je krijgt dus zoiets:
<?php
class DbConnect
{
// methoden
}
class MySQLDbConnect extends DbConnect
{
// ...
}
class MySQLiDbConnect extends DbConnect
{
// ...
}
class PDODbConnect extends DbConnect
{
// ...
}
class PDOMySQLDbConnect extends PDODbConnect
{
// ...
}
class PDOMSSQLDbConnect extends PDODbConnect
{
// ...
}
?>
hmm heb je hier een klein voorbeeldje van misschien erwin? hoe de interface er uit hoort te zien. dit ben ik nog niet tegengekomen in tutorials tot nu toe. althans dat denk ik.. ben wel dingen tegengekomen met
Bedenk wat een config class zou moeten kunnen. De config class moet de verbinding met de database maken, de verbinding sluiten, een query uitvoeren op de database, uitkomsten terugsturen etc. Op basis daarvan kan je een interface opzetten om ervoor te zorgen dat elke class die zich wil voordoen als connectie class dit kan:
Dit is uiteraard een voorbeeld, in het echt zal je meer methodes nodig hebben en wil je misschien in de executeQuery methode al de resultaten teruggeven.
<?php
interface Connection_Interface{
public function __construct( $host, $username, $password );
public function connect();
public function isConnected();
public function disconnect();
public function executeQuery( $sql );
public function getResults();
}
?>
Vervolgens kan je een object deze interface laten implementeren:
<?php
class MySQL_Connection_Class implements Connection_Interface{
public function __construct( $host, $username, $password ){
$this->host = $host;
$this->username = $username;
$this->password = $password;
}
public function connect(){
//make the connection
}
public function isConnected(){
//check if there is a connection, return a boolean
}
public function disconnect(){
//close the db connection
}
public function executeQuery( $sql ){
//execute the given query
}
public function getResults(){
//return the results from the last executed query
}
}
?>
Als je nu vervolgens een database class hebt die voor de rest van de applicatie alle database interactie verzorgt, dan kan je daarin een connection setter maken waarbij je via typehinting afdwingt dat het connection object ook echt de juiste interface implementeert.
<?php
class Database_Class{
private $connection;
public function setConnection( Connection_Interface $obj ){
$this->connection = $obj;
}
}
?>
Als je nu in die setter een object meegeeft dat de Connection_Interface niet implementeert, dan zal je een runtime error krijgen.
oke, erwin zoals ik het nu begrijp volgens mij. dan heb ik zoiets?
<?php
interface Connection_Interface
{
public function __construct($hostname, $username, $pass, $database, $table, $connector);
public function openConnect();
public function pingServer();
public function closeConnect();
public function startQuery( $sql );
public function getResults();
}
?>
vervolgens maak ik een class die deze implementeert. dat wordt dan de databaseConnect iets zoals.
<?php
class databaseConnect implements Connection_Interface
{
/**
* declareren van alle functies
*/
private $hostname;
private $username;
private $pass;
private $database;
private $table;
private $connector;
public function __construct($hostname, $username, $pass, $database, $table, $connector)
{
$this->databaseConfig = $databaseConfig;
}
public function __destruct()
{
#destroy function
}
// open connectie
public function openConnect()
{
try
{
if($this->databaseConfig->connector == "mysql")
{
$this->openConnect = mysql_connect($this->databaseConfig->hostname, $this->databaseConfig->username, $this->databaseConfig->pass);
$this->databaseConnect = mysql_select_db($this->databaseConfig->database);
}
}
catch (Exception $e)
{
return $e;
}
}
#run een query
public function startQuery($runQuery)
{
}
#sluit connectie
public function closeConnect()
{
}
/*
* ping server om te zien of deze open verbinding heeft.
*/
public function pingServer()
{
}
public function getResults()
{
}
}
?>
ga ik zo de goede kant op hiermee?
[size=xsmall]Toevoeging op 11/06/2012 10:39:19:[/size]
en hier even hoe ik de volledige code heb met deze gedachte van die implement ( het is natuurlijk niet goed nog ) maar even om te zien hoe ik het heb.
Je gaat de goede kant op, alleen moet je dit niet doen:
if($this->databaseConfig->connector == "mysql")
Het hele idee van het op deze manier opbouwen is dat je de verschillende databases (en verschillende technische methodes om ze aan te roepen) scheidt in verschillende connectie classes. Dus je hebt een class voor mysql, je hebt een class voor DB2, voor Oracle etc. En als je mysql_, mysqli_ en pdo wilt gebruiken heb je daar ook ieder een class voor. Binnen de connectie class gebruik je dus altijd maar 1 van die technieken en hoef je dus nooit te checken welke je gebruikt.
ja dat snap ik nu :) ik twijfelde er zelf ook al over. heb nu die controle weggehaald.
nu heb ik een klein vraagje. ik heb nu dus
<?php
interface Connection_Interface
{
}
class databaseConnectMySql implements Connection_Interface
{
}
// en
class databaseConfig
{
}
?>
maar wat is nu die class databaseConfig in dit geval? hoort dit een abstract class te zijn? want de gegevens ervan ( om een verbinding tot stand te brengen ) wordt pas later gegeven toch? en blijft dit dan een standalone class of moet deze extend worden?
Als je databaseConfig als class wilt instantieren dan kan het geen abstracte class zijn. Als je het echter als superclass wilt gebruiken zoals Wouter aangaf en pas in afgeleide classes de functionaliteit wilt completeren dan zou ik er wel een abstracte class van maken. Op die manier voorkom je dat deze class op zichzelf gebruikt kan worden.
Of je het moet extenden of niet is geen antwoord op te geven. Dat ligt totaal aan hoe je er verder mee wilt werken.