Class PDO²

Mammouth du PHP | 19672 Messages

11 mai 2008, 13:27

Dans ta fonction, $lien n'est défini nulle part, et donc pas comme objet non plus :arrow: erreur automatique.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 209 Messages

11 mai 2008, 13:49

Oui, d'ailleurs je me suis gouré dans le code que j'ai mis, ça c'était la première chose que j'avais testé.
Après, en fait, j'ai fait ceci, qui donne la même erreur :
	public function query($mysql)
	{
		return($this->lien->query($mysql));
	}
Mais j'avoue ne pas y comprendre grand chose, normalement le $this->lien contient PDO non ?

j'ai aussi essayé ça :
	public function query($mysql)
	{
		return(PDO::query($mysql));
	}
Normalement ça marche ça nan ?

Mammouth du PHP | 1668 Messages

11 mai 2008, 14:35

Bon, comme vous le savez je suis pas alaise en POO mais je pense que c'est ça :
public function query($mysql) 
    { 
        return(parent::query($mysql)); 
    } 
"À ceux qui poursuivent leurs rêves et se spécialisent dans l'impossible" Joseph Kong

10 ans de PHP, déjà.

"moi jtrouve que katagoto il déchire!" Nagol

Eléphant du PHP | 209 Messages

11 mai 2008, 14:47

Marche pas...
Ca fait même planter Apache, comme la dernière solution que j'ai proposé.
Par contre avec l'héritage, j'ai envie de dire que ça à l'avantage d'être immédiat, c'est plus logique (je trouve) :
Class SQl extends PDO
{
    public $lien;
    public function __construct($url, $login, $password, $nom){
        try
        {
            $lien = parent::__construct('mysql:host='.$url.';dbname='.$nom, $login, $mdp);
        }

        catch(Exception $e)
        {
            //Erreur
        }

    } 
}
Avec ça, je dois juste faire $sql->query(...)

Mammouth du PHP | 1668 Messages

11 mai 2008, 14:58

Ca change de la méthode procédurale, c'est plus simple a comprendre et ça nous permet de séparer l'affiche du "hard coding", c'est différent...
"À ceux qui poursuivent leurs rêves et se spécialisent dans l'impossible" Joseph Kong

10 ans de PHP, déjà.

"moi jtrouve que katagoto il déchire!" Nagol

Mammouth du PHP | 983 Messages

11 mai 2008, 16:17

L'héritage casse le principe d'encapsulation. Une sous classe dépend du fonctionnement de la classe mère (en l'occurrence la classe PDO ici). Il faut au maximum éviter la dépendance à l'implémentation et travailler sur le concept de contrat (programmer par interface).
Sur un plan purement logique, un point m'échappe dans ce raisonnement.

Je pars du principe de base que les fonctions natives d'une version stable d'un langage n'évolueront à priori pas de façon régressives, l'extension ne posera pas de problème dans le temps. Mais comme tu l'as souligné, si on suppose que l'évolution du langage déclare la classe PDO final et donc non extensible, tu n'auras pas le choix de faire une composition. En revanche, pour une modification dans son fonctionnement, que ce soit par héritage ou composition, tu vas quand même te heurter à un problème. L'objet instancié n'aura pas le même comportement et du coup son utilisation dans ta propre classe, qu'elle étende PDO ou en utilise une instance de composition, en sera modifiée également parce que le comportement des méthodes ou des propriétés en aura été modifié... Le résultat de ta propre classe sera donc obligatoirement différent aussi, non ?

Notez que je ne suis pas un gourou de la POO loin s'en faut, je pars peut-être d'une erreur d'interprétation :-k
Tout à fait Cyrano, l'exemple que j'ai donné n'est pas bon. Je voulais dire que tu es dépendant de l'implémentation de la classe mère pas de son contrat (puisque si son contrat change, tu es impacté dans tous les cas).
Prenons un exemple plus concret. Imaginons que tu aies besoin d'étendre PDOStatement pour des raisons diverses, il faut alors l'indiquer à PDO (exemple issu des commentaires de la doc) :
class PDO   {
    class Database extends PDO {
    function __construct($dsn, $username="", $password="", $driver_options=array()) {
        parent::__construct($dsn,$username,$password, $driver_options);
        $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DBStatement', array($this)));
    }
}
class DBStatement extends PDOStatement {
    public $dbh;
    protected function __construct($dbh) {
        $this->dbh = $dbh;
    }
}
L'implémentation de PDO fait que la connexion sera fermée seulement à la fin du script. Cela peut poser un problème car le comportement est changé car tu monopolises une connexion inutile à la base. Si tu es dans un environnement fortement sollicité ou si ton traitement dure longtemps, tu pourrais donc saturer le nombre de connexions possibles.
Le code est donc clairement dépendant de l'implémentation de PDO. Si au contraire, tu utilises la composition, tu évites ce problème.

Je ne sais pas si c'est très clair...

Par expérience, j'ai développé un framework basé sur Zend Framework et j'ai massivement utilisé l'héritage plutôt que le composition. A chaque nouveau besoin où je suis obligé de modifier le comportement de classe mères, les applications qui utilisent les versions précédentes risquent de ne plus fonctionner, ou du patir d'effets de bords.
Cela ne pose pas de problème dans le cadre d'application standalone, mais dès que tu développes du code censé être réutilisable, ca devient un problème. Car si un de nos clients décident d'ajouter des fonctionnalités à l'application, soit il faut adapter cette application au nouveau framework (ce qui peut être couteux), soit maintenir plusieurs versions du framework (ce qui n'est pas terrible non plus)