Tags
- adapter
- afup
- agile
- ajax
- annotation
- ant
- api
- application
- apt
- array
- arrayaccess
- audit
- autoload
- base de données
- batch
- bonnes pratiques
- bouchon
- bug
- build
- build.xml
- cache
- certification
- classe
- client
- code
- code mort
- config
- configuration
- conférence
- contexte
- convention
- cruisecontrol
- dependance
- dépendance
- déploiement
- développeur
- eclipse
- eclipse pdt
- enrichissement
- entreprise
- entretien
- environnement
- equipe
- exception
- factory
- forum
- framework
- greenpepper
- gtk
- hudson
- i18n
- ihm
- import
- include
- include_path
- inclusion
- ini
- integration
- intégration continue
- java
- javascript
- lighttpd
- maintenabilité
- mock
- mysql
- ménage
- métrique
- métriques
- openxml
- optimisation
- outils
- package
- pattern
- pear
- phing
- php
- phpundercontrol
- phpunit
- planning
- plateforme
- projet
- proxy
- refactoring
- regexp
- require
- roadmap
- robustesse
- service
- session
- simpletest
- spl
- subversion
- symfony
- syntaxe
- test
- test unitaire
- tests
- tests d intégration
- transaction
- ubuntu
- usi
- webservices
- xml
- zend framework
- zend studio
- zend_pdf
- zip
Commentaires récents
Tres bien presente! :)
Juste une remarque :
"$adapter = new CsvAdapter;
$adapter->setFile('villes.csv');"
-> Visiblement la methode setFile a ete oubliee dans l'implementation de l'adapter.
De la meme maniere j'ajouterais une methode setTable() a la classe DatabaseAdapter, ca rendrait ces 2 adapters encore plus versatiles!
En tout cas merci pour le post!
Ah oui je confirme, ne jamais utiliser Exception car PHPUnit lui même les attrape.
De manière générale utiliser Exception n'est pas correct de toute manière ;-)
$this->setExpectedException('MonException'); est aussi possible depuis un test.
Hello, merci pour cet article.
Une petite alternative : personnellement je met un nom de domaine comme nom de sections pour mes fichiers .ini de configuration.
Coté applicatif je detecte le domaine utilisé et je charge la configuration correspondante.
Ca permet à la fois de gérer les environnements de développements différents et également de mettre des paramètres spécifiques à certains domaines (ex: locale par défaut fr_FR pour example.fr et en_Us pour example.com).
Pour info, pour gérer cette problématique dans symfony on a les outils suivants :
http://www.symfony-project.org/book...
Il suffisait d'y penser , merci pour cette info :-)
C'est typiquement le genre de syntaxe dont on est très friand dans Copix :-)
Il faut avouer que cela simplifie l'écriture.... par contre on se retrouve vite avec des syntaxes compact dont il faut connaître la signification :-)
_dao ('MaTable')->findBy (
_daoSp ()->addCondition ('champ', '=', $valeur)
->addCondition ('champ2', '=', $valeur2)
->orderBy ('champ3')
)
Ce qui ici signifie : Je vais récupérer dans ma table "MaTable", grâce à un "Data Access Object", les enregistrement qui correspondent aux paramètres de recherches (daoSP = Data Access Object Search Params) ....
Le plus proche de l'exemple serait la fabrique de classe, utilisée de la sorte :
_class ('classId')
...qui retourne un new 'ClassId' (en plus d'inclure le fichier en question grâce à un système d'autoload).
J'aime assez aussi la possibilité de faire un raccourcis pour obtenir des singletons de ces objets, avec par exemple
_ioClass ('classId');// (instance of class) qui retournera systématiquement la même instance de la classe 'classId'.
En tout cas c'est sûr, le nested call de PHP 5 est pour moi une grande nouveauté par rapport à la version 4 :-)
Merci beaucoup pour ce petit billet très instructif ;)
Pour les tests d'IHM: selenium
Pour les session, perso je fais ça avec un petit curl en ligne de commande. Basic, mais aide parfois
Joli :)
Que pense-tu d'APC ou memcached, pour le coup?
Mais comment n'y ai je pas pensé avant ?
Cela fera certainement l'objet d'un ou plusieurs autres articles ;) j'ai un penchant pour APC, que j'active systématiquement en production.
1/ Ok !
2/ Ok mais ça c'est de l'utopie ^^
3/ Ok mais je préfère le commit atomique à chaque modification mineure
4/ Ok !
5/ Ok mais pas toujours faisable. La capitalisation du code n'est pas toujours possible en fonction des spécificités de chaque projet.
6/ Tests fonctionnels ou unitaires ? Dans l'idéal il faudrait les deux :)
7/ Ok !
8/ Tu entends quoi par là ?
9/ 80 c'est presque trop. Dans la plupart des cas, on peut s'en tirer avec une trentaine / cinquantaine de lignes.
10/ Toujours :)
Tu as oublié un commandement important :
11/ Les commentaires PHPDoc tu utiliseras et ton code, intelligemment et efficacement, tu commenteras.
s/du développeur PHP/du développeur/
Pareil que Hugo, j'ai tendance à préférer les commits atomique.
1° C'est plus facile à "revert"
2° Ca oblige le développeur à travailler sur des micro blocs testés
Disons que c'est des bonnes pratiques pour tout codeur en général, pas spécialement PHP (du coup ok avec Bast: s/du développeur PHP/du développeur/ )
et c'est un peu trop orienté TDD: après tout, on est pas OBLIGE d'en faire, non?
@Gab : on est pas obligé de faire du TDD, par contre les tests unitaires c'est quand même un incontournable si tu veux développer de la qualité. TDD t'apporte la rigueur, la systématisation, la démarche, le cadre, l'assurance, la sérennité... ce serait dommage de passer à côté, non ? ;)
Ca fait un paquet de temps que je cherchais ce qui me dérangeait dans le TDD, et j'ai enfin trouvé. Pas que je le refuse complètement, mais un truc me turlupinait, et j'ai mis le doigts dessus: quand je développe, j'aime bien tester plein de trucs (méthodes différentes pour faire la même chose). Récemment, par exemple, j'ai utilisé memcache pour cacher mes pages, puis APC, puis re-memcache, et là je mets des smarty dedans (d'où plus besoin de memcache).
Or, si je passe mon temps à faire du test, je vais tester un truc qui en fait va disparaître au gré de mes idées, d'où frustration et perte de temps.
Où est la faille?
On peut aussi utiliser un système de patch: tu fais une lignée de code 'souche', et 2 stocks de patch pour la spécialiser.
Ca évite les switch interne avec des constantes.
Je me demande aussi si cette technique ne pourrait pas être jouable avec darcs (qui commit des patch, lui)
Pourquoi pas utiliser memcache?
Ton objet serait stocké dedans par l'appli, et recraché par le script PHP. Tu évite ainsi des accès disques.
Il existe aussi le plugin "modify headers" qui permet de (comme son nom l'indique) modifier les headers.
Tu ne veux pas faire une usine à gaz, mais tu t'embarques avec phing, phar et un fichier de config. XML.
OK, tu n'as qu'un seul script PHP à maintenir, mais par contre tu te retrouves avec X fichiers de config. XML.
Je pense qu'un script PHP pour chaque couple application/environnement serait une solution plus simple et donc plus efficace.
Effectivement on aurait pu se passer de Phar et Phing en ayant par exemple 1 fichier de script générique, n fichiers de configuration. Ca m'embête vis a vis du processus de livraison pour mes équipes de production, mais c'est tout a fait faisable et pertinent.
Par contre, faire 1 script spécifique par couple application/environnement, ca oblige à dupliquer la partie commune (affichage du résultats, code des tests de vérifications...) ce qui multiplie les erreurs possibles et rend plus difficile la maintenance. J'avoue cependant que c'est souvent ce que l'on rencontre dans les projets, car ca reste la solution la plus simple.
Par contre, qui/quoi garantit que ton / tes scripts de vérification ne contiennent pas d'erreurs et qu'il te dise que la connexion mysql testée est en succès alors que c'est faux ? Il peut être nécessaire d'ajouter des tests unitaires pour vérifier que les tests de santé que tu réalises sont bien implémentés et fonctionnent tel que prévu. Si tu as plusieurs scripts avec du code dupliqué, tu auras des tests dupliqués aussi, ce qui n'est pas optimal et une vraie contrainte pour les développeurs...
Il existe donc plusieurs méthodes, à choisir en fonction des besoins et des contraintes. De mon côté, tous les développements PHP sont accompagnés de tests unitaires cela à donc un impact sur l'architecture du code et notamment la mutualisation des méthodes/fonctions. D'autre part, j'évolue déjà dans un environnement Phing, la cout de mise en oeuvre est donc limité pour ma part.
En tout cas merci pour ton retour qui est une critique très intéressante !
Aller, j'enfonce le clou : tu dis que le script ne doit pas dépendre d'une bibliothèque. Mais il faut avoir installé l'extension phar sur toutes les becanes pour que ta solution fonctionne !
;-)
De mémoire (à vérifier), un phar est exécutable par PHP même si l'extension Phar n'est pas activé (c'est un des intérêts). Exemple : quand tu installes PHP sur ta machine en local (par exemple sous windows), tu peut ajouter le support de Pear, pour cela tu dois exécuter le fichier go-pear.phar (de mémoire encore) qui fonctionne même si ton installation de php est standard (je ne crois pas qu'avant la version 5.3 l'extension phar soit activée par défaut).
Depuis la 5.3, l'extension phar en native (de mémoire encore).
Je pense donc que ca ne pose pas de problème, mais dès que j'ai 5 minutes je teste, si ca ne marche pas je vous le dis.
Dans l'hypothèse ou ca ne fonctionnerait pas, ton script serait en erreur (il ne se lancerait pas), et tu le verrais tout de suite à son exécution, ce n'est donc pas une erreur silencieuse, et tu peux y remédier tout de suite. Le niveau de criticité me semble donc assez bas à partir du moment ou tu peux ajouter des extensions sur le serveur en fonction des besoins.
Il est probable, bien que l'extension phar ne soit pas nécessaire pour exécuter un phar, que les extensions de compression le soit tu as compressé ton phar (à vérifier). Mais je ne vois pas l'intérêt de compresser le phar dans notre cas.
en effet, l'utilisation des transactions mysql avec un bloc try/catch est la meilleure solution, c'est celle que j'utilise aussi
Dans l'idéal, il faut vérifier toutes les valeurs de retour de chaque fonction utilisée, que ce soit pour les bases de données, la manipulation du système de fichier... J'utilise PDO pour mes connexions à la BDD, ce qui me permet de profiter des Exceptions pour gérer les erreurs liées à la base de données.
En sachant que l'utilisation des transactions en MySQL n'est pas toujours portable, cela dépend du moteur utilisé (ça marche pour les tables en InnoDB mais pas en MyISAM)
Vous avez bien assuré sur le stand, malgré la concurrence de Python (AFPY) et Ruby On Rails :)
Pourquoi ne pas utiliser les exceptions définies dans la SPL (http://fr.php.net/manual/fr/spl.exc...) ?
Et à la limite :
class MaSuperException extends InvalidArgumentException { }
Cette approche a l'avantage selon moi de pouvoir définir un traitement différent selon les types d'erreurs rencontrés de façon générique, qu'elles soient levées par le langage ou par l'utilisateur (en tenant des journaux avec des niveaux de sévérité différents selon les types d'exceptions rencontrés).
J'utilise ce mécanisme en complément de la classe ErrorException (buggée en ce moment je crois) pour gérer tous les problèmes pouvant être rencontrés durant l'exécution des scripts.
Tu as tout a fait raison, l'utilisation des exceptions de la SPL est une bonne pratique.
Jusqu'à la version 5.3 (non compris), l'extension, packagée avec PHP par défaut, pouvait être désactivée. Depuis la 5.3 elle ne peut plus être désactivé, il n'y a donc plus d'excuse pour ne pas l'utiliser.
Cela ne vous empêche pas de rajouter certains type d'exceptions non prévus dans la SPL, avec parcimonie !
Si le concept de packages pour PHP vous intéresse, jetez un coup d'oeil à http://webappkit.net
Il s'agit un système de paquets pour PHP, qui facilite la gestion des dépendances entre librairies et offre également une interface d'administration permettant de visualiser le tout et d'executer les tests unitaires.
Et bien sûr, c'est open source et quelques librairies sont déjà fournies.
Merci pour l'information sur webappkit !
Je testerais dès que possible.
Quelle est la particularité par rapport au système de gestion de dépendances et de packaging de PEAR ?
Olivier
PEAR s'installe au niveau système et ne gère que des librairies. Webappkit s'installe au niveau application web (simple dezippage), de telle manière qu'une appli construite sur Webappkit peut être entièrement installée via FTP.
De même, l'interface d'administration est une page web qui à terme permettra d'installer les librairies par upload de fichier zip. Pour l'instant elle permet de visualiser les tests, vérifier les dépendances, l'intégrité des paquets etc.
En outre, les paquets sont accessibles sous forme d'objets dont la classe est extensible, et auquels on peut adjoindre des objets services issus d'autres paquets. Un paquet peut ainsi contenir d'autres types de ressource que des scripts PHP, tel que des templates, etc. Ceci permet d'avoir une application complete sous forme de paquet.
Je ferai une nouvelle release (0.13) prochainement (une a deux semaines).
Pour gérer le problème de la base de données, je vois deux solutions qui s'intègrent dans le script de livraison de l'appli :
* Sauvegarde complète de la base que l'on archive dans /opt/mon-appli-2.1
* Versioning de la base de données (non testé) : une base par version du code.
Mais en cas de rollback rest le problème du différentiel de données (nécessite une anticipation).
PS: A noter que les fichiers générés par l'application doivent être géré hors du "code"
J'utilise Subversion pour gérer le déploiement de mes releases en taggant celles-ci dans mon repository.
Ainsi je n'ai qu'à faire un svn export du tag correspondant à la release que je veux déployer. Idem pour revenir en arrière.
@Jean-Sébastien: concernant le problème de différentiel des données en cas de rollback, il y a peut être une piste du côté du mécanisme de réplication des bases de données. Notamment MySQL Replication Mechanism permet de répliquer toutes les requêtes effectuées à partir d'un instant (numéro de version de la base) sur une autre base de données (i.e. un autre serveur). Il suffirait alors de noter le numéro de version quand on fait une mise en production, et lorsqu'on fait un rollback d'activer le mécanisme de réplication sur un nouveau serveur/base de données et faire répliquer toutes les requêtes le numéro de révision et maintenant. A creuser (déjà testé sur une plateforme mais pas dans ce contexte).
@Ladenise: svn export n'est pas forcément "rapide", en effet si ton projet contient des milliers de fichiers, la durée du svn export peut être non négligeable (plusieurs minutes) et rendre indisponible ton application, voir pire, pendant le svn export, si tu n'as pas désactivé l'accès à l'appli il peut y avoir un comportement imprévu si certains fichiers sont exportés mais pas tous. D'autre part, comme l'indique Jean-Sébastien, il faut forcément coupler avec un autre mécanisme pour gérer le rollback de la base de données car svn export ne peut le faire (peut être avec un script côté serveur svn, car c'est possible de déclencher un script sur une action svn, mais si le serveur svn n'accède pas à la prod...). La solution svn export est une solution simple cependant.
Je ne pense pas que dirname( __FILE__ ) remplace le define( 'ROOT' , <dir> ).
L'un n'a rien avoir avec l'autre.
L'utilisation d'une constante qui pointe sur la racine est très utile : pour former un path sans avoir de ROOT, on doit jongler avec les '/..' etc.
L'inclusion dans les autoloader de class (spl_autoload_register), de déplacement au sein du filesystem du code, etc., sont entièrement facilités par une constante "ROOT". Les chemins relatifs portent trop souvent à confusion.
De plus, le fait de définir le ROOT à partir de dirname( __FILE__ ) fait qu'il est absurde de dire une bêtise comme :
"Plus besoin de tenir un fichier de configuration avec des define qui est a modifié à chaque installation."
Encore une fois, l'un et l'autre sont deux choses différentes.
De plus, il aurait été intéressant de préciser qu'à partir de la version 5.3, la constante __DIR__ offre l'équivalent d'un dirname( __FILE__ );
@avetis.kazarian: tout est histoire de pratique, il n'y pas de bonnes et mauvaises pratiques universelles, cependant certaines pratiques sont plus adaptées que d'autres dans certaines situations.
Un fichier qui utilise le principe de dirname(__FILE__) pour inclure ses dépendances, est potentiellement utilisable directement par une autre application ou script, si il nécessite la présence de constantes (ex: ROOT) alors il faudra au préalable définir ces constantes avant d'utiliser ce fichier dans une autre application.
Effectivement, cela n'a pas de réelle importance lorsque l'on développe une application autonome, mais en prend lorsque l'on décide de rendre potentiellement mutualisable à toutes nos applications/scripts tous les développements que nous réalisons.
Attention aux "dépendances" implicites de notre code à des éléments extérieurs (define, variable globales, fichiers de configuration...) ils rendent difficilement testable ou utilisable dans un autre contexte notre code.
Merci pour la précision sur la constante __DIR__ en PHP 5.3, pour toutes les applications legacy des S.I français (et autres !) qui ne pourront pas bénéficier de la 5.3 avant quelques mois voir années, dirname(__FILE__) reste utilisable en attendant...
J'utilise Komodo edit. J'ajoute les doc block à la main, mais ceux ci sont ensuite supportés par l'autocompletion ce qui est une bonne incitation à leur utilisation :)
J'avoue que je n'utilise pas trop le chainage des appels, le poids de ma pratique de PHP4 sans doute. Et généralement mes setters renvoient un booleen.
Même chose et même évolution que toi.
Au début c'était cool l'autocomplétion puis c'est devenu une vrai méthode de travail. Les appels chaînés sont devenu une religion...
Ce qui m'amène à regretter que les types scalaire de php ne soit pas objet et qu'on ai toujours les str... fonctions, les array... fonctions etc...
Attention ! Il ne faut pas mélanger les "doc block" (autrement dit PHPDoc) et les "annotations"; ce sont deux choses entièrement différentes dans Eclipse.
Ce que vous présentez-là sont les blocs de commentaire à la JavaDoc (pour PHP on dit PHPDoc). Alors que les annotations sont un ensemble de mises en relief du code que propose Eclipse. On trouve les options d'annotations dans General > Editors > Text Editors > Annotations. Elles permettent notamment avec PDT par exemple, d'avoir pour une variable toutes les occurrences surlignées en une couleur (lorsque le curseur se trouve dessus).
Il y a de très nombreux paramètres et on s'y perd vite, mais une bonne utilisation de ceux-ci permet de gagner beaucoup de temps.
Je recommande à tous ceux qui travaillent sur un fond noir de passer par là pour les problèmes de couleurs (light/light).
En passant :
"public function getInstance" n'est pas déclarée "static" ;)
@avetis: merci de la précision sur une des nombreuses fonctionnalités d'Eclipse ;)
Par contre, en PHP le terme Annotations est aussi utilisé pour ce type d'artefact, cf http://www.slideshare.net/stubbles/declarative-development-using-annotations-in-php, ou le package PEAR PHP_Annotation, entre autre.
J'en conviens il s'agit plus de doc bloc façon xdoclet (de mémoire en Java) plutôt que de réelle annotation à la sauce Java. Mais c'est un compromis déjà efficace à leur actuelle.
Merci pour la coquille sur le public final static getInstance, c'est corrigé.
Je ne suis pas un expert avec les patterns, pourrais-tu développer cette phrase ?
"je crée quasi systématiquement des factories pour éviter de passer par une variable inutile"
Dans un nouveau post éventuellement.
@Moosh: plus simplement (j'espère ;) ) :
$o = new MaClasse();
$o->maMethod1();
$o->maMethod2();
$resultat = $o->maMethod3();
Dans ce cas là, tu réalises un enchainement de méthodes qui appartiennent toutes à l'objet $o. La variable $o finalement ne te sert pas à grand chose si ce n'est de pouvoir appeller les méthodes les unes à la suite des autres. Pour factoriser tu pourrais faire :
$o = new MaClasse();
$resultat =
$o->maMethod1()
->maMethod2()
->maMethod3();
C'est déjà un peu mieux (on peut tout mettre sur une ligne si on veut), par contre on se rend compte que la variable $o ne sert à rien finalment car elle n'est plus jamais utilisée (dans la suite du script). Du coup tu pollue ton script avec des variable qui ne sont pas utilier (et aussi l'espace mémoire).
L'idée de la factory c'est finalement de faire une méthode static qui permettra d'éviter de mettre le "new MaClasse()" dans une variable :
$resultat = MaClasse::creeObjet()->maMethod1()->maMethod2()->maMethod3();Si tu as pris soin de mettre de nom de classe explicites, des noms de méthodes assez court et parlant, tes scripts peuvent être plus concis et plus parlant (tu peux aussi mettre sur plusieurs lignes).
La méthode creeObjet() peut aussi prendre un paramètre (c'est tout l'intérêt d'une factory), on sait qu'on fait souvent l'enchainement maMethod1() et maMethod2 dans notre code, et qu'en suite on a besoin de l'objet. On peut alors faire :
class MaClasse {
...
/**
* Fait quelquechose
*
* @return MaClasse
*/
public function maMethod1() {
...
return $this;
}
/**
* Fait quelquechose
*
* @return MaClasse
*/
public function maMethod2() {
...
return $this;
}
/**
* Fait quelquechose
*
* @return string
*/
public function maMethod3() {
...
return "un resultat quelconque ici";
}
/**
* Retourne une instance de la classe
*
* @param string $comment optionnel, quel type d'instance retourner ? Si null, une instance vierge, si 'm1_et_m2' => l'instance aura déjà eu maMethod1() et maMethod2() d'appellées
*
* @return MaClasse
*/
public final static function creeObjet($comment=null) {
$o = new self;
if (null !== $comment && 'm1_et_m2' === $comment) {
$o->maMethod1()->maMethod2();
}
return $o;
}
...
}
$result = MaClasse::creeObjet('m1_et_m2')->maMethod3();
Ma remarque voulais simplement dire qu'en utilisant ce principe de factory (qui prennent un paramètre éventuellement) je peux éviter de faire le new moi-même et éviter de stocker l'objet dans une variable (si combiné avec des 'return $this' dans chacune des maMethodX())
J'espère que c'est un peu plus claire, sinon n'hésites pas à demander des précis / rectifications
v0.2.0 releasée !
Nouvelle feature : calcul des ratios de taille, nombre de fichier et nombre de lignes pour des patterns de noms de fichiers donnés :
ex: "je veux connaitre la proportion de fichiers PHP qui sont situés dans le répertoire tests/ par rapport à ceux qui sont dans le répertoire library/"
Voilà un outil intéressant que j'ai hâte de tester.
Sur le même sujet, l'outil phploc de Sebastien Bergmann qui permet de calculer des informations similaires mais plus basées sur le nombre de lignes pas les ratios (que l'on peut calculer ensuite vous me direz).
Ca sert plutôt comme outils 'a posteriori', non? Par exemple pour comme indicateurs.
Intéressant comme outil.
Par contre les mesures de temps me surprennent : PHP se targue d'avoir améliorer les performances de 10 à 20% sur les versions 5.x et ca ne se reflète pas dans tes chiffres.
@jean-sebastien: Bonne remarque, effectivement de prime abord j'ai été surpris par les temps d'exécution qui s'allongent sur les versions plus récentes de PHP. Je n'ai pas investigué plus sur le sujet mais mon hypothèse est que cela vient du mode d'exécution. J'utilise l'exécutable php en ligne de commande pour chaque exécution de fonction, il est probable que l'overhead de chargement de php en mode CLI soit plus important sur les versions récentes de PHP, ce qui n'est probablement pas le cas en mode Module sous Apache (chargement au démarrage d'Apache). Je ne vois pour l'instant que cette seule explication. Cela rend effectivement un peu moins pertinent la mesure des temps d'exécution, qui du coup sont aussi fonction de la charge CPU/Machine (puisqu'un nouveau process est exécuté), donc peuvent être pollué de façon transparente. En appuyant sur F5 plusieurs on peut notamment avoir la tendance tout de même ;). Pour aller plus loin, il peut être envisageable que je retranche le temps de chargement PHP et que je mette uniquement le temps d'exécution, d'ailleurs ce serait plus pertinent, d'ailleurs je viens de faire la modification ;)
Pour moi, je travaille souvent sur Netbeans 6.5 grâce à ses fonctionnalités qui couvrent tous les besoins d'un developpeur professionnel
Bonjour,
Merci pour le tutotial. Par curiosité.
Hormis les paquets pear, je ne me rappel pas avoir été embeté par l'installation de hudson en suivant la procédure suivante.
http://weblogs.java.net/blog/kohsuk...
et pourquoi ajouter lighthttpd ?
@senjy : il s'agit d'une installation sur un serveur dédié à hudson, pas d'applications web sur ce serveur, j'ai jugé que lighttpd serait suffisant et plus léger que apache, sachant que le serveur n'est pas une bête de course. Mais apache est un bon candidat sinon, bien sûr. Concernant le tutorial, votre lien est cassé, je pense qu'il s'agit de http://weblogs.java.net/blog/kohsuke/, je me suis inspiré de certains articles de Kohsuke mais j'avoue ne pas avoir trop cherché de tutoriaux tout fait sur l'installation, étant donné que j'avais la spécificité PHP / Lighttpd / OpenJDK. Merci tout de même pour le pointeur.
Une autre bonne habitude pour éviter ce genre de problème est d'indiquer le type de l'objet attendu, lorsque l'argument est un objet :
function foo(anObject $objet = null) {
...
}
Cette méthode évite bien des problèmes sans surcharge de code dans le corps de la fonction, vu que la vérification est prise en charge par le moteur de php nativement.
Cepdendant, vu que les types de base de PHP ne sont pas "objet" (sic), pour ces derniers, ta technique est la plus appropriée, à part dans les cas des tableaux ou la mienne fonctionne également (encore une aberration de PHP :)) :
function foo(array $array = null) {
...
}
Merci pour ce build, c'est tres interessant.
Est ce que c'est possible d'avoir quelques capture d'ecran du résultat obtenu ?
Je ne pensais pas qu'en 2009 on pouvait encore se poser cette question. La réponse est assez évidente il me semble.
Superbe analyse.
Voilà enfin les bonnes questions qui sont posées.
Pas la POO pour la POO. Autrement dit tous les Framework ne se valent pas selon mes besoins/projet/compétences/tps mise en oeuvre.
On peut facilement imaginer utiliser partiellement un framework pour la partie qui nous apporte réellement de la valeur ajoutée. Les modules trop lourds du framework (du point de vue projet) peuvent alors être remplacé par une méthodologie maison potentiellement avec une partie procédurale (pas de tabous) en plus de la POO bien sur inévitable.
Il faut donc privilégier les framework modulaires
Les bonnes questions sont posées.
Je développe plutôt en procédurale, mais depuis quelques temps je passe de plus en plus au POO. J'utilise un Framework POO : Kohana. (une base de Code Igniter, mais uniquement PHP 5 et Objet). Si on souhaite suivre l'évolution de PHP, resté en 100% procédurale revient a une limitation assès déconcertante.
Je suis en train d'essayer, mais après avoir installé PHPUnitLaucher et les outils de dev Java, "Run As... Junit test" m'ouvre la console pour me dire "May be port 8888 in used, try another". Ou parfois il ne dit rien.
J'avoue que je ne sais pas quoi passer à -DphpunitArgs...
Ben en fait le channel pear.phppro.fr
ne réponds plus
> Subversion (ou CVS, même si je conseille de l'abandonner au profit de CVS)
Je suppose que tu voulais parler de Subversion et non de CVS la seconde fois. ;)
Plutot qu'écrire du code pour les Mock, PHPUnit a développé un système de bouchon assez puissant.
Voir la fonction getMock
Justement à propos de :
il manque un test (non unitaire cette fois-ci) qui nous permet de vérifier
Quelle serait sa forme idéale ? Implémentation, méthode, utilisation ?
@Bruno: un début de réponse dans mon post : http://blog.phppro.fr/?post/2009/08/14/Tests-d-integration-quezako
@jsh : tout à fait d'accord avec la présence de cette fonctionnalité intéressante de PHPUnit, pour ma part je préfère réaliser mes mocks moi même car sinon je ne peux pas utiliser de mock en dehors de mes tests unitaires, hors cela peut être intéressant d'utiliser un mock à certains moment du développement (au début du développement d'un webservices par exemple), ou bien dans un autre contexte d'appel que phpunit. D'autre part, je trouve le mécanisme de gestion de la pile d'appel assez verbeux à écrire pour le mock, et je préfère la notion de pile à la "addExpectedResult", plus brute mais plus simple. Mais la fonctionnalité reste intéressante ;)
@Bruno : il s'agit d'une indisponibilité temporaire, cela devrait être rétabli fin aôut (réinstallation de mon serveur PEAR :( ), En attendant tu peux télécharger le tarball compatible PEAR sur Google Code à l'adresse http://code.google.com/p/phpcoderatio/downloads/list, puis faire un :
$ pear install phpcr-0.2.0.tgz
@Cédric: je t'invite à ouvrir un ticket sur http://code.google.com/p/phpunit4eclipse/issues/list, ou à contacter Bertrand Paquet le développeur "bertrand point paquet at gmail point com"
@Senjy : Quels types de captures d'écrans souhaites-tu ?
merci pour cette article, c'est intéressant de trouver des sujets qui touche le monde professionel en plus autour de PHP. Ce qui est rare.
Mais c'est vrai qu'avoir des exemples concret c'est encore mieux. aussi je suis preneur
petite question sur un détail constaté :
"Exemple dans le fichier contexts/@common.php (inclus par tous les fichiers de mon application) :"
à quoi sert ce @ dans le nom de fichier ?
Classement ? comportement magique ?
"Le travail fait n'est jamais perdu", dixit un collègue ;)
Tu dégage le code, mais les idées que tu as mis en oeuvre pour l'écrire reste d'une manière ou d'une autre dans ta tête.
Exactement la même chose. Votre réponse est parfaite. On trouve si souvent des méthode commentées dans des classes sans savoir qui les a écrites, qui les a commentées et pourquoi... La gestion des version est là pour cela.
Quand au wiki c'est effectivement un point intéressant pour peu que l'on en ai un sous la main.
On dispose de solutions pour garder des traces de changements (svn par exemple), par contre j'ai toujours pas trouvé de solution efficace permettant de "se souvenir" de ce qui a été fait.
Vous est-il déjà arrivé de récupérer un vieux code dont vous n'aviez la connaissance ni au moment de son écriture, ni du nettoyage ?
Je suis persuadé que le seul cas où ça se produit c'est le coup du collègue qui dit "ya machin qui avait codé quelque chose de similaire, regarde le dépot".
@Raph: bonne remarque, effectivement cela arrive régulièrement de commencer à développer une snippet pour nos propres besoins et de se rendre compte que quelque chose de similaire a déjà été développé dans l'équipe (par le passé, ou ... en parallèle !). Pour tenter d'endiguer ce problème je propose en règle général un ensemble de pratiques simples à mes développeurs: 1/ regarder si un "service" (par exemple technique) n'existe pas déjà dans l'API projet, 2/ ne jamais copier / coller mais plutot déplacer du code à un endroit central et l'utiliser à plusieurs endroits, 3/ toujours développer la solution la plus simple possible pour répondre au besoin du moment, entres autres.
Eclipse et Zend Studio propose des "Code Gallery", je pense que c'est aussi une piste pour retrouver du code déjà développer en ayant une démarche "search first, code after".
j'aime bien cette idée de revue partielle de code, je suis cependant un peu réticent à l'idée de laisser le développeur choisir quel fragment de code sélectionner, craignant un peu la dissimulation du code "baclé" et l'envoi d'un code nettoyé, surtout si la personne relisant ce code est un n+1... Je préfère l'idée d'un envoi d'une liste des fonctionnalités développées et une revue de code "au hasard" ou d'instinct sur les fonctionnalités critiques.
L'idée de la revue croisée est une bonne alternative, (j'en avais discuté avec Damien Seguy lors d'une formation), bien encadrée, elle permet de créer une émulsion entre les développeurs.
Merci, c'est une présentation très claire.
Tu parles des tests fonctionnels avec Fitnesse et PHPSlim/PHPFit. Ca fait longtemps que j'en entend parler mais n'ai jamais eu l'occasion de les utiliser sur de vrais projets. Tu aurais des cas concrets de mise en œuvre à présenter ?
@clochix: je prévois un ou plusieurs articles sur le sujet TDR (Fitnesse / GreenPepper) dans les prochaines semaines, keep in touch ;)
Complément d'information posté sur le blog de Clochix (http://www.clochix.net/post/2009/09...) concernant l'utilisation des fonctionnalité Mock de PHPUnit:
Pour ma part, j'évite de l'utiliser (i.e. la fonctionnalité Mock de PHPUnit) car je souhaite rester indépendant d'un quelconque framework lors de mon développement.
Les fonctionnalités Mock de PHPUnit sont très intéressantes, elles ont cependant de mon point de vue un défaut majeure dans l'utilisation que je fais des mocks. En effet, lorsque je développe j'utilise la version "mock" de mes classes (adapter) dans mon code tant que je n'ai pas développé la version native (standard). Cela me permet de prototyper / présenter rapidement les fonctionnalités "statiques" de mes développements et de "débrancher" lorsque je suis prêt le mock pour mettre la vraie implémentation (imaginez que je développe un webservice et que je doive rapidement fournir une version de mon webservice pour des consommateurs qui seraient "impatients"). Le problème avec le framework PHPUnit est qu'il n'est pas adapté a priori pour une utilisation en dehors des tests unitaires.
autre part les mocks peuvent être utiles dans d'autres cas encore que les tests unitaires et celui que je décris, par exemple certains tests d'intégration qui porte sur d'autres zones du code... même remarque dans ce cas.
Et vous quels sont vos pratiques pour mettre en place des bouchons dans les cas autres que les tests unitaires ?
J'utilise ext/inclued.
Qu'as-tu utilisé comme outils ?
@jpauli: Je ne connaissais pas ext/inclued, je pense qu'il est très similaire à mon outil, qui par contre est un outil d'analyse statique (pas au runtime). J'ai moi même développé l'outil qui a servi à généré ce graphe. L'algorithmique est simple : analyser toutes les références à des classes / inclusions autres que la classe courante, c'est à dire recenser les extends, implements, includes, appels statiques, instanciations, ... Mon problème se situe plutôt au niveau de la réprésentation graphique, j'ai actuellement fait le même choix basique que ext/inclued, à savoir l'utilisation de graphviz/dot, qui fonctionne plutôt bien, mais mes conclusions sont que pour profiter de toutes la richesse de ce type de graphe/informations il est nécessaire d'utiliser une représentation graphique "vivante" permettant de parcourir en temps réel les dépendances, notamment lorsqu'il s'agit du graphe de dépendances de ZF (plusieurs centaines de noeuds)... Pour l'instant j'ai vu une librairie Flash qui serait parfaite pour ça, Constellation Roamer de Asterisq (www.asterisq.com), mais le prix de la licence ma un peu refroidi, pour l'instant...
Je compte mettre en open source le code de l'outil, mais le temps me manque ces jours-ci ;)
Le temps manque ? C'est bizarre je connais bien le principe xD
Très intéréssant ton outils. Bcp de projets PEAR possèdent un parseur PHP libre basé sur les tokens (PHPDepends, PHPCPD etc...), peut-être pourra tu créer un channel pear et un composant quand tu auras le temps ? ;-)
Quoiqu'il en soit, je ne peux t'aider en ce qui concerne l'animation, mais je reste persuadé que de tels paquets existent dans le monde du libre (le contraire m'étonnerait). A chercher... :)
Bonjour,
j'ai trouvé le slide excellent. cela correspond pile poil à ce que j'aimerai mettre en place dans mon entreprise.
ce n'est pas facile mais j'y crois dur comme fer.
est-ce que tu as quelques conseils sur la manière de procéder ?
merci d'avances
@jacko972: envoie moi un email sur contact at phppro point fr en me décrivant ton contexte, tes problématiques et tes questions
Salut, merci pour cet article intéressant.
Pour la visualisation dynamique, ça me fait penser à un outils Java (désolé...) très intéressant pour parcourir le modèle d'une BDD : jailer. Il se base sur une librairie graphique (prefuse). C'est du Java certes, mais il y a surement des idées à puiser ;)
A+
Merci pour l'analyse, effectivement il serait bien de pouvoir greffer un outil similaire à celui ci à une trace d'exécution temps réel.
Pourquoi pas à base des traces générées par xdebug, que j'analyse avec kcachegrind pour le moment. Au niveau des bibliothèques qui permettent de faire ça, je pense à Infovis(http://thejit.org/demos/).
Sinon, une bonne manière de comprendre et d'analyser les dépendances de notre code, c'est d'utiliser l'inversion de contrôle, et de coupler le tout avec un injecteur de dépendances, pour générer directement un schéma !
C'est amusant, j'avais commencé aussi à coder un analyseur de dépendances mais pas du tout dans ce but. Le mien était de pouvoir extraire seulement le nécessaire d'une librairie ou d'un framework.
@alexis: déjà essayer InfoVis (JS) mais pas satisfait pour ce besoin. Mes conclusions sont que seul flash / flex offre une ergonomie suffisante dans mon cas (fluidité, usabilité...).
@evoilliot: jailer semble trop spécifique aux base de données effectivement. J'ai déjà regardé du côté du projet Prefuse, qui a une implémentation exceptionnelle en Flex/Flash (Flare Project). C'est d'ailleurs celle qui est en top de ma liste. Le coup d'intégration de la librairie est cependant assez élevé (pas mal de développement ActionScript), je n'ai malheureusement pas assez de temps pour améliorer ma Proof of Concept sous Flex Builder :(
@jean-marc: peut être des bonnes idées à prendre dans ton outils, il est disponible quelque part ?
@all: version open source imminente...
Respects !
Voila un outil des plus intéressants concernant l'OO.
J'utilisais PHPDepends jusqu'à présent, mais ton outil est d'ores et déja dans ma liste ;-)
Merci, c'est un article interessant pour un sujet qui est d'actualité pour moi. Comment inserer des images dans un documents docx ?
@spm: C'est un peu plus compliqué mais possible, j'utilise ce type de routine (qui contient certainement des bugs, mais qui fonctionne pour mes générations de rapports avec OpenXML) :
// parses for pics if (preg_match_all('/(.*)<\/p\:pic>/U',$content,$matches)>0) { for($i=0;$i
/U',$matches[1][$i],$matches2)>0){ $matches3 = null; if(preg_match_all('/\$\{([^\}]+)\}/',$matches2[3][0],$matches3)>0) { $matches4 = null; if(preg_match_all('/0){ $relFile = dirname($file).'/_rels/'.basename($file).'.rels'; if (true === file_exists($relFile)) { $x = simplexml_load_file($relFile); foreach($x->Relationship as $relationship){ if ((string)$relationship['Id'] === $matches4[1][0]){ $picFile = (string)$relationship['Target']; if(!$picFile) continue; $picFile = realpath(dirname($file).'/'.$picFile); if(!$picFile) continue; unlink($picFile); try { $tplPicFile = $this->parseVar($matches3[0][0],$matches3[1][0],$vars); } catch(Exception $e) { $tplPicFile = dirname(__FILE__).'/resources/no-data.png'; } copy($tplPicFile,$picFile); } } } } } } } } $content = $this->parseString($content,$vars);
Globalement, je mets le nom de la variable dans l'attribute "description" texte de l'image dans mon document openxml (par exemple dans powerpoint) puis je parse le xml du document pour remplacer les occurences des variables par les vrais images sachant que les balises xml existent déjà (puisque créé par powerpoint) sauf sont à ajouter les balises xml des resources (le fichier image complémentaire)
Sorti du contexte, ca doit être un peu rebutant par contre, je le conçois...
olivier
J'ai toujours dit que PEAR c'est 4 choses utilisables indépendament.
1° Une librairie à classe unique. Je veux dire que normalement il n'y a pas 2 classes qui font la même chose.Et quand c'est le cas il faut le dire.
2° C'est un outil de packaging et déploiement pour ce package de classe php (pear) ou de modules de php (PECL)
3° C'est une convention de codage
4° C'est une communauté.
Beaucoup se limitent à croire que c'est juste le 1° et que ca en fait un simple concurrent à Zend_Framework, Symphony, Midgard, .... Hors beacoup de librairies (y compris ces dernières) peuvent être installée avec pear.
Merci Olivier pour ce super billet, sa partie technique et surtout tes remarques.
Tu me donnes des idées pour notre plateforme d'intégration continue...
Conseils d'utilisation de PEAR ? Utilisez-le toujours pour packager/déployer vos devs OS !
Sinon en ce moment j'essaye d'améliorer la débianisation des paquets pear pour qu'elle soit justement plus adaptée aux nouveaux usages : https://www.assembla.com/wiki/show/... Si quelqu'un s'y connait et peut jeter un coup d'oeil...
Nous passons par le svn de SimpleTest (https://simpletest.svn.sourceforge....), tout "bêtement", ce qui nous permet d'avoir une propriété svn:externals dans le projet concerné et de mettre à jour simpletest facilement s'il y a lieu.
Vu qu'aucune configuration n'est nécéssaire au niveau de SimpleTest, la mise en oeuvre d'un autre outil ne s'est jamais fait sentir.
Bonjour,
Je recherche des informations sur l'utilisation de Phing et PhpUnderControl, mais j'ai un peu du mal à dissocier les différences entre les 2. Si j'ai bien compris phpUnderControl peut utiliser phing ? Mais j'ai l'impression que phpUnderControl peut faire la même chose que Phing. Bref si vous pouviez m'éclairer ? :)
Je pense que l'apprentissage du framework est une des facettes de l'apprentissage de notre métier.
Comme si on avait l'habitude de programme "en ligne", le jour où on décide de passe a la POO
- il nous faut 2 mois pour comprendre les subtilité de l'héritage et utiliser les différents design pattern
- Il nous faut 3 mois pour migrer tout le code sur php 5.3 et utiliser les namespaces (on notera que, comme pour le framework, rien nous obliger a upgrader on peut rester sur la version précédente)
- Après 4 mois, on refait tout parce qu'on a compris comment ça marche..
On peut trouver de exemples comparable avec la POO, des design pattern, des nouveau langages etc...
Est ce que sur le dos de l'économie on doit stagner sur nos acquis ? je doute.
Ce qui vaut pour les framework vaut aussi pour les CMS et surtout pour Php lui même.... ;-)
C'est toute l'histoire de l'informatique ou les choses sont rarement figées.
@r.johann@orange.fr: Quelques précisions sur mon billet : http://blog.phppro.fr/?post/2010/02/28/Complementarite-PHPUnderControl-/-Phing
C'est marrant parce que ça fait un moment que je développe un portail client sous drupal et je suis arrivé à la même conclusion.
Si bien que maintenant le module drupal me sert en gros de contrôleur et que les parties Modèles et Vues sont codées séparément.
pour l'apprentissage je suis d'accord, mais c'était pareil quand j'ai appris php, actionscript etc, il y a toujours un periode d'apprentissage et puis c'est tellement bon d'apprendre une nouvelle chose. Après pour ce souvenir des class perso, il y a les commentaires !! non ??
t'as oublié, avec un framework, il suffit de recruter un developpeur qui connait le framework pour qu'il se retrouve facilement dans le code, alors qu'avec un code sans framework ce dernier met 1 mois à comprendre comment ça marche !!
Je suis assez d'accord avec le principe d'écrire du code le plus ré-utilisable possible mais je ne vois pas bien le lien avec le constat fait au début de l'article...
Le temps d'apprentissage du framework est nécessaire et se révèle productif parce qu'on capitalise dessus.
Il n'empeche que le code qu'on va développer dessus peut etre générique comme tu le dis à la fin.
Pour la problématique de passage d'une version majeure à la suivante, c'est vrai que c'est galère, mais en même temps on ne choisit de le faire que si le projet le nécessite, c'est-à-dire si ses fonctionnalités évoluent de manière considérable. Dans le cas contraire, ce n'est souvent pas nécessaire.
Bref, bien coder (code optimisé, réutilisable) ne dépend pas du fait d'utiliser Symfony ou ZF, ni de développer en 5.3 ou pas... Et cet article le rappelle bien !
Merci pour cet article.
Il me servira de base pour l'intégration de ces outils.
Est-ce qu'on peut dire que c'est du cloud computing ?
Pour ma part, j'aurais séparé PHP et MySQL, cela permettra de créer si besoin un cluster en fonction de la charge à prévoir.
Je n'ai pas compris cette notion de Serveur Mandataire, ça ne peut pas être fait par le serveur Web ou PHP ?
Le reverse-proxy est à mon sens géré par l'hébergeur, donc techniquement je n'en parlerai pas dans la réponse. Et puis au final je ne parlerai même pas de PHP ou de MySQL, car pour ton client qui n'a pas de ressource technique ni peut-être de connaissance cela ne lui dit rien.
Par contre, il faudrait accès ton discours autour du gain apporté..
Qu'en pensent les autres ??
Bonne journée
S.
Pour moi la solution réside vraiment dans certains design patterns (service layer, datamapper, dao, ...) qui permettent vraiment de dissocier la logique métier du framework. J'ai récemment pu faire le test de porter directement ma couche métier de Zend Framework vers eZPublish en changeant uniquement les mappers.
Les modèles étant très génériques, les tests unitaires sur ces classes n'ont plus à être modifiés.
Je pense qu'en adoptant une vision très modulaire et en couches on peut vraiment palier à n'importe quelle problématique et ainsi ne plus être prisonnier d'un framework (en gros on choisit celui sur lequel on est la plus efficace)
J'aurais bien aimé lire les réponses ...
Perso, j'utilise tcpdf car il supporte le html et en général, je crée donc un tpl html que je remplis avec les données depuis la db et que je passe à tcpdf.
Sinon pour cette technique, elle est intéressante a part qu'il me semble que si tu dois afficher un texte dont tu ne connais pas la longueur alors tu peux avoir des problèmes dans le positionnement absolu après, du style textes qui se chevauchent mais c'est à creuser.
L'approche est interressante par contre je trouve que la génération de pdf est vraiment quelquechose de rébarbatif et peu passionnant.
J'ai eu l'occasion d'utiliser wkhtmltopdf et cela m'a vraiment séduit :
- avoir une approche souple de la mise en page comme on peut l'obtenir avec le (x)html / css.
- avoir le rendu de webkit (qtwebkit)
Le principal inconvénient de cette solution est l'obligation de pouvoir utiliser un binaire sur son hébergement.
http://code.google.com/p/wkhtmltopd...
Intéressant sauf que Zend_Pdf, même s'il peut charger des pdfs, reste encore très limité niveau fonctionnalités. Pas ou peu de formatage du texte (alignement justifié, écriture de bloc, analyse d'une syntaxe html pour le formatage), pas de possibilité de limité les actions sur le pdf comme empêcher le copier/coller ou l'impression, etc ...
Perso j'utilise tcpdf pour générer mes pdfs de bout en bout. La librairies n'est franchement pas très propre mais est assez efficace.
Nettement plus terre-à-terre, j'utilise le tandem FPDF (de http://www.fpdf.org) combiné à la libraire FPDI (http://www.setasign.de/products/pdf...).
FPDF est une classe (géniale) qui permet de générer du PDF sans passer par des librairies et FPDI (héritant de FPDF) permet d'utiliser des modèldes comme fond de page.
Résultat le code PHP à écrire se limite aux cellules "dynamiques"
On peut aussi faire appel à wkhtmltopdf (http://code.google.com/p/wkhtmltopd...)
Simple utilitaire shell pour convertir html en pdf avec webkit rendering engine.
On peut prévoir une feuille de style dédiée.
C'est vraiment LA solution la plus simple pour le développeur.
Juste peut-être développer un système de cache pour les pages qui sont appelées de multiples fois.
Je l'ai utilisé pour mon intranet Drupal (http://drupal.org/project/print). Pas encore exempt de bug avec Drupal mais ça va venir.
@metagoto: d'après la définition Wikipédia (et celle que j'avais en tête), il ne s'agit pas vraiment de cloud computing, car dans ce cas là le client est "propriétaire" de l'infrastructure et doit gérer le capacity planning notamment. Source: http://fr.wikipedia.org/wiki/Cloud_computing
@syndrael: Bonne remarque concernant la séparation PHP/MySQL. Je n'ai pas jugé utile de le faire dans cette version de la plateforme car nous prévoyons des volumétries relativement modestes, et le client souhaite pouvoir maintenir ou faire maintenir l'application et la plateforme par des partenaires plutôt web agency dans le futur (boite locale). Concernant le reverse-proxy, j'aurais effectivement pu utiliser les mécanisme de load balancing proposé par l'hébergeur (optionnel, pas dispo en standard), je souhaitais avoir un peu plus de flexibilité et pouvoir brancher mon propre monitoring. Concernant le gain apporté, je ne vous ai pas publié la propale ;) mais elle était suffisamment fourni sur ces aspects. Merci pour tes retours !
Merci à tous pour vos précisions et retours d'expériences !
@Hervé: Désolé, ce n'était pas l'objet de mon article, même si je comprends tout à fait l'intérêt que ca pourrait apporter... Qu'aurais tu répondu à ces questions ?
@all: Merci à tous pour vos retours d'expériences très intéressant !
A la question des commandes shell, j'aurai répondu ls et cd.
A la question "Qu'attendez vous de mon intervention ?", j'aurai répondu, avec tout autant de tact, "bah rien, c'était pas mon idée".
;)
Bonjour Olivier,
Je vais répondre :
1/ Quels OS
Linux (Debian) pour les serveurs de prod et Windows XP pour le développement
2/ Répartition des taches
* développement 75%
* tâches techniques 5%
* réunions 5%
* autres 5%
* coup d'oeil par la fenêtre et passages à la cafetière 10%
3/ Quelle est l'activité qui vous prend le plus de temps au quotidien ?
Me lamenter sur les mauvaises pratiques de mes collègues, maudire la programmation procédurale et éviter les médisances
4/ Les 3 logiciels les plus utilisés pour le développement
Eclipse PDT, Firefox et SVN
5/ L'utilité des applis Symfony
J'en fais pas ! ;-)
6/ Quelles sont vos douleurs actuellement pour mener à bien vos activités: ce qui vous fait perdre du temps en dev, en déploiement en prod...
Le manque d'analyse et de spec et d'une manière générale d'informations sur ce qu'il faut faire !
7/ Ou en êtes vous dans la roadmap produit (début, milieu, fin) ?
???
8/ Votre sentiment sur la qualité du produit (d'abord du service rendu à vos clients, ensuite du code) ?
Qualité du produit, moyen, qualité du service pas trop mal, qualité du code, nulle !
9/ Votre niveau de connaissance dans le framework Symfony:
-1, on ne fait que du Php pur et dur :-(
10/ Décrivez moi comment vous vous y prenez pour : corriger un bug détecté en production, développer une nouvelle fonctionnalité planifiée, fournir le même service à un nouveau client
Pour corriger un bug en production ... je cherche d'abord où peut se trouver le code incriminé ensuite l'auteur du bug.
Développer une nouvelle fonctionnalité, le plus dur c'est de comprendre ce que la personne chargée du contact avec le client à retenu et compris
11/ Quelles opérations à réaliser pour mettre en production (depuis un dev jusqu'à l'utilisation possible par un client en production ) ?
On recherche quelque chose déja développé, par la société, ou par d'autres, on copie/colle on livre sur un FTP et voilà cher client(e), c'est à vous de tester ... on en déduira ensuite ce que vous vouliez
12/ Donnez moi la liste des 5 ou 10 commandes en ligne de commande que vous utilisez le plus au quotidien
Jocker
13/ Quels sont les outils que vous avez envie d'utiliser et que n'utilisez pas encore ?
Un framework comme Symfony
14/ Quels sont les outils que vous ne voulez pas utiliser, ou que vous fuyez volontairement ?
IE6
15/ Si vous deviez utiliser un outil pour les tests unitaires ce serait ? OK pour utiliser PHPUnit pour les tests unitaires ?
Déjà qu'on passe à la POO, on verra ensuite
16/ Si vous deviez utiliser un outil pour le déploiement ce serait ? OK pour utiliser Phing pour le package et le déploiement, plutôt que les outils SF (trop liés à SF ?)
ANT
17/ Qu'attendez vous de mon intervention ?
Un nouveau boulot, je crois..
À essayer, à adopter et à ne plus jamais s'en passer : http://html2pdf.fr/
@Hervé: Merci Hervé d'avoir pris le temps de répondre, très intéressant, et relativement proche de ce que je "croise" au quotidien chez mes clients ;)
Pas mal le questionnaire Olivier !
On peut rapidement deviner "la moyenne" des réponses qui traduit nettement un manque de connaissances de la part de l'équipe globale du projet en ce qui concerne l'industrialisation (certains projets sont encore à 0% d'orienté objet !!)
Qu'en est-il sur des projets similaires en Java ou encore .Net, langages réputés beaucoup plus structurants? Je pense que c'est mieux, mais qu'on trouve tout de même des irréductibles non?
Le remède aux maux de la gestion de projets (au sens le plus large) PHP serait-il d'envoyer ses équipes faire un tour sur des projets Java/.Net ?
Je n'utilise pas phing avec PUC, car PUC(CC) intègre déja Ant, je ne vois pas trop l'interêt de remplacer Ant par Phing ?
Je serait curieux de savoir quel logiciel vous avez utilisé pour faire les schémas. Dia ou autre ?
Merci.
Bonjour,
Très intéressant !
Quel dommage que le coontenu ne soit pas proposé en PDF, tellement plus simple à conserver :-)
D'autre part, tu es formateur indépendant ? ou ???
PDFlatex est une solution très souple, à envisager si vous avez la main sur les paquets installés sur le serveur :)
Article intéressant...
Après être passée par fpdf, puis Zend_PDF (trop jeune à l'époque) puis Fop, j'utilise aujourd'hui Prince Xml (cf. http://www.alsacreations.com/articl...).
C'est un binaire qui convertit une page HTML en PDF (et qui respecte Acid2).
L'intérêt : une seule sortie HTML et 2 feuilles de style (une screen pour le navigateur et une print utilisée par princexml et/ou imprimante).
Par contre, ce n'est pas gratuit et nécessite d'avoir la main sur le serveur (en environnement Pro, pas de problème).
Je ne connais pas wkhtmltopdf.
Heu ... il manque un truc (d'après moi très très important..), à propos des performances?
Tous mes tests montrent bien que 100% procédure est presque 10fois plus rapide, moins de RAM... que la POO... Et en plus je trouve ça super con de finalement tendre vers la syntaxe Java alors que Php est la base un truc simple!
@Jonas: J'ai utilisé Powerpoint v2007 ;)
@jpauli: Phing étant écrit en PHP, il est 100% extensible en PHP (ce qui n'est pas le cas de Ant, qui nécessite Java). Ce qui permet de rapidement / facilement développer des tasks (classes) complémentaire pour rationnaliser certaines pratiques récurrentes dans les projets (mêmes internes). Dans mon cas, 80% des développeurs que je croise ne sont pas à l'aise avec Java, ca les rassure et les rend plus opérationnel d'utiliser un outil en PHP ;)
@Mike: mes clients peuvent recevoir la version originale Powerpoint ;) Je suis consultant expert et coach agile indépendant, je réalise des formations de temps en temps par l'intermédiaire de société partenaire, car je ne suis pas (encore) agréé pour ça.
@Tom: Bien entendu tu as raison le sujet de la performance est un sujet important qui montre souvent des différences entre l'usage procédural et la programmation objet. Cependant, j'ai l'impression que c'est beaucoup plus lié aux pratiques qu'à la mécanique interne, personnellement j'ai déjà vu des applis procédurale moins véloce que des applis utilisant le paradigme objet, cela dépend plutôt de l'architecture du code et de la façon de le charger. Ce qui est sûr cependant c'est que la programmation objet impose de nombreux artefacts complémentaires pour maîtriser la performance : gestion de l'autoloading, mise en cache, singleton, découpage en couche...
@all: En complément, je pourrais donner un retour d'expérience personnel : je me sers souvent du procédural pour "introduire" PHP chez mes clients novices, grâce à sa simplicité (syntaxe, algorithmique) cela permet petit à petit au client de se faire la main, et j'introduit dans un second temps la programmation objet, quand cela devient possible.
merci olivier pour la formation, je suis le developpeur de ton titre ;)
j'ai changé de boulot depuis, et dans ma nouvelle structure, hudson et eclipse sont utilisés, ta journée découverte m'a donc été fort utile.
Bonjour,
Pourriez-vous apporter des précisions sur la méthodologie pour obtenir ces métriques ?
En particulier les outils utilisés, si le code était homogène (par ex : positionnement des accolades)...
Plus je lis vos articles ,
plus je sent une petite dent contre l'utilisation des FW , ou plutôt une intention de tenter de faire prendre conscience de ce qu'implique l'utilisation d'un FW pour un projet X .
Si je peux donner mon avis , l'utilisation d'un framework communautaire tel que ZF ou Symphony n'apporte que trois avantages .
-> Eviter les formations des nouveaux arrivants , l'outil étant connu , il est facile de trouver un développeur ayant un minimum de connaissances sur le FW désiré .
-> Avoir à disposition une "communauté" en cas de problème lié à cet outil.
-> Avoir un suivi des failles / bugs
J'ai donc le même point de vue que vous sur l'utilisation d'un FW tel que le produit Zend ou Sensio Labs .
L'utilisation d'un framework fait "maison" sera tout aussi valable et performant , à partit du moment ou sa documentation clair et à jour est faite .
L'avantage selon moi d'utiliser un FW fait maison , est bien entendu d'avoir un contrôle total sur l'évolution de celui-ci , ce qui permet de le faire évoluer en faisant en sorte de rester compatible avec les projets existants , afin d'avoir un minimum de code à adapter .
Pour ce qui est de la sécurité , pour moi le plus gros risque ne vient pas du framework en lui même , mais bien du code que l'on écrit dans les controllers.
Voilà donc mon point de vue sur ce sujet .
Personnellement , j'utilise un FW fait maison ( en entreprise ) qui aujourd'hui a fait ses preuves , et qui me permet d'utiliser les ressources ( certaines libs ) d'autres FW comme le ZF , ce qui me permet de dire , que non la roue n'a pas été réinventée , mais nous restons maitre de l'évolution de la voiture ..
cdt ,
Ch.
Dans l'ensemble, je partage ton avis.
Cependant, lorsque le framework en question est du type "full stack" ou encore "super librairie", le développeur sera naturellement tenté et même guidé pour ne rien inventer du tout et ce jusqu'à la partie applicative. Tout est pré-mâché si je puis dire. Peut-on lui reprocher de suivre aveuglément les conventions et good practices dudit framework? Injecter du "custom code" (comprendre découplé au niveau de la librairie) sera au mieux un second framework dans le framework et au pire un calvaire de plus à appréhender pour les collègues (si tant est que l'individu a des collègues;)
Et si le problème sous-jacent était une question de compétence, tout simplement ? Maîtriser convenablement le langage, php en l'occurrence, ses idiomes et son domaine d'application me semble être l'élément primordiale pour ne pas se faire piéger par un framework, ou à contrario, en reconnaître les qualités.
@metagoto: merci pour ton point de vue très intéressant.
@stopher: merci pour ton retour d'expérience !
@Christophe: j'ai utilisé les outils habituels :PHPLoc, PHPCpd notamment, sans paramétrage particulier. En passant successivement ces outils sur certains répertoires du code (généré, développé, ....). Concernant l'homogénéité du code, je dirais qu'il s'agit d'un code "historique" (i.e. qui a évolué au cours du temps, de façon hétérogène en fonction des fichiers et des zones du code), c'est à dire quelque chose de "très" représentatif de mon point de vue dans un contexte d'entreprise ;)
Effectivement , les compétences dans le langage entrent en jeu .
Un développeur peu expérimenté ( ici en php ) se lance dans l'apprentissage et l'utilisation d'un framework les yeux fermés , car c'est le plus connu ou par effet de mode , ne me semble pas vraiment recommandé .
Le développeur en question fera un peu office de "presse boutons" .
Les FW aujourd'hui sont très complets , en terme de sécurité , de connectivité , de gestion de flux , d'affichage ect ..
Mais si aucune étude sur les rouages qui se cachent derrière , et sans avoir d'expérience au préalable , le jour ou il se retrouve sans l'outil magique et puissant qu'est le FW aujourd'hui ( tout du moins les plus grands ) , le développeur risque d'être perdu , bref de ne plus savoir coder correctement le moindre petit projet sans ce genre d'outil .
Maintenant , je reconnais qu'une personne qui utilise un FW aussi complet que le ZF , ou Symfony ( pour l'avoir utilisé ), possède tout de même un minimum de compétences pour savoir les utiliser et en tirer profit .
C'est peut-être (et certainement même) juste une crainte personnelle de voir les FW devenir une sorte de couche d'abstraction tel que le nouveau développeur développera et ne saura développer qu'à partir d'un FW , sans avoir de connaissances solides sur les mécanismes (de plus bas niveau donc ).
Ch.
Comme c'est bien exprimé :
"Et si le problème sous-jacent était une question de compétence, tout simplement ? Maîtriser convenablement le langage, php en l'occurrence, ses idiomes et son domaine d'application me semble être l'élément primordiale pour ne pas se faire piéger par un framework, ou à contrario, en reconnaître les qualités."
Je reprends Mère-Téresa et son quote, c'est si bien exprimé!
Le problème est là : il faut une **parfaite** maitrise de PHP5 pour faire joujou convenablement (comme tu le décris Olivier) avec un FW.
Il faut une **très bonne voire parfaite** maitrise du génie logiciel pour faire joujou convenablement avec un FW.
Sans l'un ou l'autre, le FW est une *tare* qui *ralentit* les projets voire même les fait* couler*.
Les gens n'ont pas compris ça, en majorité; ils n'ont pas compris que pour apprendre à conduire un bus, il faut savoir piloter parfaitement une voiture,
comme ils n'ont pas compris que l'informatique vue de haut ce sont des couches qui s'empilent comme un oignon: qui osera faire du PHP sans maitriser C ? Qui osera manipuler le FW XYZ sans maitriser PHP ?
Qui osera se pencher sur la couche de niveau N sans maitriser (ou au moins être très au courant) la couche N-1 ?
Ca mène à des catastrophes très souvent ;-)
Qu'entendez-vous par "R&D autour du produit Magento" ? Avez-vous participé au projet ?
Prévoyez-vous un billet sur vos "convictions sur le produit" ?
Merci de vos réponses.
"Je ne vous livre pas ici mes convictions sur le produits"
C'est fort dommage !
Voilà les miennes: http://www.desfrenes.com/blog/post/...
Quel outil as-tu utilisé pour générer un tel graphe ?
C'est très intéressant comme analyse, pour n'importe quelle application.
Les convictions, c'est que Magento est une usine à gaz ?
Bonjour, simple question d'ordre pratique : comment faire pour réaliser ce genre de graphe ? Merci
Moi je serais quand même curieux de connaître tes opinions sur ce produit, même si c'est par mail (tu la vois la perche ?) ;-)
@David: Dans le cadre d'une collaboration avec une société française spécialisé dans l'eCommerce et le développement "rapide" de sites eCommerce pour des marques, nous avons fait de la recherche et développement sur le produit Magento (version Community et Enterprise) pour mettre en oeuvre une démarche TDD (Test-First) permettant le développement piloté par les tests (unitaires) sous Magento. Dans ce cadre, nous avons du analyser le produit (techniquement) et comprendre le design, et les patterns / antipatterns d'architecture utilisé. Nous avons détecté un certains nombre d'anti-patterns. Je n'ai pas participé au projet Magento personnellement, mais j'ai *assez* bien compris la topologie du code ;)
@desfresnes,@metagoto,@herve: Je vois que mes "convictions" sur le produit vous intéressent ;) Ce n'était effectivement pas l'objet de mon post. Il est possible que j'écrive un article dans les prochains mois sur le sujet, même si je ne l'avais pas priorisé pour l'instant. Cependant, en résumé voici ce que je pense "magento est le meilleur progiciel d'eCommerce du marché sur le plan des fonctionnalités, de la communauté, de la facilité de mise en oeuvre notamment, par contre quand on ouvre le capot on comprend vite que beaucoup de principe d'architectures et de bonnes pratiques qui garantissent la pérennité et la maintenabilité du produit n'ont pas été mise en oeuvre". Je serais curieux de voir ce que sera devenu ce produit dans 2 ans, et surtout combien cela coutera à maintenir chez Varien. Je suis assez "interloqué" par la complexité technique interne... Le code n'est pas vraiment "lisible" pour un nom initié.
@nanomag,@herve: cela ne va pas vous plaire ;) : le logiciel utilisé est FreeMind + mon analyse statique "à la main" du code de bootstrap de Magento. Aucun logiciel automatisé n'a été utilisé pour réaliser ce schéma, d'un autre côté, il ne m'a pas fallu plus d'1h pour le réaliser, en suivant les différentes instructions en séquence.
Très bien ton outil. Quels paramètres as tu utilisé pour générer le diagramme de ZF? Merci.
Bonsoir,
En ce qui me concerne j'avais lu des commentaires sur sa capacité (ou pas justement) à tenir la charge dans le cas d'un catalogue produits assez étoffé.
Hervé
Malheureusement, la POO n'est pas accessible à tous.
Moi le premier, je n'arrive pas à appréhender la POO alors que le procédural ne me pose pas de souci de compréhension.
Mais développer n'est pas mon métier, juste un petit hobby pour réaliser de petits sites :)
Merci pour l'article Olivier, comme d'habitude c'est intéressant
J'utilise ArrayAccess quand j'ai besoins de l'interface compatible array, à laquelle s'ajoutent généralement Countable et un Iterator. C'est d'une banalité affligeante ;)
Le gros défaut est que php interdit de redéfinir une méthode avec une signature différente. On ne peut donc pas y injecter du type hinting, ou alors on le fait de manière détournée dans le corps de la méthode.
Par exemple un ORM. Une property modélise une relation 1-N vers des types T. Celle-ci expose un "ArrayAccess" pour que l'utilisateur puisse y ajouter des types uniquement compatibles avec T. Ce comportement ne serait pas possible si la property n'était qu'un simple array dans lequel on peut ajouter ce qu'on veut.
Tout à fait d'accord avec le post moins avec le commentaire de Julien :)
Heureusement que tous les développeurs PHP n'ont pas à maîtriser C sinon la communauté serait nettement réduite...
Sous drupal j'utilise la fonction t() pour traduire les chaînes de caractères.
Ex :
throw new Exception(t('Mon message'));
Au moins ça permet de regrouper toutes les traductions au même endroit.
le problème d'avoir juste un simple code numérique : le code source est moins lisible, et on a donc plus de mal à savoir quel est le message d'erreur, sans avoir aller chercher dans d'autres fichiers.
C'est pour ça que dans jelix, on a un compromis : on donne une clé alphanumerique, qui peut être beaucoup plus parlant qu'un simple nombre.
Par exemple,
throw new jException('jelix~errors.controller.class.unknown', $classname);
Et en fait, ça réutilise le système de localisation de jelix, qui se base sur un principe de clé->valeur plutôt que sur un truc du type de gettext.
J'ai tendance à utiliser le langage python pour ce genre de scripts batch ou directement des programmes en C++, surtout si ceux-ci doivent être utilisés fréquemment (penser tâches cron) et que le volume de données traitées est important.
Cela n'est pas forcément justifié, mais j'ai du mal à faire "confiance" à php pour tout ce qui est scripts d'utilité.
A un moment je me suis dit que HipHop for PHP allait me permettre de coder en php ce genre de programmes "batch" tout en ayant les avantages du C++ au runtime. Mais la taille des binaires générés est bien trop importante (il y a également d'autres inconvénients). J'ai abandonné l'idée ;)
D'expérience la plupart des plugins Symfony sont le plus souvent des wrappers autour de lbs existantes, ou alors exploitent directement et pleinement les fonctionnalités du coeur du framework (routing, request, response, templates, orm, etc.), ce qui n'est pas toujours évident ni forcément intéressant à découpler.
J'a très très rarement vu des libraires spécifiquement métier publiées sur la forge de plugins de Symfony, et je sais pas trop du coté des autres frameworks...
Très bon programme. Merci.
Par contre, peut-il créer un graph des dépendances des classes si ces dernières sont placées à plusieurs dans un même fichier ?
Je m'explique : j'ai plusieurs classes dans un même fichier .php. Exemple dans le fichier Page.php, j'ai une classe "class Page extends SiteTree" et une autre "class Page_Controller extends ContentController". Malheureusement, je ne parviens pas à obtenir les classes *Controller sur mon graph...
Merci d'avance pour votre aide.
Bonjour,
Je suis en train de faire ce type de manipulation avec du code un peu différent selon mon besoin.
Je rencontre un problème au niveau de la compression. j'utilise bien ZipArchive et je change l'extension de zip par pptx mais openOffice me demande de choisir un filtre pour l'ouvrir...chose qui n'arrive pas avec un fichier fais par PowerPoint et quand j'en choisi un il me fais une erreur. Dans l'archive il y a bien tous les dossiers et fichiers ! pourriez vous m'aidez s'il vous plait ?
Pareil que François, FPDF + FPDI. Importation d'un template en PDF, ajout des données dynamiques, et hop, un joli PDF
j'utilise ce système (ou des dérivés) depuis très très longtemps : http://www.glagla.org/weblog/2007/1...
bon, ben je ne pourrais que conseiller d'utiliser HTML2PDF http://html2pdf.fr/ étant donné que j'en suis le créateur :)
J'ai tendance à faire pareil sauf que je rajoute le typage :
@param array $tab : mon commentaire