Avatar billede Slettet bruger
13. april 2010 - 01:20 Der er 14 kommentarer og
1 løsning

SQL link genbrug i Objekt Orienteret kode.

Hej Eksperter,

Hvordan håndterer i SQL links på tværs af forskellige objekter i PHP?

For mig at se er der tre muligheder - hvis man er konsekvent og ikke blander dem sammen ;-)

1) At lave et sql-link som gemmes i en variabel i starten af filen som starter objekterne og derefter sende den variable som en parameter til objektets construct funktion og derefter gemme det i en variabel i objektet. Det er den metode jeg bruger i øjeblikket.

2) At åbne og lukke sql-linket ved hvert kald i objekterne. Dette kunne jeg aldrig drømme om at gøre, fordi jeg formoder at det ville være en meget langsommelig løsning.

3) At køre 'programming-by-contract' stilen og antage at objektet aldrig instantieres uden at der er en sql forbindelse. Jeg kører ikke med forbindelser til forskellige databaser - så det er ikke noget problem ikke specifikt at angive sql-links på kald til fx mysql_query().

---

Mulighed nummer ét er den jeg bruger i øjeblikket. Det virker som den mest "sikre" men er også en smule omstændig.

Jeg har et par spørgsmål til det her:

spm.1: Vil løsning 3 overhovedet virke?
spm.2: Er der andre alternativer til det jeg har nævnt?
spm.3: Hvilken løsning er at foretrække?

Håber på en lærerig debat ;-) For der er helt sikkert delte meninger om det her!
Avatar billede Slettet bruger
13. april 2010 - 01:25 #1
I får lige et par kode eksempler på ovenstående 3 eksempler - tager forbehold for syntaxfejl - det er skrevet direkte i kommentarboksen :-)

1)
$sqlLink = mysql_connect(...);
mysql_select_db($sqlLink);

class Test
{
  private $sqlLink;

  function __construct($sqlLink) {
      $this->sqlLink = $sqlLink;
  }

  function Hej () {
      mysql_query(..., $this->sqlLink);
  }
}

(Dette kan laves nemmere ved at lade classes extende en abstrakt class som kun har construct funktionen, så længe man ikke har brug for construct funktionen i det nye objekt)
Avatar billede Slettet bruger
13. april 2010 - 01:27 #2
2)
class Test
{
  function Hej () {
      $sqlLink = mysql_connect(...);
      mysql_select_db(..., $sqlLink);
      mysql_query(..., $sqlLink);
      mysql_close($sqlLink);
  }

  /* Processen gentaget individuelt i hver funktion der kræver
    * adgang til databasen */

}
Avatar billede Slettet bruger
13. april 2010 - 01:29 #3
3)
$sqlLink = mysql_connect(...);
mysql_select_db($sqlLink);

class Test
{
  function Hej () {
      mysql_query(...);
  }
}

mysql_close($sqlLink);


(Til kodeeksempel 1 - der mangler selvfølgeligt en mysql_close til sidst...)

Jeg glæder mig til at høre jeres forslag :-)
Avatar billede Slettet bruger
13. april 2010 - 01:31 #4
Undskylder for spam posting - jeg burde være gået i seng! :-) Bliver nød til at genskrive første eksempel før det giver mening. Giv os en edit-button!

1)
$sqlLink = mysql_connect(...);
mysql_select_db($sqlLink);

class Test
{
  private $sqlLink;

  function __construct($sqlLink) {
      $this->sqlLink = $sqlLink;
  }

  function Hej () {
      mysql_query(..., $this->sqlLink);
  }
}

$test = new Test($sqlLink);

mysql_close($sqlLink);
Avatar billede arne_v Ekspert
13. april 2010 - 05:46 #5
#1 er pænt

#2 er pænt og performance problemet kan løses ved at bruge pconnect fremfor connect

#3 er ikke pænt
Avatar billede Slettet bruger
13. april 2010 - 11:42 #6
Tak Arne.

Er glad for at se at jeg ikke er helt galt på den. #1 og #3 svarene er som forventet.

Ang. #2: pconnect virker som en rigtig god løsning faktisk. Tak for prejet :-) I følge kommentarer på www.php.net/mysql_pconnect så er det dog ikke et performance issue at connecte og close flere gange så længe at mysql serveren er på LAN med serveren eller kører på selve serveren. Jeg har bare en instinktiv modstand mod det ;-)

1'eren er stadig min foretrukne løsning da den giver mindst mulig koderod. Man kunne jo lave en abstract class som alle andre extendede som havde __construct funktionen der gemte linket. Så må man bare undvære __construct i de øvrige objekter - men det virker ikke som det store tab. :-)

Desuden kunne man lave sql connecteren i en klasse for sig - for maximized code cleaness. Som nedenstående eksempel:

class SQL
{
  public $link;
  function __connect() {
      $sqlLink = mysql_connect();
      mysql_select_db(..., $sqlLink);
      $this->link = $sqlLink;
  }
  function __destruct() {
      mysql_close($sqlLink);
  }
}

$sql = new SQL;

$test = new Test($sql->Link);
Avatar billede Slettet bruger
13. april 2010 - 11:43 #7
Så er det man skal overveje korrektur læsning...

__connect skal selvfølgeligt være __construct.

DAMMIT! Jeg ville give min højre arm for en edit knap.
Avatar billede arne_v Ekspert
13. april 2010 - 14:33 #8
Der er traditionelt en vis modstand mod connection pools (hvilket er hvad pconnect reelt er) i MySQL kredse.

Det er imidlertid helt standard med andre databaser og andre sprog. Og jeg kan ikke tro at MySQL er saa meget anderledes.

Med hensyn til pconnect skal man lige overveje hvordan PHP koeres CGI/FASTCGI/mod_php.
Avatar billede arne_v Ekspert
13. april 2010 - 14:33 #9
Det med at have en klasse som alt skal arve fra er sjaeldent en god loesning.
Avatar billede zynzz Praktikant
13. april 2010 - 19:54 #10
Jeg ville nok lade en singelton metode klare det i selve objektet...

fx.:
$this->database = Database::getInstance();

Database::getInstance(); retunere så mySQL linket....

Men ville mene din metode er lige så god, kan dog være tricky hvis du vil kalde den fra et scope hvor variablen ikke findes, men kommer igen an på hvad opgaven lyder på... :)
Avatar billede arne_v Ekspert
13. april 2010 - 22:03 #11
Givet at det er muligt maaske endda sandsynligt at man senere faar brug for mere end en connection, saa synes jeg ikke at singleton er nogen paen loesning.
Avatar billede zynzz Praktikant
14. april 2010 - 19:05 #12
Altså man jo starte flere objekert fx.:
Database::getInstance(1);  //Connection 1
Database::getInstance(2);  //Connection 2


Men det kommer jo igen an på hvad opgaven lyder på.., og hvis han alligevel bruger "Database klassen" i alle objekterne, er den jo nem at kalde frem i et andet scope, ved fx. oprettelse af et nyt objekt i et af de eksisterende objekter...
Avatar billede arne_v Ekspert
15. april 2010 - 02:46 #13
En connection egner sig ikke til singleton.

En connection pool egner sig glimrende til singleton.

Men når nu mysql extension allerede har en, så er der ikke så meget pointe.

Jeg ville naturligvis aldrig lave et connection pool API så man eksplicit skulle angive hvilket nummer connection man vil have.
Avatar billede zynzz Praktikant
16. april 2010 - 16:14 #14
Overstående kan du have ret i...
Avatar billede arne_v Ekspert
13. juni 2010 - 04:49 #15
Tid at få afsluttet her?

Og et svar fra mig.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester