Un PDO "simplifié"

Mammouth du PHP | 1668 Messages

13 janv. 2009, 14:36

Bonjour à toutes et à tous,

Voilà, j'utilise intensément PDO, j'avais fais une classe ci-dessous qui gérait les erreurs uniquement :
<?php
/**
 * Classe de "étendu" de PDO
 * 
 * @author Katagoto
 */
class TPDO
{
	/**
     * L'instance de PDO 
     * 
     * @var PDO 
     */ 
	private $lien;

	/**
	 * NHombre de requêtes
	 *
	 * @var int
	 */

	public $NbRequete;

	/**
	 * Nombre de temps total pour le sql
	 *
	 * @var int
	 */

	public $Temps;

	/**
	 * Si le mode transactionnel est activé
	 *
	 * @var bool
	 */

	public $transaction = true;

     /**
     * Constructeur de sql 
     * 
     * Tente une connexion au serveur de BD 
     * 
     * @param string $url 
     * @param string $login 
     * @param string $password 
     * @param string $nom 
     */ 
	public function __construct($url, $login, $password, $nom)
	{
                    global $template;
		try
		{
			$temps = microtime(true);
			$this->lien = new PDO('postgresql:host='.$url.';dbname='.$nom, $login, $mdp);
			$this->Temps += ($temps - microtime(true));
		}

		catch(Exception $e)
		{
			$dernier = apc_fetch('bug_connexion_sql', $existe);

			if (DEBUG || ($existe && $dernier > (time()-(15*60))))
			{
				apc_store('bug_connexion_sql', time());

				@mail(LIST_MAIL,
				'Avertissement de sécurité la Connexion à la Base de Données du site est impossible',
				@file_get_contents(ABS_DIR.'templates/fr/bug/sql/mail/connexion_impossible.html').$e->getMessage().'</p><p>Description :'.$e->__toString().'</div></body></html>');
			}


			$template->parse('bug/sql/connexion_impossible.html');
			exit();
		}

	}

     /**
     * Surcharge des méthodes PDO 
     * 
     * @param string $m nom de la méthode 
     * @param array $a arguments à passer à la méthode 
     * @throws BadMethodCallException si la méthode $m n'existe pas 
     */ 
	public function __call($m, $a)
	{
                   global $template;
		if(method_exists($lien, $m))
		{

			try
			{
				$lien->beginTransaction();
				$this->NbRequete++;
				$temps = microtime(true);
				$copie =& $this->lien->$m($a);
				$this->Temps += ($temps - microtime(true));
				$this->lien->closeCursor();
				if ($lien->commit())
				{
					throw PDOException('Exécution impossible d\'une requête :'.var_dump($a));
				}
				return $copie;
			}
			catch (PDOException $e)
			{
				if ($this->transaction)
				{
					$this->lien->rollBack();

					$dernier = apc_fetch('bug_requete_sql', $existe);

					if (DEBUG || ($existe && $dernier > (time()-(15*60))))
					{
						apc_store('bug_requete_sql', time());
						@mail(LIST_MAIL,
						'Avertissement de sécurité une requête à la Base de Données du site est impossible',
						@file_get_contents(ABS_DIR.'templates/fr/bug/sql/mail/requete_impossible.html').$e->__toString().'</div></body></html>');
					}

					else
					{
						throw new BadMethodCallException('La méthode PDO->$m() n\'existe pas!');
					}
					$template->parse('bug/sql/requete_impossible.html');

				}
			}
		}
	}
	
	/**
	 * Surcharge de PDO::prepare
	 *
	 * @param str $requete
	 * @return TPDOStatement
	 */
	
	public function prepare($requete)
	{
                   global $template;
			try
			{
				$lien->beginTransaction();
				$this->NbRequete++;
				$temps = microtime(true);
				$copie =& new PDOStatement($requete);
				$this->Temps += ($temps - microtime(true));
				return $copie;

			}
			catch (PDOException $e)
			{

					if (DEBUG || ($existe && $dernier > (time()-(15*60))))
					{
						apc_store('bug_requete_sql', time());
						@mail(LIST_MAIL,
						'Avertissement de sécurité une requête à la Base de Données du site est impossible',
						@file_get_contents(ABS_DIR.'templates/fr/bug/sql/mail/requete_impossible.html').$e->__toString().'</div></body></html>');
					}

					else
					{
						throw new BadMethodCallException('La méthode PDO->$m() n\'existe pas!');
					}
					$template->parse('bug/sql/requete_impossible.html');

				}

	}

}
Seulement, cette classe à un vis : elle ne fonctionne que pour PDO...
100% de nos requêtes étant préparées, comment faire pour qu'elle englobe PDOStatement et ainsi comptabilise le temps ? Y a-t'il des choses à améliorer/changer ?

Par avance merci de votre aide...
"À 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

ViPHP
ViPHP | 4674 Messages

13 janv. 2009, 17:40

Hey :),

Il faut faire des wrappers pour les classes PDO et PDOStatement. Grosso modo, tu passeras toujours par un classe qui ne fait que rediriger les appels vers PDO et pareil pour PDOStatement. De cette façon, tu caches PDO, tu captures les erreurs qui remontent, bref t'es plus libre.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Mammouth du PHP | 1668 Messages

13 janv. 2009, 19:22

Un petit indice SVP m'sieur ?

Par avance merci de votre aide
"À 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

ViPHP
ViPHP | 4674 Messages

13 janv. 2009, 19:32

Très rapidement :
class Wrapper_Pdo {

    protected $_pdo = null;



    public function __construct ( $arg1, ..., $argn ) {

        $this->_pdo = new PDO($arg1, ..., $argn);
    }

    public function exec ( $statement ) {

        return $this->_pdo->exec($statement);
    }

    public function query ( $statement ) {

        try {

            $statement = $this->_pdo->query($statement);
        }
        catch ( PDOStatement $e ) {

            $e->raiseError();
        }

        return new Wrapper_PdoStatement($statement);
    }

    ...
}
Et :
class Wrapper_PdoStatement {

    protected $_statement = null;



    public function __construct ( PDOStatement $statement ) {

        $this->_statement = $statement;
    }

    public function execute ( Array $parameters = array() ) {

        return $this->_statement->execute($parameters);
    }

    ...
}
Tout simplement. Tu peux tout récupérer. C'est une sorte de Programmation Orientée Aspect si tu connais.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Mammouth du PHP | 1668 Messages

13 janv. 2009, 19:56

Non, et c'est ce que je pensais faire :/

Donc il y a pas plus simple, dommage

Merci
"À 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

ViPHP
ViPHP | 4674 Messages

13 janv. 2009, 20:03

Disons que c'est simple quand même … très peu de code, léger, facile à maintenir etc., et c'est le plus abstrait possible. Comprends le plus complet possible. Tu gères tout les cas en faisant ça, et tu peux intervenir où tu veux :).
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

ViPHP
ViPHP | 2287 Messages

14 janv. 2009, 13:41

En français, on appelle simplement cela l'encapsulation ;-)
if(!@work()){ Nespresso(); } else { what(); }
______________________________

ViPHP
ViPHP | 4674 Messages

14 janv. 2009, 14:03

L'encapsulation est le simple fait d'avoir des données avec un accès différent selon le contexte (public, protégé, privé). On a donc des méthodes pour accéder à ces données.

Le wrapper (l'emballage littéralement) pousse les choses plus loin avec des prémices de programmation orienté aspect. C'est surtout le fait de rediriger les appels, de les envelopper dans une nouvelle action, qui est important.

Évidemment que l'on a de l'encapsulation mais je tiens à faire la différence car l'emballage est plus poussé … ou du moins, il sert pas tout à fait à la même chose. L'encapsulation est une notion vraiment basique de la programmation orientée objet qu'on ne saurait comparer à l'emballage à niveau égal ;-).
Si on parle d'emballage, on voit la solution mais aussi le problème. Si on parle d'encapsulation, on voit une solution possible parmi beaucoup de problèmes. On n'est moins précis.

Mais la remarque est juste :).
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).