[PHP/MySQL] PDO Connectie in functies

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • P.B.
  • Registratie: Juli 2001
  • Niet online
Na hele lange tijd ben ik weer eens begonnen met PHP/MySQL. Tot mijn verbazing is mysql_ uit PHP verwijderd en vervangen door msqli_ en PDO.

Na wat onderzoek te doen ben ik erachter gekomen dat PDO de voorkeur geniet, dus heb ik mij daar enigszins ingelezen.

Ik ben bezig een website te maken die multilanguage moet zijn. Om PDO een beetje onder de knie te krijgen, probeer ik delen van die website in een testscriptje te testen.

Ik heb code gemaakt voor een lijstje met beschikbare talen, en een functie om de juiste tekst te krijgen die bij de taal hoort.

Code voor lijstje
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$dbh = new pdo("mysql:host=localhost;port=8889;dbname=abc", "root", "root", array (
  PDO::ATTR_PERSISTENT => true
));

$sth = $dbh->prepare("SELECT * FROM Languages");
$sth->execute();
$result = $sth->fetchAll();

if ($result != false) {
    $i = 0;
    foreach ($result as $row) {
      echo "<img src=\"assets/img/flags/" . $row['Flag'] . "\" style=\"max-width:100%; height:10px;\" title=\"". $row['LangLong'] . "\"/>&nbsp;" . strtoupper($row['LangShort']);
      if(++$i === count($result)){
        echo "&nbsp;";
      }else{
        echo "&nbsp;|&nbsp;";
      }
    }
}


Nu dan de functie voor het ophalen van een tekst (Content) die bij een taal hoort (LangID) en afgekort is in de HTML template met Short, in de tabel Text

PHP:
1
2
3
4
5
6
7
8
function get_text_short($short, $langid) {
      $dbh = new pdo("mysql:host=localhost;port=8889;dbname=abc", "root", "root");
      $sth = $dbh->prepare("SELECT Content FROM Text WHERE LangID = :langid AND Short= :short");
      $sth->bindParam(':langid', $langid);
      $sth->bindParam(':short', $short);
      $sth->execute();
      return $sth->fetchColumn();
    }


Als ik de tekst die in de tabel Text onder kolom Short staat aangemeld met lorum en LangID = 1, dan doe ik het volgende:

PHP:
1
echo(get_text_short("lorum", 1));


Tot zover werkt dit allemaal en ben ik er blij mee dat ik PDO redelijk onder de knie krijg.

Echter, mijn gevoel zegt dat het performance wise niet efficient gaat werken als er voor elke snippet aan tekst een nieuwe DB connectie moet worden gemaakt. Aan de andere kant, de PDO variabele global maken lijkt me ook niet de juiste weg. Is het nu vereist dat er voor elke database call, een nieuwe connectie moet worden gemaakt?

Ik kan op internet heel veel vinden, maar niet iets waarin staat of dit nou de juiste manier is of niet. Overigens, is dit wel veel ingewikkelder dan de oude mysql_ functies, naar mijn mening. Maar de security schijnt beter te zijn.

[ Voor 3% gewijzigd door P.B. op 18-12-2017 20:55 ]


Acties:
  • 0 Henk 'm!

  • HollowGamer
  • Registratie: Februari 2009
  • Niet online
Tuurlijk niet, daarom werk je ook met classes.
Doe jezelf en je carrière (als je daarin verder wilt) en leer gewoon een framework (Laravel of iets in die richting).

Verder is PDO al een hele lang tijd en is inderdaad het stukken veiliger om hiermee te werken.
Echter moet je wel data valideren en eventueel filteren, iets dat je hier niet doet.

Acties:
  • +3 Henk 'm!

  • mcDavid
  • Registratie: April 2008
  • Laatst online: 02-10 08:45
P.B. schreef op maandag 18 december 2017 @ 20:36:
Na hele lange tijd ben ik weer eens begonnen met PHP/MySQL. Tot mijn verbazing is mysql_ uit PHP verwijderd en vervangen door msqli_ en PDO.
Lolwat? :D Die functies zijn pas 5 jaar deprecated of zo? En gebruik ervan werd al láng daarvoor afgeraden...
Tot zover werkt dit allemaal en ben ik er blij mee dat ik PDO redelijk onder de knie krijg.

Echter, mijn gevoel zegt dat het performance wise niet efficient gaat werken als er voor elke snippet aan tekst een nieuwe DB connectie moet worden gemaakt.

Ik kan op internet heel veel vinden, maar niet iets waarin staat of dit nou de juiste manier is of niet. Overigens, is dit wel veel ingewikkelder dan de oude mysql_ functies, naar mijn mening. Maar de security schijnt beter te zijn.
Daar heb je helemaal gelijk in. Het is dan ook nogal een rare constructie dat je die database connectie in dezelfde functie aanmaakt als waarin je een query uitvoert. Normaalgesproken zou je die database connectie instantiëren in een database class. Die database-class geef je mee als dependency aan de class waarin je een query wilt doen. Maar zo te zien ben je nog niet helemaal up-to-speed met object-georienteerd programmeren, dus zal dit nogal ingewikkeld klinken. Dat is waarschijnlijk ook de reden dat je het moeilijker vindt, PDO ("PHP Data Objects") is volledig OO opgezet, en als je OO programmeert is het juist supermakkelijk.

Ik zou je echt aanraden je meer in OO te verdiepen want zonder is er eigenlijk geen goeie manier om dit op te lossen.
Wat je zou kunnen doen is je database-connectie meegeven als parameter aan deze functie (lelijk), of deze global maken (nog veel lelijker) zodat je hem vanuit de functie kunt benaderen.

Overigens zou je dit zelfde problemen ook gehad hebben met de oude mysql-functies of mysqli-functies. Het zou er hooguit wat minder uit de toom uitzien omdat je alles sequentieel zou kunnen doen.


Dan last but not least: PDO is niet persé veiliger. Geparameteriseerde queries gebruiken is veiliger. En PDO leent zich daar erg goed voor. Maar als je wilt kun je nog steeds dezelfde gevaarlijke fouten maken als vroeger, dus blijf opletten wat je doet en stop niet zomaar user input in een query!

Acties:
  • +1 Henk 'm!

  • CyberJack
  • Registratie: Augustus 2002
  • Laatst online: 06-10 12:15
HollowGamer schreef op maandag 18 december 2017 @ 21:05:
Doe jezelf en je carrière (als je daarin verder wilt) en leer gewoon een framework (Laravel of iets in die richting).
Doe je zelf en je carrière (als je daarin verder wilt) een plezier en leer eerst OO php.
Een framework leren en gebruiken kan daarna altijd nog, maar zonder goede basis heb je hier ook niet veel aan.

https://bottenberg.dev


Acties:
  • +1 Henk 'm!

  • HollowGamer
  • Registratie: Februari 2009
  • Niet online
CyberJack schreef op dinsdag 19 december 2017 @ 10:35:
[...]


Doe je zelf en je carrière (als je daarin verder wilt) een plezier en leer eerst OO php.
Een framework leren en gebruiken kan daarna altijd nog, maar zonder goede basis heb je hier ook niet veel aan.
Genoeg mensen die ook begonnen zijn met een framework eerst. ;)

Al ben ik wel met je eens dat OO leren een betere eerst stap is. :)

@Verwijderd Ben misschien wat hard, maar inderdaad zoals aangeven door @mcDavid zijn deze al een hele lang tijd deprecated.

Verder is tegenwoordig scheiding wel zo fijn, als je OO leert, kijkt dan ook eens naar MVC.

Acties:
  • +3 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Als je dit soort vragen stelt ben je volgens mij precies dat aan het doen: OO leren. Niet iedereen leert op dezelfde manier he.

Dat terzijde, als je een database-verbinding leert zien als een afhankelijkheid om je database-query te doen, en het altijd goed is om afhankelijkheden expliciet te maken, dan ben je al een heel eind op weg om het te leren. Immers, als je een functie schrijft, dan zijn de parameters van die functies de afhankelijkheden van die functie om te kunnen functioneren.

Classes zijn in de allereerste basis niet veel anders dan namespaces waarin je bij het maken van een object "alvast" wat parameters voor alle methods (functies als eigenschap van zo'n object) meegeeft.

Dus van:
PHP:
1
2
3
4
function get_some_stuff($a, $b) {
    $pdo = new Pdo('...')
    return $pdo->do_something_with_pdo($a, $b);
}


PHP:
1
2
3
4
5
6
7
$pdo = new PDO('....');

function get_some_stuff(\PDO $pdo, $a, $b) {
    return $pdo->do_something_with_pdo($a, $b);
}

get_some_stuff($pdo, "waa", "meu");


naar:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
class SomeDao {
   function __construct(\PDO $pdo) {
      $this->pdo = $pdo;
   }

   function get_some_stuff($a, $b) {
      return $this->pdo->do_something_with_pdo($a, $b);
   }
}
$pdo = new Pdo('...');
$o = new SomeDao($pdo);
$o->get_some_stuff("waa", "meu");


Vervolgens kun je nog verder gaan abstraheren, maar encapsulation (wat de term is voor wat in het voorbeeld hierboven met `$this->pdo` gebeurt) is een eerste stap.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • +1 Henk 'm!

  • P.B.
  • Registratie: Juli 2001
  • Niet online
Dank voor al jullie reacties, het wordt zeer gewaardeerd.
HollowGamer schreef op maandag 18 december 2017 @ 21:05:
Tuurlijk niet, daarom werk je ook met classes.
Doe jezelf en je carrière (als je daarin verder wilt) en leer gewoon een framework (Laravel of iets in die richting).

Verder is PDO al een hele lang tijd en is inderdaad het stukken veiliger om hiermee te werken.
Echter moet je wel data valideren en eventueel filteren, iets dat je hier niet doet.
Ik doe dit niet beroepsmatig maar meer hobbymatig en incidenteel.
mcDavid schreef op maandag 18 december 2017 @ 21:12:
[...]
Lolwat? :D Die functies zijn pas 5 jaar deprecated of zo? En gebruik ervan werd al láng daarvoor afgeraden...
[...]


Daar heb je helemaal gelijk in. Het is dan ook nogal een rare constructie dat je die database connectie in dezelfde functie aanmaakt als waarin je een query uitvoert. Normaalgesproken zou je die database connectie instantiëren in een database class. Die database-class geef je mee als dependency aan de class waarin je een query wilt doen. Maar zo te zien ben je nog niet helemaal up-to-speed met object-georienteerd programmeren, dus zal dit nogal ingewikkeld klinken. Dat is waarschijnlijk ook de reden dat je het moeilijker vindt, PDO ("PHP Data Objects") is volledig OO opgezet, en als je OO programmeert is het juist supermakkelijk.

Ik zou je echt aanraden je meer in OO te verdiepen want zonder is er eigenlijk geen goeie manier om dit op te lossen.
Wat je zou kunnen doen is je database-connectie meegeven als parameter aan deze functie (lelijk), of deze global maken (nog veel lelijker) zodat je hem vanuit de functie kunt benaderen.

Overigens zou je dit zelfde problemen ook gehad hebben met de oude mysql-functies of mysqli-functies. Het zou er hooguit wat minder uit de toom uitzien omdat je alles sequentieel zou kunnen doen.


Dan last but not least: PDO is niet persé veiliger. Geparameteriseerde queries gebruiken is veiliger. En PDO leent zich daar erg goed voor. Maar als je wilt kun je nog steeds dezelfde gevaarlijke fouten maken als vroeger, dus blijf opletten wat je doet en stop niet zomaar user input in een query!
De laatste keer dat ik PHP/MySQL intensief heb gedaan is inmiddels reeds vele jaren geleden. Toen was het nog gebruik om 'procedural' te programmeren. Ik heb mij nu naar aanleiding van dit topic, meer in OO verdiept (dit is voor mij iets nieuws) en hoewel ik het in eerste instantie niet begreep, kan ik het nu beter begrijpen na wat praktijktoepassingen.
drm schreef op dinsdag 19 december 2017 @ 18:52:
Als je dit soort vragen stelt ben je volgens mij precies dat aan het doen: OO leren. Niet iedereen leert op dezelfde manier he.

Dat terzijde, als je een database-verbinding leert zien als een afhankelijkheid om je database-query te doen, en het altijd goed is om afhankelijkheden expliciet te maken, dan ben je al een heel eind op weg om het te leren. Immers, als je een functie schrijft, dan zijn de parameters van die functies de afhankelijkheden van die functie om te kunnen functioneren.

Classes zijn in de allereerste basis niet veel anders dan namespaces waarin je bij het maken van een object "alvast" wat parameters voor alle methods (functies als eigenschap van zo'n object) meegeeft.

Dus van:
PHP:
1
2
3
4
function get_some_stuff($a, $b) {
    $pdo = new Pdo('...')
    return $pdo->do_something_with_pdo($a, $b);
}


PHP:
1
2
3
4
5
6
7
$pdo = new PDO('....');

function get_some_stuff(\PDO $pdo, $a, $b) {
    return $pdo->do_something_with_pdo($a, $b);
}

get_some_stuff($pdo, "waa", "meu");


naar:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
class SomeDao {
   function __construct(\PDO $pdo) {
      $this->pdo = $pdo;
   }

   function get_some_stuff($a, $b) {
      return $this->pdo->do_something_with_pdo($a, $b);
   }
}
$pdo = new Pdo('...');
$o = new SomeDao($pdo);
$o->get_some_stuff("waa", "meu");


Vervolgens kun je nog verder gaan abstraheren, maar encapsulation (wat de term is voor wat in het voorbeeld hierboven met `$this->pdo` gebeurt) is een eerste stap.
Dit antwoord heeft mij ENORM geholpen. Nu begin ik het beter te begrijpen. Ik begrijp nu ook pas dat PDO een soort Class is, waar je dus een object mee kan maken. Heel erg bedankt, @drm ! _/-\o_
Ik ga mij nog verder verdiepen in OO en hopelijk kan ik het in redelijk korte termijn goed begrijpen. In eerste instantie lijkt het heel moeilijk maar naarmate ik er verder in kom wordt het steeds makkelijker.

De code is nu als volgt geworden:

PHP:
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
class DAO {

  function __construct(\PDO $pdo) {
    $this->pdo = $pdo;
  }

  function get_text_short($short, $langid) {
    $sth = $this->pdo->prepare("SELECT Content FROM Text WHERE LangID = :langid AND Short= :short");
    $sth->bindParam(':langid', $langid);
    $sth->bindParam(':short', $short);
    $sth->execute();
    return $sth->fetchColumn();
  }

  function get_languages() {
    $sth = $this->pdo->prepare("SELECT * FROM Languages");
    $sth->execute();
    $result = $sth->fetchAll();

    if ($result != false) {
        $i = 0;
        $output = "";
        foreach ($result as $row) {
          $output = $output . "<img src=\"assets/img/flags/" . $row['Flag'] . "\" style=\"max-width:100%; height:10px;\" title=\"". $row['LangLong'] . "\"/>&nbsp;" . strtoupper($row['LangShort']);
          if(++$i === count($result)){
            $output = $output . "&nbsp;";
          }else{
            $output = $output . "&nbsp;|&nbsp;";
          }
        }
    }else{
      $output = "No languages are defined";
    }
  return $output;
  }

}

$dbh = new pdo("mysql:host=localhost;port=8889;dbname=abc", "root", "root", array (
  PDO::ATTR_PERSISTENT => true
));

$content = new DAO($dbh);
echo $content->get_languages() . '<br /><br />' . $content->get_text_short("lorum", 1);

Acties:
  • 0 Henk 'm!

  • mcDavid
  • Registratie: April 2008
  • Laatst online: 02-10 08:45
Je vergeet nu nog om $pdo als property te defineren in je class. Je gebruikt $this->pdo maar die property 'pdo' bestaat niet in deze class.

Waarschijnlijk zal PHP die wel dynamisch voor je declareren, maar wel een warning geven. Je IDE zal als het goed is ook waarschuwen dat je een undefined property gebruikt.

https://secure.php.net/ma...guage.oop5.properties.php

Verder klein tipje: een class genaamd "DAO" zegt mij niets. Die kan nog steeds 1000 verschillende dingen doen. Probeer je classnames beschrijvend te maken, dan hou je het overzichtelijk. Ook als je straks 1000 classes in je applicatie hebt.
Waarschijnlijk wil je in dit geval uiteindelijk 2 classes maken, één genaamd Content en één genaamd Language.
Pagina: 1