JeuWeb - Crée ton jeu par navigateur
Que peut apporter une classe MySQL ? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Que peut apporter une classe MySQL ? (/showthread.php?tid=2013)

Pages : 1 2 3


RE: Que peut apporter une classe MySQL ? - Loetheri - 14-11-2007

Rien dit, rien fait ...


RE: Que peut apporter une classe MySQL ? - Plume - 14-11-2007

Citation :Enfin, bon, à ce que je vois, je ne dirai plus rien sur tout ce qui touche l'OO.
Mais non ! Tu veux ma main dans ta bouille ? :boxe:

~L~


RE: Que peut apporter une classe MySQL ? - Zamentur - 15-11-2007

Citation :La définition de ta fonction extract_one a, je suppose, un LIMIT caché ?
En fait non, j'y ai pensé, mais finalement je l'ai pas fait car dans la plus part des cas il s'agit d'utilisation de clé unique , donc pas besoin de LIMIT rajouté par la fonction
Du coup je rajoute moi meme le LIMIT si c'est vraiment nécéssaire

Mais bon c'est une ancienne version , je suis justement en train de me diriger vers le meme genre de chose que LexLxUs . Et surtout je vais rajouter d'autres fonctions (comme extract_one) qui permetront de faire des actions souvent faites en termes de requete

Citation :Pour moi, une classe/série de fonctions de BdD est utile si tu implémentes des fonctionnalités te permettant réellement d'aller plus vite, d'éviter de faire des trucs rébarbatifs.
Ben n'est ce pas ce que montre mes methodes extract_one et extract_ladata?

Citation :Cela dit, pour ta fonction d'erreur, c'est bien tant que tu développes mais elle n'est pas une fonction de production.
Oui et non. Ma fonction d'erreur enregistre toute les erreurs qui se produise, en l'occurance si çà arrive dans la version de production je veux etre avertit. Et oui car en cas de bug sur la version de production il faut pouvoir determiner ceux qui sont touché par le probleme pour pouvoir le corriger si besoin!
Sinon tu auras foule de joueur qui viendront quémander une réparation qu'il n'ont pas lieu de toucher...
Et puis sur Ragol, j'avais pas pensé à discocier le dev, de la production. Du coup, je programmais directement avec une petite condition pour indiquer qu'une partie était en beta (et donc accessible qu'à une categorie de gens)
C'est vrai que pour Algol une station de dev (sur un serveur maison) est en train d'etre mise en place, mais bon tout çà çà suppose qu'il ya 0 bug sur la station de production...

Suis je le seul à dire que je ne suis pas sur à 100% qu'il y aura 0 bug (ou plutot que je suis sur qu'il y en aura)?

Enfin bon dans tout les cas je laisse la gestion d'erreur en production.


RE: Que peut apporter une classe MySQL ? - naholyr - 15-11-2007

Zamentur a écrit :Suis je le seul à dire que je ne suis pas sur à 100% qu'il y aura 0 bug (ou plutot que je suis sur qu'il y en aura)?
Il n'y a que ceux qui ne savent pas développer qui pensent pouvoir produire des applications sans bug Wink


RE: Que peut apporter une classe MySQL ? - Ludvig - 19-11-2007

Prélude a écrit :Les premiers compilateur GCC ne faisaient que transformer en C puis compiler derrière.
En effet, ce n'est qu'une surcouche.

Eh sauf que là c'est compilé, donc tu perds en temps de compilation, mais pas en exécution.

C'est tout la différence entre C++ et par exemple Java ou PHP.


Perso (perso hein :glace: ) c'est à cause de ça que je ne suis pas très chaud pour utiliser des classes PHP.
De plus pour faire du oop il manque pas mal de choses...


Pour pas être complètement à la rue j'ai fait quelques fonctions que je trouve très utile :

function getsql($query) //<-un simple requête qui retourne une reponse
function getsqlarr($query) //<-une requête type SELECT a,b,c FROM ... la reponse est un array
function setsql($query) //<-pour faire des UPDATE / INSERT / ...
function getallsql($query,&$nof) //<- où on utilise pas LIMIT 1, retourne un array + le nombre de réponses
function getmultisql($query,$rows,&$nof) //<- pour des requêtes type SELECT a,b,c FROM ... sans le LIMIT 1, on a une array avec a1,b1,c1,a2,b2,c2,a3 ...

Enfin, c'est très vieux jeu d'utiliser des fonctions mais je ne vois pas ce qu'il me faut de plus compliqué Tongue


/Lud *nouveau boulot - moins de temps pour le php Sad *


RE: Que peut apporter une classe MySQL ? - pascal - 19-11-2007

hs :

ça peut aussi apporter un sale bug de m*** lorsque l'architecture n'est pas respectée :

j'ai fini de migrer des données vendredi midi, alors j'attends un retour des utilisateurs : est-ce que tout va bien, pas de trucs en double, tout est là, tout ça...

ce soir vers 17h, après une relance, j'ai une réponse :
gros problème, les données sont là, mais en double :
genre une entreprise en 7 exemplaires, une autre en 33 versions ...

je suis dégouté, je vérifie mon script, la procédure, tout semble OK.

je vérifie les données, tout est OK, on n'a pas les 33 doublons...

donc c'est que la base est pas la bonne. je vérifie la config du site, elle est bonne. je vérifie la classe SQL, bingo !
la config a été copiée dans la classe, au lieu d'utiliser le fichier de config.

j'avais changé la config, pas la config de la classe SQL, tout ça parce quelqu'un n'a pas utilisé $GLOBALS ou global et a copié la config au lieu de chercher la syntaxe.

moralité :
_ ne pas repeter de code
_ centraliser la config, sans exception
_ filer la syntaxe à ma collègue

A+

Pascal


RE: Que peut apporter une classe MySQL ? - naholyr - 20-11-2007

Ouais enfin c'est effectivement totalement HS puisque ton problème c'est surtout une question de config mal foutue Tongue


RE: Que peut apporter une classe MySQL ? - Sephi-Chan - 25-11-2007

oxman a écrit :Je rejoins naholyr vis à vis de la page précédente, et à ce sujet, vous utilisez quelle db d'abstraction de bdd et pourquoi ? :o)

(Je sens que l'on va bien s'amuser avec ma question mdr)
Vous noterez que je parle bien des classes pour MySQL, et pas SQL de manière générale. Je ne veux donc pas parler des classes d'abstractions de SGBD qui sont à mon sens inutiles à un jeu par navigateur.

Merci.


RE: Que peut apporter une classe MySQL ? - naholyr - 25-11-2007

Fervent utilisateur de Symfony, j'utilise donc l'ORM Propel.
Avant j'étais assez fan de ezPdo mais c'est toujours un ORM.

Pour préciser, l'ORM se place encore au-dessus de la couche d'abstraction et permet de manipuler son modèle comme des objets sans se soucier des requêtes qui peuvent être réalisées derrière. Le danger c'est de se retrouver sans s'en rendre compte avec des pages présentant un nombre de requêtes absolument énorme (c'est particulièrement vrai et difficile à corriger avec ezPdo), mais dans le cas de Propel ça s'optimise très bien. Par exemple sur le forum de mon jeu je tourne à 8 requêtes sur la page d'affichage d'un thread (la plus gourmande). Sans ORM je pourrais probablement réduire à 6 ou 5, mais pour 25% de réduction du nombre de requêtes je perdrais bien plus en beauté du code Wink

Sinon pour la simple abstraction SQL je conseille toujours PEAR::ADODB2 qui est très complet.
Propel repose sur Creole qui est parfois un peu lourdingue dans sa syntaxe.

Et sinon dans le contexte de mon boulot j'ai parfois des collègues "pur php4" qui font du site jetable en série, et qui n'ont vraiment pas le temps de se préoccuper de ça. Je leur fournis une toute petite classe qui fait tout le travail dont tu parles et même un peu plus en quelques lignes, sa simplicité les a séduit. Je vous la fournis reformatée PHP5 :

Code PHP :
<?php

class SQL
{

const
PLACEHOLDER_MARKER = ':'

protected static $queries;

protected static
$connection;

/**
* Connexion à la base de données
*
* @todo DB-Abstraction (mysql_connect)
*/
public static function connect($infos)
{
$infos = array_merge(array(
'server' => 'localhost',
'username' => 'root',
'password' => ''), $infos);
self::$connection = mysql_connect($infos['server'], $infos['username'], $infos['password']);
if (!
self::$connection) {
return
false;
} else {
return
true;
}
}

/**
* Déconnexion de la base de données
*
* @todo DB-Abstraction (mysql_close)
*/
public static function disconnect()
{
mysql_close(self::$connection);
}

/**
* Retourne la liste des requêtes déjà exécutées par doQuery()
* Chaque item est un tableau (requête résolue, temps d'exécution de la requête elle-même, temps d'exécution total de la fonction doQuery, message d'erreur)
*/
public static function getQueries()
{
return
self::$queries;
}

/**
* Prépare une variable pour l'utilisation dans une requête SQL
* Exemples :
* SQL::escape('bonjour "Marcel" !') == '"bonjour \"Marcel\""' (utilisation de mysql_real_escape_string)
* SQL::escape(array(1, 2, 3, 4, 5)) == '(1,2,3,4,5)' (chaque variable du tableau est bien sûr échappée)
* SQL::escape(NULL) == 'NULL'
*
* @todo DB-Abstraction (mysql_real_escape_string)
*/
public static function escape($variable)
{
switch (
gettype($variable)) {
case
'array':
$escaped_values = array();
foreach (
$variable as $value) {
$escaped_values[] = self::escape($value);
}
return
'(' . implode(',', $escaped_values) . ')';
case
'string':
return
'"' . mysql_real_escape_string($variable, self::$connection) . '"';
case
'boolean':
return
$variable ? 1 : 0;
case
'integer':
case
'double':
return
$variable;
case
'NULL':
return
'NULL';
default:
// object, resource, etc... types non gérés
return false;
}
}

/**
* Renvoie la requête préparée
* $query est la requête originale, avec des "placeholders" notés ":nom-de-clé"
* Exemple : 'SELECT name FROM users WHERE id IN :ids'
* $values est la liste des variables par lesquelles seront remplacés les "placeholders"
* Exemple : array('ids' => array(1, 3, 9))
* Exemple :
* SQL::getQuery('SELECT name FROM users WHERE id IN :ids', array('ids' => array(1, 3, 9)))
* == 'SELECT name FROM users WHERE id IN (1,3,9)'
*/
public static function getQuery($query, $values = array())
{
// On trie le tableau $values selon les index, afin d'être sûr de ne pas avoir de
// conflit (par exemple entre :user et :username)
krsort($values);
// On remplace chaque :key par self::escape($values[key])
foreach ($values as $key => $value) {
$query = str_replace(self::PLACEHOLDER_MARKER . $key, self::escape($value), $query);
}
return
$query;
}

/**
* Prépare et exécute une requête, le résultat renvoyé dépend de la requête :
* - INSERT => renvoie le nombre de lignes insérées
* - UPDATE => renvoie le nombre de lignes mises à jour
* - DELETE => renvoie le nombre de lignes supprimées
* - REPLACE => renvoie le nombre de lignes affectées
* - SELECT => renvoie la liste des résultats (objets)
* - autres => renvoie la ressource non traitée
* En cas d'erreur, renvoie false
*
* @todo DB-Abstraction (mysql_query + mysql_free_result)
*/
public static function doQuery($query, $values)
{
$start_func = microtime(true);
$query = self::getQuery($query, $values);

$start_query = microtime(true);
$res = mysql_query($query, self::$connection);
$time_query = microtime(true) - $start_query;

if (
$res) {
switch (
strtoupper(substr(ltrim($query), 0, 7))) {
case
'INSERT ':
case
'UPDATE ':
case
'DELETE ':
case
'REPLACE':
$result = self::getAffectedRows();
mysql_free_result($res);
break;
case
'SELECT ':
$result = array();
while (
$row = mysql_fetch_object($res)) {
$result[] = $row;
}
mysql_free_result($res);
break;
default:
$result = $res;
}
}

$time_func = microtime(true) - $start_func;
self::$queries[] = array($query, $time_query, $time_func, self::getError());

return
$res ? $result : false;
}

/**
* Renvoie l'ID de la dernière ligne insérée (n'a de sens que s'il y a un champ
* AUTO_INCREMENT et que la dernière requête est un INSERT).
*
* @todo DB-Abstraction (mysql_insert_id)
*/
public static function getLastInsertID()
{
return
mysql_insert_id(self::$connection);
}

/**
* Renvoie le nombre de lignes concernées par la dernière requête
*
* @todo DB-Abstraction (mysql_affected_rows)
*/
public static function getAffectedRows()
{
return
mysql_affected_rows(self::$connection);
}

/**
* Renvoie l'erreur rencontrée lors de la dernière requête
*
* @todo DB-Abstraction (mysql_error)
*/
public static function getError()
{
return
mysql_error(self::$connection);
}

}

Ce n'est pas une couche d'abstraction, pour cela il faudrait sortir les fonctions "spécifiques", faire une interface, et implémenter le design pattern factory. Ça fait ce que c'est censé faire : aider mes collègues à faire des requêtes sécurisées avec MySQL, et puis ça préparer bien le terrain pour un DBAL quand-même Wink

Et puis les placeholders, en plus de sécuriser de manière transparente la requête, ça rend souvent les appels de requête bien plus lisibles.
Les deux fonctionnalités qui leur changent vraiment la vie ce sont les placeholders et le fait que doQuery('SELECT ...') renvoie directement la liste des résultats.

Dans la "vraie" classe c'est du PHP4, il n'y a pas de commentaires mais un readme.txt, et les temps ne sont pas loggées (juste la requête et le message d'erreur éventuel) :lol:


RE: Que peut apporter une classe MySQL ? - Sephi-Chan - 25-11-2007

Je ne comprends pas bien ce que fait ce fameux placeholder. Tu peux expliquer s'il te plaît ? Confused