Datasource : abstraction de données

Soyez le premier à donner votre avis sur cette source.

Snippet vu 13 417 fois - Téléchargée 25 fois

Contenu du snippet

Voici 4 classes php5 écrites dans le but d'utiliser indépendemment de son programme une source de données(fichier ou bdd).
Pour utiliser un fichier xml on fait créer à la Datasource l'objet simplexml et pour une bdd : le provider correspondant
La source de donnée ici est très simplifiée :une classe abstraite décrivant la source de donnée et 3 classes filles implémentant cette même source.
Pour exemple une classe XML , une classe Mysql, une classe Sqlite sont dérivées de Datasource.
Bon le code est toujours extensible (j'ai récupéré quelques codes à doite, à gauche) d'ailleurs surtout à gauche :), j'aime pas trop le bleu.
Rassurez - vous, rien de sous entendu!

Source / Exemple :


<!--
Fichier XML test3.xml
-->
<?xml version="1.0" ?> 
<a>
 <b>
  <c id="test" >text</c>
  <c id="test2" name="oups" >stuff</c>
 </b>
 <d>
  <c>code</c>
 </d>
</a>
<!--
Fin Fichier XML test3.xml
-->
<?php
/**

  • Classe ERROR
  • Description:
  • Gestion des erreurs
  • /
class ERROR { const ERROR_OFF=0; const ERROR_DISPLAY=1; const ERROR_LOGFILE=2; const NOTICE=0; const WARNING=1; const FATAL=2; const IGNORE=3; public static $LOGFILE='log/logfile.log'; protected static $mode=self::ERROR_DISPLAY; public static function set($mode) { self::$mode = $mode; } /**
  • Process statique de getion d'erreurs
  • dependant du mode ->
  • display : affichage
  • logfile : enregistrement des erreurs dans le fichier logfile
  • off : erreurs gérées par php uniquement
  • /
public static function procError ($type,$class,$msg) { if (self::$mode === self::ERROR_DISPLAY) { switch($type) { case self::FATAL: throw new Exception ('<br/><strong> ERREUR Fatale : '.$class.' - '.$msg.'<br/><br/></strong>'); break; case self::IGNORE: break; case self::WARNING: echo '<br/><strong>WARNING : '.$class.' - '.$msg.'.<br/><br/></strong>'; break; case self::NOTICE: echo '<br/><strong>NOTICE: '.$class.' - '.$msg.'.<br/><br/></strong>'; break; default: throw new Exception ('<strong>ERR: type d\'erreur innatendu : '.$type.' - '.$class.' - '.$msg.'</strong>'); } } else if (self::$mode === self::ERROR_OFF) { //Todo } else if (self::$mode === self::ERROR_LOGFILE) { if (file_exists(self::$LOGFILE)&&is_writeable(self::$LOGFILE)) { $fp = fopen (self::$LOGFILE,'a'); if (flock($fp, LOCK_EX)) { switch($type) { case self::FATAL: fputs($fp,date('d/m/Y H:i:s').' : ERREUR Fatale : '.$class.' - '.$msg."\n"); flock($fp, LOCK_UN); fclose($fp); throw new Exception ('ERREUR Fatale : '.$class.' - '.$msg); break; case self::IGNORE: break; case self::WARNING: fputs($fp,date('d/m/Y H:i:s').' :WARNING : '.$class.' - '.$msg."\n"); break; case self::NOTICE: fputs($fp,date('d/m/Y H:i:s').' :NOTICE: '.$class.' - '.$msg."\n"); break; default: fputs($fp,date('d/m/Y H:i:s').' :ERREUR Innattendue : '.$class.' - '.$msg."\n"); flock($fp, LOCK_UN); fclose($fp); throw new Exception ('ERREUR Innattendue : '.$class.' - '.$msg); } flock($fp, LOCK_UN); } else throw new Exception('ERR: Le fichier log '.self::$LOGFILE.' est vérrouilé en écriture'); fclose($fp); } else throw new Exception('ERR: Problème rencontré los de la création du fichier '.self::$LOGFILE); } } } /**
  • CDataSource
  • Description : Intéraction avec plusieurs sources de données différentes
  • comme une base de données, un fichier xml, ou autre
  • emploi :CDataSource::add(type,arg1,argn)
  • argn sont les arguments requis pour le constructeur de classe type.
  • /
abstract class CDataSource { /** history of succeeded query
  • /
public $history; /** history of error query
  • /
public $errHistory; protected $errQuery_id=-1; /** id de requete
  • /
protected $query_id=-1; /**
  • tableau contenant les paramètres de connexion
  • /
protected $_aConfig=null; /**
  • flag property
  • /
protected $_bConnected=false; /**
  • ressource
  • /
public $_ressource=null; /**
  • flag bench
  • /
protected $_BENCH = false; /**
  • constructeur
  • /
protected function __construct() { } /**
  • membre abstrait
  • /
abstract protected function checkConfiguration(); /**
  • membre abstrait
  • /
abstract public function query($queryString, $desc=NULL); /**
  • membre abstrait
  • /
abstract public function fetch_assoc(); /**
  • membre abstrait
  • /
abstract public function free(); /**
  • membre abstrait
  • /
abstract public function num_rows(); /** membre abstrait
  • /
abstract public function insert_id(); /** membre abstrait
  • /
abstract public function error(); /**
  • Methode add :
  • Description : instancie un objet de class sourceType
  • ses arguments sont variables selon le type construit
  • args: nombre arguments variables.
  • add(familyClass,argumentConstructeur1,argumentConstructeur2,...,argumentConstructeurN)
  • ex:CDataSource::add(CMysql,'localhost','user','pwd','dbname');
  • /
public function add($sourceType) { if (class_exists($sourceType)) { if (is_subclass_of($sourceType,__CLASS__)) { if(($n=func_num_args())>1) { $args=func_get_args(); $s='$args[1]'; for($i=2;$i<$n;++$i) $s.=",\$args[$i]"; eval("\$component=new $sourceType($s);"); $component->connect(); return $component; } else return new $sourceType; } else throw new Exception ('Impossible d\instancier la classe '.$sourceType); } else throw new Exception ('La classe '.$sourceType.' est inexistante'); } /**
  • A implémenter
  • /
public function init() { } /**
  • A implémenter
  • /
protected function connect() { } /**
  • La connexion à la source a-t'elle lieu?
  • /
public function isConnected() { if ( $this->_bConnected ) return true; return false; } public function setBench($value) { if (is_bool($value)) { $this->_BENCH = $value; } else ERROR::procError(ERROR::WARNING,get_class(),'::'.__FUNCTION__.': type bool attendu <br/>'); } } /**
  • CSimpleXml
  • Description :
  • Source de données de type fichier xml
  • /
class CSimpleXml extends CDataSource { public $result=null; private $arTmp=null; /**
  • Constructeur
  • /
protected function __construct ($fileName) { $this->_aConfig['FILENAME'] = $fileName; $this->_bConnected=false; } /** Vérifie et retourne si les noeuds xml existent, l'element SimpleXML correspondant
  • /
public function __get($prop) { //echo $prop.'</br>'; if (property_exists($this->_ressource,$prop)) return $this->_ressource->$prop; else throw new Exception(get_class($this->_ressource).' : Paramètre Invalide: '.$prop); } /**
  • Vérifiaction de la configuration
  • /
protected function checkConfiguration() { if (is_array ($this->_aConfig)) { if (isset($this->_aConfig['FILENAME'])) $tmp = $this->_aConfig['FILENAME']; else $tmp=''; if (!is_file($tmp)) return false; if ( strtolower ( array_pop( explode( '.',$tmp) ) ) != 'xml' ) return false; return true; } return false; } /**
  • Vérification de la configuration + parsing + connexion
  • /
protected function connect() { if ( $this->checkConfiguration() ) { $resParser = xml_parser_create(); if (xml_parse($resParser,file_get_contents($this->_aConfig['FILENAME']))) { $this->_ressource = simplexml_load_file($this->_aConfig['FILENAME']); } else { $errorStr = xml_error_string( xml_get_error_code($resParser)).' at LINE '.xml_get_current_line_number ($resParser); ERROR::procError( ERROR::FATAL, get_class(),'::'.__FUNCTION__.':'. $this->_aConfig['FILENAME'].': Fichier xml non valide: '.$errorStr); } xml_parser_free($resParser); } else ERROR::procError( ERROR::FATAL, get_class(),'::'.__FUNCTION__.':Erreur de configuration de l\'objet de type: '.__CLASS__); $this->_bConnected = true; } /**
  • Requête générique
  • /
public function query($queryString, $desc=NULL,$error_level=ERROR::WARNING) { unset($this->arTmp); $this->arTmp=null; if ($this->_BENCH) $start = microtime (true); $this->result = $this->_ressource->xpath($queryString); if ($this->_BENCH) $query_time = microtime (true) - $start; else $query_time =null; if ($this->result) { $this->history[++$this->query_id] = array('desc' => $desc, 'query' => $queryString, 'time' => $query_time); return $this->result; } else { ERROR::procError($error_level,get_class(),'::'.__FUNCTION__.': Xpath Error in '.$queryString.' at line '.__LINE__ ); if (count($this->history)>0) $this->result = $this->_ressource->xpath ($this->history[$this->query_id]['query']); $this->errHistory[++$this->errQuery_id] = array('desc' => $desc, 'query' => $queryString, 'time' => $query_time, 'queryPos'=>$this->query_id+1); return false; } } /**
  • Retourne ligne par ligne le resultat de la requête sous forme de tableau
  • associatif
  • /
public function fetch_assoc() { if(is_null($this->arTmp)) $this->fetch_assoc_ar(); if (current($this->arTmp)) { $arr = current ($this->arTmp) ; next ($this->arTmp); return $arr; } return null; } /**
  • /
public function num_rows() { return count($this->arTmp); } /** A implémenter dans le cadre de SimpleXML
  • /
public function error() { return; } /**
  • /
public function insert_id() { return null; } /** construit le tableau temporaire à dispo de fecth_assoc
  • /
private function fetch_assoc_ar() { $i=0; //unset($this->arTmp); //$this->arTmp=null; if (!$this->result) ERROR::procError(ERROR::FATAL,get_class(),'::'.__FUNCTION__.': Aucune requête n\'a été définie <br/>'); if ($this->query_id > -1) { $node=explode('/',$this->history[$this->query_id]['query']); if (isset($node[0])&&empty($node[0])) { array_shift($node); array_shift($node); } //print_r($node); $newnode=$this; foreach ($node as $prop) { $newnode=$newnode->$prop; } $aVal=array(); foreach ($newnode as $key=>$val) { foreach ( $val->attributes() as $attr=>$value ) { $idx=(string)$attr; $aVal[$i][$idx]=(string)$value; } $aVal[$i]['TagValue']=(string)$val; $i++; } $this->arTmp = $aVal; } else ERROR::procError(ERROR::WARNING,get_class(),'::'.__FUNCTION__.': Aucune requête n\'a été définie <br/>'); return NULL; } /**
  • libére la resource resultat
  • /
public function free() { unset ($this->result); } /**
  • clot la connexion
  • /
public function close(){ unset ($this->_ressource); $this->_bConnected=false; } /**
  • recharge la classee à partir de la dernière configuration
  • /
public function reload(){ $this->connect(); } } /**
  • CMysql
  • Description: La Source de données est une base Mysql
  • /
class CMysql extends CDataSource { protected $result; protected $db; /**
  • Vérification de la configuration
  • /
protected function checkConfiguration() { if (!isset($this->_aConfig['HOSTNAME'])) return false; if(!isset($this->_aConfig['USER'])) return false; if(!isset($this->_aConfig['PASS'])) return false; if (!isset($this->_aConfig['DB'])) return false; return true; } /**
  • Constructeur
  • /
protected function __construct ($hostname='localhost',$user,$pass,$db) { $this->_aConfig['HOSTNAME'] = $hostname; $this->_aConfig['USER']=$user; $this->_aConfig['PASS']=$pass; $this->_aConfig['DB']=$db; $this->_bConnected=false; } /**
  • requête générique
  • /
public function query($queryString, $desc=NULL,$error_level=ERROR::WARNING) { if ($this->_BENCH) $start = microtime (true); $this->result = @mysql_query ($queryString, $this->_ressource ); if ($this->_BENCH) $query_time = microtime (true) - $start; else $query_time=null; if ($this->result) { $this->history[++$this->query_id] = array('desc' => $desc, 'query' => $queryString, 'time' => $query_time); return $this->result; } else { ERROR::procError($error_level,get_class(),'::'.__FUNCTION__.': '.mysql_error().' in '.$queryString.' at line '.__LINE__ ); if (count($this->history)>0) $this->result = @mysql_query ($this->history[$this->query_id]['query'], $this->_ressource ); $this->errHistory[++$this->errQuery_id] = array('desc' => $desc, 'query' => $queryString, 'time' => $query_time, 'queryPos'=>$this->query_id+1); return false; } } /**
  • verification de la configuration + connexion
  • /
protected function connect() { if ( !$this->checkConfiguration() ) { ERROR::procError(ERROR::FATAL,get_class(),''.__FUNCTION__.':Problème de configuration de connexion détecté.'); } $this->_ressource = @mysql_connect($this->_aConfig['HOSTNAME'], $this->_aConfig['USER'], $this->_aConfig['PASS']); if (!$this->_ressource ) { ERROR::procError(ERROR::FATAL,get_class(),'::'.__FUNCTION__.':Erreur lors de la connection vers : '.$this->_aConfig['HOSTNAME'].' Veuillez vérifier les paramètres utilisés pour votre connexion.'); } $this->db=@mysql_select_db($this->_aConfig['DB'], $this->_ressource); if (!$this->db ) { ERROR::procError(ERROR::FATAL,get_class(),'::'.__FUNCTION__.':Erreur lors de l\'ouverture de la base de donnée : '.$this->_aConfig['DB'].'.Veuillez vérifier l\'existence de la base.'); unset($this->_aConfig); } $this->_bConnected=true; } /**
  • retourne le resultat de la requête sous forme de tableau
  • associatif
  • /
public function fetch_assoc($result=null) { if ($result) { return mysql_fetch_assoc ($result); } if (preg_match('/\b(?i)select/s',$this->history[$this->query_id]['query'])) { if ($this->result) { return mysql_fetch_assoc ($this->result); } } else ERROR::procError(ERROR::WARNING,get_class(),''.__FUNCTION__.': fonction incompatible avec la ressource utilisée'); } /** retourne le nombre de lignes d'une requête
  • /
public function num_rows($result=null) { if ($result) return mysql_num_rows($result); if ($this->result) { if (preg_match('/\b(?i)select/s',$this->history[$this->query_id]['query'])) return mysql_num_rows($this->result); else ERROR::procError(ERROR::WARNING,get_class(),'::'.__FUNCTION__.': fonction incompatible avec la ressource utilisée'); } } /**
  • /
public function insert_id() { return mysql_insert_id($this->_ressource); } /**
  • /
public function error() { return mysql_error(); } /**
  • libére la resource resultat
  • /
public function free($result=null) { if ($result) { @mysql_free_result($result)or ERROR::procError(ERROR::WARNING,get_class(),'::'.__FUNCTION__.': problème durant la libération des ressources'); } else { if (preg_match('/\b(?i)select/s',$this->history[$this->query_id]['query'])) { $free = @mysql_free_result($this->result); if (!$free) ERROR::procError(ERROR::WARNING,get_class(),'::'.__FUNCTION__.': problème durant la libération des ressources'); } else ERROR::procError(ERROR::WARNING,get_class(),'::'.__FUNCTION__.': fonction incompatible avec la ressource utilisée'); } } } class CSqlite extends CDataSource { /**
  • Constructeur
  • /
protected function __construct ($dbfilename='db_xxx',$mode=0666) { $this->_aConfig['DBFILENAME'] = $dbfilename; $this->_aConfig['MODE']=$mode; $this->_aConfig['SQLITEERROR']=null; $this->_bConnected=false; } protected function checkConfiguration() { if (!isset($this->_aConfig['DBFILENAME'])) return false; if(!isset($this->_aConfig['MODE'])) return false; return true; } protected function connect() { if ( !$this->checkConfiguration() ) { ERROR::procError(ERROR::FATAL,get_class(),''.__FUNCTION__.':Problème de configuration de connexion détecté.'); } $this->_ressource = @sqlite_open($this->_aConfig['DBFILENAME'], $this->_aConfig['MODE'], $this->_aConfig['SQLITEERROR']); if (!$this->_ressource ) { ERROR::procError(ERROR::FATAL,get_class(),'::'.__FUNCTION__.':Erreur lors de la connection : '.$sqliteError.'.'); } $this->_bConnected=true; } /**
  • requête générique
  • /
public function query($queryString, $desc=NULL,$error_level=ERROR::WARNING) { if ($this->_BENCH) $start = microtime (true); $this->result = @sqlite_query ( $this->_ressource,$queryString ); if ($this->_BENCH) $query_time = microtime (true) - $start; else $query_time=null; if ($this->result) { $this->history[++$this->query_id] = array('desc' => $desc, 'query' => $queryString, 'time' => $query_time); return $this->result; } else { ERROR::procError($error_level,get_class(),'::'.__FUNCTION__.': '.$this->error().' in '.$queryString.' at line '.__LINE__ ); if (count($this->history)>0) $this->result = @sqlite_query ($this->_ressource, $this->history[$this->query_id]['query']); // Historisatoin des erreurs $this->errHistory[++$this->errQuery_id] = array('desc' => $desc, 'query' => $queryString, 'time' => $query_time, 'queryPos'=> $this->query_id+1); return false; } } /**
  • retourne le resultat de la requête sous forme de tableau
  • associatif
  • /
public function fetch_assoc($result=null) { if ($result) { return sqlite_fetch_array ($result,SQLITE_ASSOC); } if (preg_match('/\b(?i)select/s',$this->history[$this->query_id]['query'])) { if ($this->result) { return sqlite_fetch_array ($this->result,SQLITE_ASSOC); } } else ERROR::procError(ERROR::WARNING,get_class(),''.__FUNCTION__.': fonction incompatible avec la ressource utilisée'); } /**
  • /
public function insert_id() { return sqlite_last_insert_rowid($this->_ressource); } /** retourne le nombre de lignes d'une requête
  • /
public function num_rows($result=null) { if ($result) return sqlite_num_rows($result); if ($this->result) { if (preg_match('/\b(?i)select/s',$this->history[$this->query_id]['query'])) return sqlite_num_rows($this->result); else ERROR::procError(ERROR::WARNING,get_class(),'::'.__FUNCTION__.': fonction incompatible avec la ressource utilisée'); } else ERROR::procError(ERROR::WARNING,get_class(),'::'.__FUNCTION__.': fonction incompatible avec la ressource utilisée'); } /**
  • libére la resource resultat
  • /
public function free() { unset ($this->result); } /**
  • clot la connexion
  • /
public function close(){ sqlite_close($this->_ressource); $this->_bConnected=false; } /**
  • recharge la classee à partir de la dernière configuration
  • /
public function reload(){ $this->connect(); } /**
  • /
public function error() { $errCode = sqlite_last_error($this->_ressource); return 'SQLITE - '.$errCode.':'.sqlite_error_string($errCode); } } try { /** Exemple d'utilisation de la classe CSimpleXml
  • /
echo '<br/><strong>EXEMPLE OBJET SIMPLEXML: </strong>'; //bench à true pour toutes les classes filles $oxml=CDataSource::add('CSimpleXml','test3.xml'); $oxml->setBench(true); $oxml->query('b/c','xpath'); $i=0; /** Même comportement qu'une requête fetch_assoc
  • /
while ($node=$oxml->fetch_assoc()) { $row[$i]=$node; $i++; } //erreur de requête $oxml->query('b/cd','xpath'); /** Affichage du tableau généré par fetch_assoc
  • /
echo '<br/> AFFICHAGE DU FETCH ALL POUR RESSOURCE:<br/>'; print_r ($row); /** Affichage du tableau historisation
  • /
print_r($oxml->history); echo '<br/>REQUETES OK : '; print_r($oxml->history); echo '<br/>REQUETES EN ERREUR : '; print_r($oxml->errHistory); $oxml->free(); $oxml->close(); if ($oxml->isConnected()) echo '<br/>oxml connecté'; else echo '<br/>oxml non connecté'; $oxml->reload(); if ($oxml->isConnected()) echo '<br/>oxml connecté'; else echo '<br/>oxml non connecté'; /** Exemple avec une source de données Mysql
  • /
echo '<br/><strong>EXEMPLE OBJET MYSQL: </strong>'; $oMysql = CDataSource::add('CMysql','localhost','changeusr','changepwd','param'); $oMysql->setBench(true); $oMysql->query('SELECT * from param'); $i=0; while ($row = $oMysql->fetch_assoc()) { $tab[$i]=$row; $i++; } $oMysql->free(); $oMysql->query('insert into param (pkey,pval) values (\'key6\',\'val4\')'); echo '<br/>AFFICHAGE DU FETCH ALL POUR RESSOURCE:<br/>'; print_r($tab); echo '<br/>REQUETES OK : '; print_r($oMysql->history); echo '<br/>REQUETES EN ERREUR : '; print_r($oMysql->errHistory); $oMysql->free(); /** Exemple avec une source de données sqlite
  • /
echo '<br/><strong>EXEMPLE OBJET SQLITE: </strong>'; $oDbsqlite = CDataSource::add('CSqlite','db_test', 0666); $oDbsqlite->setBench(true); $oDbsqlite->query('CREATE TABLE user ( ID_user BIGINT NOT NULL PRIMARY KEY DEFAULT \'0\', login VARCHAR(10), password VARCHAR(10))'); $oDbsqlite->query('INSERT INTO user (ID_user,login,password) VALUES (1,\'user_test\',\'pass\')'); $oDbsqlite->query('SELECT * FROM user'); $i=0; while ($row=$oDbsqlite->fetch_assoc()) { $rows[$i]=$row; $i++; } /** Autre exemple de requête au passage et pour la forme : une des dates les plus importantes de l'année ;)
  • /
$oDbsqlite->query('SELECT date( \'now\', \'start of year\', \'+10 months\', \'+14 days\', \'weekday 4\') as datebojo'); if ($row=$oDbsqlite->fetch_assoc()) { echo 'le beaujo arrive le: '.$row['datebojo'].'<br/>'; } $oDbsqlite->free(); $oDbsqlite->close(); echo '<br/> AFFICHAGE DU FETCH ALL POUR RESSOURCE:<br/>'; print_r($rows); echo '<br/>REQUETES OK : '; print_r($oDbsqlite->history); echo '<br/>REQUETES EN ERREUR : '; print_r($oDbsqlite->errHistory); } catch(Exception $excep) { echo $excep->getMessage(); } ?>

Conclusion :


Merci de signaler d'éventuels bugs.
Pour exécuter ce script il est nécessaire de paramètrer les extensions pdo,sqlite,mysql et simpleXML dans php.ini.
sinon les parties d'appel aux extensions non chargées sont à mettre en commentaires ou à supprimer

A voir également

Ajouter un commentaire

Commentaires

guill76
Messages postés
193
Date d'inscription
mercredi 24 août 2005
Statut
Membre
Dernière intervention
3 juin 2016
-
Salut,
Pour le pear je ne l'ai jamais utilisé mais pour appuyer ce que dit malalam, je viens de me faire (aujourd'hui) une petite adaptation d'un de mes codes (un editeur de tag mp3) au framework prado que je suis en train de décortiquer. Eh bien pour produire une simple datagrid (c'est à dire une simple grille html liée à un simple tableau php alimenté lui même par une source de données, dans mon cas, un répertoire de fichiers) tu dois instancier un nombre incalculable de classes ascendantes (certes c'est automatique mais ..):
D'abord le composant application qui appelle un gestionnaire de service qui appelle le gestionnaire de template puis le gestionnaire de composants applictifs puis tous ses composants 1 à 1, du validateur jusqu'à la datagrid en passant par des composans intermédiaires (parseurs de texte avec reg exp,parseur xml,editeur de code html,composants html simples et complexes, editeur de scripts clients,etc.. ): ça prend 10 fois plus de temps à charger que de charger ces propres classes (qui sont en plus tout aussi réutilisables)
Un framework comme prado est gigantesque mais son exploitation demande un serveur ultra performant pour optimiser les requêtes utilisateurs. Il reste donc reservé à une prog industrielle et ne peut se développer qu'avec du matériel puissant: Mon PC, lui, malheureusement, il fait la différence.
Dans l'absolu tu as peut être raison mais pour bien comprendre les choses il faut à mon avis savoir à tout prix comment, toi, tu peux ou tu pourrais les développer.
malalam
Messages postés
10843
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17 -
Hello,

je vais te répondre : je suis développeur web professionnel. Pour ma part, j'utilise, au contraire, le moins possible de packages pear ou autres, déjà tout fait. Et la raison est simple : je préfère passer un peu plus de temps au départ, et beaucoup moins au fil du temps. Quand on développe soi-même ses packages, on les dimensionne selon nos besoins, déjà, plutôt que de se trimballer un package énorme, que l'on utilise qu'à 10%. De plus, quand on a des modifications, des évolutions à apporter, c'est bien plus rapide quand pon doit les apporter sur un code que l'on a développé soi-même : on ne doit pas se taper tout le package pour essayer de comprendre comment il fonctionne, pour pouvoir y ajouter ce qui nous manque. On a un contrôle total, en clair. Et c'est important...tant au niveau des évolutions, que de l'optimisation et de la sécurité.
toutphp
Messages postés
107
Date d'inscription
lundi 24 mai 2004
Statut
Membre
Dernière intervention
5 mai 2010
-
Une petite question avec et sans rapport ton code :-) :

Pourquoi veux-tu réinventer ce qui existe déjà. Regarde PEAR et ses différents modules, ils correspondent à ce que tu fais et le tout est Open Source.

Mais ceci dit je serais pas encore capable de faire ce que tu fais donc ce n'est pas du tout une attaque personnel mais plutôt une interrogation que j'ai depuis longtemps .Je suis développeur et ma devise est : en faire le moins possible si ça existe à coté et que c'est bien fait.

En tout cas beau travail quand même !
guill76
Messages postés
193
Date d'inscription
mercredi 24 août 2005
Statut
Membre
Dernière intervention
3 juin 2016
-
euh non en fait quelle c.., j'ai pas réalisé : dériver la classe exception de php5 n'aurait pas eu le même effet, mais plutot faire une autre classe d'erreur non statique oui.
guill76
Messages postés
193
Date d'inscription
mercredi 24 août 2005
Statut
Membre
Dernière intervention
3 juin 2016
-
Merci.
Pour la classe d'erreur, oui j'aurais peut être pu dériver la classe exception de php5 , mais bon l'idée de faire une classe statique m'est venue sans trop réfléchir. Y'a -il réellement des inconvénients à employer cette méthode? je ne sais pas.
Sinon en relisant j'ai vu 2 petites c...... dans mon code, je corrige.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.