[CREATION] Base de données en PHP sans MySQL (PHP4 - test en cours)

Base de données en PHP sans MySQL (PHP4 - test en cours) [CREATION] - PHP - Programmation

Marsh Posté le 16-06-2006 à 13:01:16    

!! IMPORTANT !!
 
[Edit]Fini !! Phase de test et optimisation du code.
 
Téléchargement : http://tousleschats.free.fr/hermes/bdd.zip
 
- Il ne s'agit pas de remplacer mySQL ou une autre BDD existante.
- Comme tout est en PHP4 (sans extension XML en plus), n'espérez pas gérer des millions d'enregistrements, vous mettrez à genou le serveur, vous êtes prévenu. :o
- Ce script est livré sans aucune garantie. Je ne suis responsable de rien en cas de perte de données, de serveur qui pête etc...  :o
- On peut :
 
  * Créer une table.
  * Effacer une table.
  * Insérer des données dans une table.
  * Sélectionner (récupérer) des données dans une table. (avec conditions, ordre et limites)
  * Détruire des données dans une table.
  * Updater des données dans une table.
 
 
Pourquoi avoir entrepris ce projet - Avantages
 
- La base ainsi créée est complêtement portable (>= PHP 4)
- La base est embarquée dans chacun de vos sites, ce qui fait que si vous sauvegardez votre site, la base est également sauvegardée.
- Au niveau sécurité, les gens peuvent toujours s'amuser à essayer les injections SQL. Il faut savoir que 98% des hacks de sites s'appuient sur des failles sessions et/ou mySQL.
- Pas de limites de requêtes puisque pas d'utilisation de mySQL.
 
Dans quels cas ce script peut-il être utilisé
 
- Si vous comptez sur cette BDD pour créer un forum ou une base de données énorme de produits par exemple, oubliez ça tout de suite. Cette base ne peut pas être utilisée pour ça. Elle gère sans problème des centaines/milliers d'enregistrements, mais pas des centaines de milliers ni des millions.  
- Elle peut parfaitement convenir pour par exemple un blog, un CMS (sans forum), une gallerie photo etc...  
- Elle peut aussi être pratique pour conserver des préférences graphiques d'un site par exemple...
 
Particularités - Utilisation
 
Comme il fallait produire un script le moins lourd possible, j'ai opté pour l'utilisation de tableaux + une fonction unique d'appel. Comme cela se passe-t-il concrêtement ?
 
Exemple d'une requête de création de table :
 

Code :
  1. // Création de la table
  2. $tbl_champs[0] = 'id NBR AUTO';
  3. $tbl_champs[1] = 'nom TXT NUL';
  4. $tbl_champs[2] = 'prenom TXT NUL';
  5. $tbl_champs[3] = 'numero NBR NUL';
  6. $tbl_champs[4] = 'rue TXT NUL';
  7. $tbl_champs[5] = 'code-postal NBR NUL';
  8. $tbl_champs[6] = 'ville TXT NUL';
  9. $tbl_champs[7] = 'anniversaire TS NUL';
  10. $tbl_champs[8] = 'date-inscription TS AUTO';
  11. bdd('c', 'liste-amis', $tbl_champs);


 
On utile donc un tableau qu'on envoie via la fonction bdd.
 
'c' veut dire création.
'liste-amis' est le nom de la table. (lettres permises :  a-zA-Z0-9-_)
$tbl_champs est le tableau qu'on envoie.
 
Dans les données envoyées, il faut 3 paramètres :
 
Le nom du champ (lettres permises :  a-zA-Z0-9-_), son type et sa valeur par défaut.
 
A l'heure actuelle, 3 types sont supportés :
 
NBR = nombre (virgule ou non).
TXT = texte (sans limite de longueur).
TS = TimeStamp (entier)
 
Pour la valeur par défaut :
 
- Si le champ est un nombre :
  * AUTO
  * NUL (équivaut à 0)
  * Une valeur par défaut qui est forcément un nombre.
 
- Si le champ est un texte :
  * NUL (équivaut à "" )
  * Une valeur par défaut qui est forcément une chaine de caractères entourée par "".
 
- Si le champ est un TS (Timestamp) :
  * AUTO (inscrit le Timestamp du serveur au moment de la requête).
  * NUL (= 0)
  * Une valeur par défaut (qui est forcément un timestamp).
 
 
Exemple d'une requête de destruction d'une table :
 
Très simple :  

Code :
  1. bdd('e', 'liste-amis');


 
Où 'e' signifie 'effacement' et 'liste-amis' est le nom de la table à effacer.
 
 
Exemple d'une requête d'insertion de données dans une table :
 

Code :
  1. // Insertion dans la base de données
  2. $tbl_champs[0]['nom'] = 'LOURD';
  3. $tbl_champs[0]['prenom'] = 'Daniel';
  4. $tbl_champs[0]['numero'] = '3';
  5. $tbl_champs[0]['rue'] = 'rue du Porche';
  6. $tbl_champs[0]['code-postal'] = '13000';
  7. $tbl_champs[0]['ville'] = 'Marseille';
  8. $tbl_champs[0]['anniversaire'] = mktime(0, 0, 0, 12, 1, 1970);
  9. $tbl_champs[1]['nom'] = 'BERTRAND';
  10. $tbl_champs[1]['prenom'] = 'David';
  11. $tbl_champs[1]['numero'] = '18';
  12. $tbl_champs[1]['rue'] = 'rue du 28 Mai';
  13. $tbl_champs[1]['code-postal'] = '75000';
  14. $tbl_champs[1]['ville'] = 'Paris';
  15. $tbl_champs[1]['anniversaire'] = mktime(0, 0, 0, 12, 31, 1969);
  16. $tbl_champs[2]['nom'] = 'COLOMB';
  17. $tbl_champs[2]['prenom'] = 'Christophe';
  18. $tbl_champs[2]['numero'] = '1';
  19. $tbl_champs[2]['rue'] = 'rue du Sable';
  20. $tbl_champs[2]['code-postal'] = '33000';
  21. $tbl_champs[2]['ville'] = 'Bordeaux';
  22. $tbl_champs[2]['anniversaire'] = mktime(0, 0, 0, 10, 28, 1980);
  23. $tbl_champs[3]['nom'] = 'DUCOMPTE';
  24. $tbl_champs[3]['prenom'] = 'Isabelle';
  25. $tbl_champs[3]['numero'] = '5';
  26. $tbl_champs[3]['rue'] = 'Place colombine';
  27. $tbl_champs[3]['code-postal'] = '13000';
  28. $tbl_champs[3]['ville'] = 'Marseille';
  29. $tbl_champs[3]['anniversaire'] = mktime(0, 0, 0, 10, 29, 1979);
  30. $tbl_champs[4]['nom'] = 'FLIPPER';
  31. $tbl_champs[4]['prenom'] = 'Dauphin';
  32. $tbl_champs[4]['numero'] = '1';
  33. $tbl_champs[4]['rue'] = 'rue du grand bassin';
  34. $tbl_champs[4]['code-postal'] = '13000';
  35. $tbl_champs[4]['ville'] = 'Marseille';
  36. $tbl_champs[4]['anniversaire'] = mktime(0, 0, 0, 12, 1, 1970);
  37. $tbl_champs[5]['nom'] = 'MAHLER';
  38. $tbl_champs[5]['prenom'] = 'Gustav';
  39. $tbl_champs[5]['numero'] = '6';
  40. $tbl_champs[5]['rue'] = 'rue du cimetière';
  41. $tbl_champs[5]['code-postal'] = '75000';
  42. $tbl_champs[5]['ville'] = 'Paris';
  43. $tbl_champs[5]['anniversaire'] = mktime(0, 0, 0, 8, 10, 1989);
  44. bdd('i', 'liste-amis', $tbl_champs);


 
Comme vous pouvez le constater, on utilise un tableau à deux dimensions pour une raison simple : On transmet l'ensemble des données à inscrire d'un seul coup sans écrire plusieurs fois sur le serveur.  
 
 
Exemple d'une requête de sélection des données dans une table :
 

Code :
  1. // Sélection dans la base de données
  2. // Tableau de champs sélectionnés
  3. $resultats = array();
  4. $tbl_champs[0] = "id";
  5. $tbl_champs[1] = "nom";
  6. $tbl_champs[2] = "prenom";
  7. $tbl_champs[3] = "numero";
  8. $tbl_champs[4] = "rue";
  9. $tbl_champs[5] = "code-postal";
  10. $tbl_champs[6] = "ville";
  11. $tbl_champs[7] = "anniversaire";
  12. $tbl_champs[8] = "date-inscription";
  13. // Condition(s) (Opérateurs possibles : < > <= >= == !=)
  14. $tbl_conditions = array();
  15. $tbl_conditions[0] = 'anniversaire >= '.mktime(0, 0, 0, 12, 1, 1970);
  16. $tbl_conditions[1] = 'numero > 0';
  17. // Tri(s) (Valeurs possibles : ASC ou DESC)
  18. $tbl_ordres = array();
  19. $tbl_ordres[0] = 'anniversaire ASC';
  20. $tbl_ordres[1] = 'prenom DESC';
  21. // Récupération des données
  22. $resultats = bdd('s', 'liste-amis', $tbl_champs, $tbl_conditions, $tbl_ordres, 0, 6);
  23. $i = 0;
  24. while (isset($resultats['id'][$i]))
  25. {
  26. echo $resultats['id'][$i]." | ";
  27. echo $resultats['nom'][$i]." | ";
  28. echo $resultats['prenom'][$i]." | ";
  29. echo $resultats['numero'][$i]." | ";
  30. echo $resultats['rue'][$i]." | ";
  31. echo $resultats['code-postal'][$i]." | ";
  32. echo $resultats['ville'][$i]." | ";
  33. echo date("d-M-Y", $resultats['anniversaire'][$i])." | ";
  34. echo date("d-M-Y", $resultats['date-inscription'][$i])."<br />";
  35. $i++;
  36. }


 
$tbl_champs contient l'ensemble des champs que l'on veut récupérer.
$tbl_conditions contient l'ensemble des conditions :  
syntaxe : champ opérateur (Les opérateurs supportées sont '< > <= >= == !=') valeur
- Si 0 est écrit à la place de $tbl_conditions lors de l'appel à la fonction bdd, il n'y a pas de conditions requises.
- Si le type du champ est TXT, il faut obligatoirement des "".
 
Il n'y a pas de OR ou de XOR et il n'y en aura surement pas. :o
 
$tbl_ordre contient l'ensemble des tris.
syntaxe : champ paramètre (qui peut être soit ASC soit DESC).
- Si 0 est écrit à la place de $tbl_ordre lors de l'appel à la fonction bdd, il n'y a pas de tris requis.
- Si le type du champ est TXT, il faut obligatoirement des "".
 
les deux derniers paramètres (limite1, limite2) concernent LIMIT, ces deux paramètres sont obligatoirement des entiers.
 
S'il n'y a que le premier paramètre de précisé, celui-ci veut dire : nombre d'enregistrements renvoyés en partant de l'index 0, sinon, les enregistrements de limite1 à limite2 seront renvoyés.
 
Exemple d'une destruction dans la table (DELETE)
 

Code :
  1. // Condition(s) (Opérateurs possibles : < > <= >= == !=)
  2. $tbl_conditions = array();
  3. $tbl_conditions[0] = 'prenom == "Dauphin"';
  4. bdd('d', 'liste-amis', $tbl_conditions);


 
Où 'd' signifie "destruction" ou "DELETE", 'liste-amis' est la table sur laquelle on travaille, et $tbl_conditions est l'ensemble des conditions déclenchant le DELETE des données.
 
 
Exemple d'update des données dans une table
 

Code :
  1. $tbl_champs = array();
  2. $tbl_champs['nom'] = 'HEHE';
  3. $tbl_champs['prenom'] = 'Hohoho';
  4. $tbl_champs['numero'] = '0';
  5. $tbl_champs['rue'] = 'rue du Test';
  6. $tbl_champs['code-postal'] = '33000';
  7. $tbl_champs['ville'] = 'Bordeaux';
  8. $tbl_champs['anniversaire'] = mktime(0, 0, 0, 12, 31, 1981);
  9. // Condition(s) (Opérateurs possibles : < > <= >= == !=)
  10. $tbl_conditions = array();
  11. $tbl_conditions[0] = 'nom == "HEHE"';
  12. bdd('u', 'liste-amis', $tbl_champs, $tbl_conditions);


 
Où 'u' signifie "update", 'liste-amis' est la table sur laquelle on travaille, $tbl_champs est l'ensemble des champs à modifier et $tbl_conditions est l'ensemble des conditions déclenchant le UPDATE des données.
 
Si vous voulez vous amuser à tester ou si vous êtes intéressés par ce projet, ce topic est là pour en parler.
Vous pouvez télécharger ce fichier pour tester (zip à décompresser) : http://tousleschats.free.fr/hermes/bdd.zip
 
Notes complémentaires :
 
- A l'heure actuelle, lorsque vous sélectionnez des données et que vous ne voulez pas de condition ni d'ordre, mettez 0. Vous pouvez également ne mettre que les 3 premiers paramètres (l'instruction 's', le nom de la table et les champs appelés).
- Si vous utilisez une condition ou un ordre, cela doit concerner obligatoirement un champ appelé et non simplement un champ présent dans la table. Merci donc de ne pas rapporter d'erreur à ce sujet.
- Pour utiliser ce script dans vos projet, il y a deux choses à savoir :
 
1) Chemin et inclusion :
 
Avant de faire appel à bdd(), il faut écrire :

Code :
  1. define("ADR", "../" );
  2. include(ADR."bdd/fonctions-bdd.php" );


 
Où ADR est une constante représentant le chemin du script de base de données.
 
2) Pour gérer les permissions, c'est très simple : Editez fonctions-bdd.php et à la ligne 7, vous avez la constante DROITS_BDD qui vous le permet (valeur standard octale). Par défaut, puisque qu'il sagit de tester, j'ai mis 777, mais il est évident que dans le cas d'une utilisation de ce script sur internet, il ne faut pas conserver cette valeur.
 
 
Voilà...  :o


Message édité par Hermes le Messager le 22-06-2006 à 10:15:34
Reply

Marsh Posté le 16-06-2006 à 13:01:16   

Reply

Marsh Posté le 16-06-2006 à 13:01:38    

Performances :
 
Comme on peut s'y attendre, les performances d'une base de données entièrement en PHP sont faibles étant donné que PHP est interprêté. :o
 
La base est parfaite pour des tables d'une 100aine d'enregistrements.
 
On a :
 
Pour l'insertion des données  (100 enregistrements d'un coup) : 0.066 secondes.
Pour la sélection des données (100 enregistrements sans conditions ni tri) : 0.02 secondes.
Pour la sélection des données (100 enregistrements sans conditions avec 1 ou plusieurs tris : 0.02 secondes (aucune différence notable)
Pour la sélection des données (100 enregistrements avec  1 conditions) : 0.03
Pour chaque nouvelle condition : 0.005 secondes suplémentaires.
La clause limite : Pas de changement notable.
 


Message édité par Hermes le Messager le 22-06-2006 à 10:25:38
Reply

Marsh Posté le 16-06-2006 à 13:01:48    

Réservé

Reply

Marsh Posté le 16-06-2006 à 13:38:49    

Eeeeeet ben ! T'as du t'amuser ! Un grand bravo, car ça à l'air simple et efficace ! Chapeau bas.


Message édité par Glock21 le 16-06-2006 à 13:38:59

---------------
Je donne souvent l'air d'être ailleurs, mais en faite, je ne suis nulle part...
Reply

Marsh Posté le 16-06-2006 à 13:56:55    

Note : Sachez qu'il est possible de faire le même script, mais PHP5 only et dans ce cas, on aurait des perfs bien meilleures, en particulier grace aux nouvelles instructions sur les tableaux comme array_intersect_keys (qui n'existe pas en PHP4) et qui permettent donc d'éviter pratiquement tout recours aux boucles.
 
Quand cette version PHP >= 4 sera terminée, je ferais sans doute une adaptation PHP >= 5.
 
J'ai volontairement exclu les recours à XML et cie pour des raisons de compatibilité. J'utilise que des trucs présents à 100% dans PHP, qui ne nécessitent aucun module supplémentaire.

Reply

Marsh Posté le 16-06-2006 à 14:00:44    

Hermes le Messager a écrit :


Quand cette version PHP >= 4 sera terminée, je ferais sans doute une adaptation PHP >= 5.


SQLite ?


---------------
my flick r - Just Tab it !
Reply

Marsh Posté le 16-06-2006 à 14:04:03    


 
Et ? SQlite est un module, n'est pas présent partout etc... etc...  :o  

Reply

Marsh Posté le 16-06-2006 à 14:06:46    

Hermes le Messager a écrit :

Et ? SQlite est un module, n'est pas présent partout etc... etc...  :o


 
Je rectifie :  
 
Dans la version 5 de PHP, l'extension SQLite ainsi que le moteur sont intégrés et compilés par défaut.  
 
 :jap:  :jap:  

Reply

Marsh Posté le 16-06-2006 à 14:11:57    

Par contre, il restera toujours le problème de l'embarquement de la BDD dans les sites avec SQLite alors qu'avec mon script, tout est embarqué. [:spamafote]

Reply

Marsh Posté le 16-06-2006 à 14:16:05    

Hermes le Messager a écrit :

Par contre, il restera toujours le problème de l'embarquement de la BDD dans les sites avec SQLite alors qu'avec mon script, tout est embarqué. [:spamafote]


La base de donnees en SQLIte est un fichier, donc tu la mets dans un ptit repertoire de ton site et voila


---------------
my flick r - Just Tab it !
Reply

Marsh Posté le 16-06-2006 à 14:16:05   

Reply

Marsh Posté le 16-06-2006 à 14:20:55    

zapan666 a écrit :

La base de donnees en SQLIte est un fichier, donc tu la mets dans un ptit repertoire de ton site et voila


 
Faudra que je regarde ça d'un peu plus près.  :jap:  
 
Si SQLite est présent partout à partir de PHP >= 5, que sa config est indentique partout et qu'on peut choisir sans problème l'emplacement du fichier (je parle en particulier des hébergements mutualisés), alors effectivement, mon script n'a plus d'intérêt pour PHP >= 5.  :D  (Il conserve toutefois un intérêt : celui de se casser le cul à réinventer la roue et de faire des progrès en prog)


Message édité par Hermes le Messager le 16-06-2006 à 14:22:26
Reply

Marsh Posté le 20-06-2006 à 19:54:30    

Ajout de LIMIT de ma chtite BDD.
 
J'ai aussi corrigé pleins de bugs, utilisé de nouvelles fonctions concernant les tableaux, je vide les variables au fur et à mesure avec unset() et j'utilise que des for et des switch.

Reply

Marsh Posté le 20-06-2006 à 20:02:56    

Si j'ai bien compris, ton script gère l'auto-incrémente, ça lui donne un avantage sur SQLite.
Par contre, sans Update, c'est short, autant le Delete on peut s'en passer, autant l'Update... :/

Reply

Marsh Posté le 20-06-2006 à 20:06:38    

The-Shadow a écrit :

Si j'ai bien compris, ton script gère l'auto-incrémente, ça lui donne un avantage sur SQLite.
Par contre, sans Update, c'est short, autant le Delete on peut s'en passer, autant l'Update... :/


 
ça vient, ça vient, C'est bcp plus facile que le select que je viens de terminer.
 
Ya rien d'autre que du WHERE ;) Après, un simple str_replace et c'est bon [:spamafote]
 
J'aurais fini ce soir tard ou demain si tout va bien.
 
Après viendra la correction des bugs qui ne manqueront pas d'arriver vu la complexité de la chose. :/

Reply

Marsh Posté le 20-06-2006 à 20:08:30    

Sinon oui, l'auto-incrémente est géré effectivement. [:spamafote]

Reply

Marsh Posté le 21-06-2006 à 12:14:11    

DELETE marche, plus qu'à terminer UPDATE et c'est fini. Avant ce soir si tout va bien. :o

Reply

Marsh Posté le 21-06-2006 à 18:35:12    

Ayé, j'ai fini, UPDATE marche aussi.
 
Je vais pouvoir commencer les tests et les optimisations. :D :D
 
En tous cas, je vois que ça passionne les foules... [:toto le hros]

Reply

Marsh Posté le 21-06-2006 à 18:44:29    

J'suis un peu con, j'avais oublié le lien pour la télécharger. :/
 
http://tousleschats.free.fr/hermes/bdd.zip


Message édité par Hermes le Messager le 21-06-2006 à 18:44:51
Reply

Marsh Posté le 21-06-2006 à 19:20:00    

The-Shadow a écrit :

Si j'ai bien compris, ton script gère l'auto-incrémente, ça lui donne un avantage sur SQLite.


SQLite gère l'autoincrement [:spamafote]  
(depuis la version 3.1.0 sur les INTEGER PRIMARY KEY, càd Janvier 2005, après si les drivers PHP ne gère que SQLite2 et pas SQLite3...)


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 21-06-2006 à 19:28:20    

masklinn a écrit :

SQLite gère l'autoincrement [:spamafote]  
(depuis la version 3.1.0 sur les INTEGER PRIMARY KEY, càd Janvier 2005, après si les drivers PHP ne gère que SQLite2 et pas SQLite3...)


Bah en fait, à l'époque où j'avais testé SQLite, ça ne le gérait pas, du coup j'ai laissé tombé, spa d'ma faute si des trucs dont je n'ai plus rien à foutre évoluent. :o

Reply

Marsh Posté le 21-06-2006 à 19:39:26    

The-Shadow a écrit :

Bah en fait, à l'époque où j'avais testé SQLite, ça ne le gérait pas, du coup j'ai laissé tombé, spa d'ma faute si des trucs dont je n'ai plus rien à foutre évoluent. :o


Ouais bein maintenant il gère alors stop the fud :o :o :o :o :o :o :o :o :o


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 22-06-2006 à 09:25:04    

J'ai optimisé mon script. [:dawa]
 
J'ai plus que 1650 lignes au lieu de 2200 [:dawa]

Reply

Marsh Posté le 22-06-2006 à 10:26:37    

Performances :
 
Comme on peut s'y attendre, les performances d'une base de données entièrement en PHP sont faibles étant donné que PHP est interprêté. :o
 
La base est parfaite pour des tables d'une 100aine d'enregistrements.
 
On a :
 
Pour l'insertion des données  (100 enregistrements d'un coup) : 0.066 secondes.
Pour la sélection des données (100 enregistrements sans conditions ni tri) : 0.02 secondes.
Pour la sélection des données (100 enregistrements sans conditions avec 1 ou plusieurs tris : 0.02 secondes (aucune différence notable)
Pour la sélection des données (100 enregistrements avec  1 conditions) : 0.03
Pour chaque nouvelle condition : 0.005 secondes suplémentaires.
La clause limite : Pas de changement notable.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed