Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

[PHP5]CLASSE DE TEMPLATE PHP AVEC CACHE


Information sur la source

Catégorie :Class et Objet ( POO ) Classé sous : classe, template, php, poo, cache Niveau : Initié Date de création : 17/06/2007 Date de mise à jour : 22/06/2007 22:17:38 Vu / téléchargé: 7 415 / 222

Note :
Aucune note

Commentaire sur cette source (27)
Ajouter un commentaire et/ou une note

Description

Bonjour,
je soumets à votre critique un moteur de template en PHP :
- aucune nouvelle synthaxe à apprendre ;
- aucun traitement supplémentaire ;
- gain de ressource ;
- séparation de la logique et de la présentation ;
- toute la flexibilité et la puissance de PHP peut etre utilisé ;
- ajout d'une simple variable ;
- ajout de plusieurs variables simultanément ;
- ajout de résultat d'une requête SQL ;
- boucle imbriqué illimité ;
- imbrication de template illimité ;
- gestion d'un système de cache pour optimiser l'affichage ;

Mais voilà, j'aimerai avoir votre avis afin de savoir s'il est réellement optimisé ou si on peut encore l'améliorer ;)
 

Source

  • <?php
  • class Template
  • {
  • private $path = null;
  • private $vars = array();
  • public function __construct($path = null)
  • {
  • if (isset($path))
  • {
  • $this->setPath($path);
  • }
  • }
  • public function setPath($path)
  • {
  • $path = trim($path, '/\\');
  • $path .= DIR_SEP;
  • if (!is_dir($path))
  • {
  • throw new Exception ('Chemin du dossier template incorrect : `' . $path . '`');
  • }
  • $this->path = $path;
  • }
  • function setVar($name, $value)
  • {
  • $this->vars[$name] = $value;
  • }
  • function setVars($vars, $clear = false)
  • {
  • if($clear === true)
  • {
  • $this->vars = $vars;
  • }
  • else
  • {
  • if(is_array($vars))
  • {
  • $this->vars = array_merge($this->vars, $vars);
  • }
  • }
  • }
  • function fetch($file)
  • {
  • extract($this->vars);
  • ob_start();
  • include($this->path . $file);
  • $contents = ob_get_contents();
  • ob_end_clean();
  • return $contents;
  • }
  • }
  • ?>
  • <?php
  • class Cache
  • {
  • private $path = null;
  • public function __construct($path = null)
  • {
  • if (isset($path))
  • {
  • $this->setPath($path);
  • }
  • }
  • public function setPath($path)
  • {
  • $path = trim($path, '/\\');
  • $path .= DIR_SEP;
  • if (!is_dir($path))
  • {
  • throw new Exception ('Chemin du dossier cache incorrect : `' . $path . '`');
  • }
  • $this->path = $path;
  • }
  • public function setCache($file, $contents)
  • {
  • $filename = $this->path . md5($file);
  • $contents = serialize($contents);
  • if (!file_put_contents($filename, $contents))
  • {
  • throw new Exception('Impossible de mettre en cache : `' . $file . '`');
  • }
  • }
  • public function getCache($file)
  • {
  • $filename = $this->path . md5($file);
  • if (file_exists($filename))
  • {
  • $contents = file_get_contents($filename);
  • $contents = unserialize($contents);
  • return $contents;
  • }
  • else
  • {
  • return false;
  • }
  • }
  • public function destroy($file)
  • {
  • $filename = $this->path . md5($file);
  • @unlink($filename);
  • }
  • }
  • ?>
<?php

class Template 
{
	private $path = null;
	private $vars = array();

	public function __construct($path = null)
	{
		if (isset($path))
		{
			$this->setPath($path);
		}
	}

	public function setPath($path)
	{
		$path  = trim($path, '/\\');
		$path .= DIR_SEP;

		if (!is_dir($path))
		{
			throw new Exception ('Chemin du dossier template incorrect : `' . $path . '`');
		}

		$this->path = $path;
	}
		
	function setVar($name, $value)
	{
		$this->vars[$name] = $value;
	}

	function setVars($vars, $clear = false)
	{
		if($clear === true)
		{
			$this->vars = $vars;
		}
		else
		{
			if(is_array($vars))
			{
				$this->vars = array_merge($this->vars, $vars);
			}
		}
	}

	function fetch($file)
	{
		extract($this->vars);
		
		ob_start();
		
		include($this->path . $file);
		
		$contents = ob_get_contents();
		
		ob_end_clean();
		
		return $contents;
	}
}

?>


<?php

class Cache
{
	private $path = null;
	
	public function __construct($path = null)
	{
		if (isset($path))
		{
			$this->setPath($path);
		}
	}
	
	public function setPath($path)
	{
		$path  = trim($path, '/\\');
		$path .= DIR_SEP;

		if (!is_dir($path))
		{
			throw new Exception ('Chemin du dossier cache incorrect : `' . $path . '`');
		}

		$this->path = $path;
	}
	
	public function setCache($file, $contents)
	{
		$filename = $this->path . md5($file);
		
		$contents = serialize($contents);
		
		if (!file_put_contents($filename, $contents))
		{
			throw new Exception('Impossible de mettre en cache : `' . $file . '`');
		}
	}
	
	public function getCache($file)
	{
		$filename = $this->path . md5($file);

		if (file_exists($filename))
		{
			$contents = file_get_contents($filename);
			$contents = unserialize($contents);
			return $contents;
		}
		else
		{
			return false;
		}
	}
	
	public function destroy($file)
	{
		$filename = $this->path . md5($file);
		@unlink($filename);
	}
}

?>

Conclusion

l'exemple :

Code : PHP

// inclusion de la classe template
require('includes/template.php');

// inclusion de la classe Cache
require('includes/cache.php');

// nouvelle instance de la classe Template
$tpl = new Template('templates');

// nouvelle instance de la classe Cache
$cache = new Cache ('cache');

// on assigne une simple variable 'bonjour'
$tpl->setVar('bonjour', 'Bonjour tout le monde !');

// on assigne plusieurs variable simultanément 'hello' et 'salut'
$bonjour = array('hello' => 'hello tout le monde !', 'salut' => 'salut tous le monde !');
$tpl->setVars($bonjour);

// supposons que l'array $user_list provienne d'une base de donnée...
// pour eviter d'utiliser des ressources inutilement, on va mettre
// en cache le résultat de la requête

// les résutats sont-ils en cache ? si oui on les
// récupère à partir du fichier et non de la requête
if (!$user_list = $cache->getCache('user_list'))
{
// mysql_connect, ETC...
$user_list = array(
1 => array(
  'id' => 1,
  'nom' => 'jean'),
2 => array(
  'id' => 2,
  'nom' => 'vincent'),
3 => array(
  'id' => 3,
  'nom' => 'maxime')
  );
// on met en cache le résultat
$cache->setCache('user_list', $user_list);
}

// on l'assigne comme variable 'user_list'...
$tpl->setVar('user_list', $user_list);

// on compile le template user_list
$user_list_render = $tpl->fetch('user_list.php');

// et on l'assigne comme variable user_list_render...
$tpl->setVar('user_list_render', $user_list_render);

// on affiche la page entière
echo $tpl->fetch('exemple.php');


l'exemple (exemple.php) :


Code : PHP

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Exemple de la classe template</title>
</head>

<body>
<?php echo $bonjour; ?>
<br />
<?php echo $hello; ?>
<br />
<?php echo $salut ?>
<br />
<?php echo $user_list_render; ?>
</body>
</html>


l'exemple (user_list.php) :


Code : PHP

<table>
  <tr>
    <th>Id</th>
    <th>Nom</th>
  </tr>
  <?php foreach($user_list as $user): ?>
  <tr>
    <td><?php echo $user['id'];?></td>
    <td><?php echo $user['nom'];?></td>
  </tr>
  <?php endforeach; ?>
</table>

On aurait pu aussi mettre en cache la page entière, mais vous avez compris le fonctionnement...
L'intérêt d'un tel système de cache et de permettre de générer par exemple un fichier XML à partir des résultats mis en cache par exemple.

!!! ATTENTION !!!

Le cache n'a pas de durée de vie, pour le mettre à jour :

Lors d'une requête d'ajout (vos pages de post/edition de messages, de news, etc.) inclure :

$cache->destroy('nom_du_fichier_ou_vous_avez_mis_le_cache);
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

22 juin 2007 22:17:38 :
- Séparation de la classe de template et cache pour une meilleur gestion des données (la classe cache permet de mettre en cache tout type de donnée et pas seulement un fichier template, comme par exemple uniquement les résultats d'une requête SQL pour un traitement différent (fil RSS) ; - Ajout d'une méthode setter ; - Remplacement des shorts tags par les tags <?php et ?> ;

Commentaires et avis

signaler à un administrateur
Commentaire de coucou747 le 17/06/2007 19:01:32

<? c'est pas une syntaxe utilisable sur les serveurs qui ont du xml, c'est obsolete, on doit mettre <?php echo..

signaler à un administrateur
Commentaire de hametsu21 le 17/06/2007 20:08:14

Mais sinon, tu vois aucun code qui te chagrine, tu ne vois pas comment l'optimiser ? Rendre la classe plus efficace ?

Merci :)

signaler à un administrateur
Commentaire de webdeb le 17/06/2007 22:02:25

Ce qui me chagrine surtout ce sont les attributs publics qui sont largement déconseillés. Pourquoi ne les mets-tu private ? Tu fais un setter() pour mettre sa valeur à jour. D'ailleurs tu pourrais plutôt définir le template de cette manière :

<?php

$tpl = new Template('monTemplate.tpl');

?>

Sinon je plussoie Coucou747 par rapport aux tags que tu utilises.

++

signaler à un administrateur
Commentaire de coucou747 le 17/06/2007 22:13:08

dire que l'imbrication de template est illimitee avec un systeme comme :
$user_list_render = $tpl->render('user_list.php');
$tpl->setVar('user_list_render', $user_list_render);

c'est tres "j'ai pas code la fonctionalite, j'ai pose du scotch, et ca tient, si ca tombe, je poserais une agraphe"...

enfin on aurait pu penser a un tag genre {template "machin.tpl"} avec des options genre pour un resultat de requette : {template "machin.tpl" requetteNom -All} ou {template "machin.tpl" requetteNom -Limit 1 to 10} voir encore {template "machin.tpl" requetteNom -Once}
et des variables genre {variable ici}
ou une combinaison : {template "machin_{variable}.tpl" requetteNom -Once}

signaler à un administrateur
Commentaire de hametsu21 le 18/06/2007 09:35:45

"La perfection est atteinte, non pas lorsqu'il n'y a plus rien à ajouter, mais lorsqu'il n'y a plus rien à retirer."
Antoine de Saint-Exupéry.

Pourquoi rajouter un setter alors qu'avec l'attribut public, nous pouvons accéder au variable de la session ? Surtout que c'est pas comme si c'était un identifiant de base de donnée ou tout autre variable critique...

Pourquoi rajouter un système de pseudo language, le but est d'utiliser le moins possible de ressources, de codes, de méthodes... Actuellement, l'imbrication est effectivement illimité et je ne vois pas le rapport avec "j'ai pas code la fonctionalite, j'ai pose du scotch, et ca tient, si ca tombe, je poserais une agraphe". D'ailleurs, les requêtes ne doivent pas être executer par la Vue mais par le ModelDAO... j'aime bien séparé les différentes choses...

A+

signaler à un administrateur
Commentaire de coucou747 le 18/06/2007 12:43:43

tu inseres une template comme une variable, c'est ca que je veux dire, t'as rien pour l'inserer comme ca avant, et inserer les variables une seule fois pour toute les templates... du coup, c'est normal que ca marche, meme si t'as rien fait pour...

signaler à un administrateur
Commentaire de hametsu21 le 18/06/2007 13:15:05

Oui, en effet, mais vu que ça marche par un système simple, pourquoi mettre en place un système compliqué :D ?

signaler à un administrateur
Commentaire de coucou747 le 18/06/2007 13:20:41

je vais suivre ton raisonement : utiliser echo directement, ca marche tres bien, et c'est imbatable en perfs, pourquoi se faire chier avec autre chose ?

utiliser un truc complique avec d'autres balises, ca fait un systeme plus souple, plus propre, plus modifiable, etc...

signaler à un administrateur
Commentaire de hametsu21 le 18/06/2007 13:52:06

Oui et Non, car dans ce cas on se limiterait à nos simple méthodes et non à celle d'orgine dans PHP, car il faudrait rajouter plusieurs méthodes et ce n'est pas mon but.

signaler à un administrateur
Commentaire de coucou747 le 18/06/2007 14:25:24

ton but c'etait quoi ? faire un truc simple et concis pour remplacer echo mais sans rien apporter de plus ?

signaler à un administrateur
Commentaire de hametsu21 le 18/06/2007 15:09:31

Séparer la logique de la présentation sans utiliser de moteur de template avec des pseudos languages et des tonnes de méthodes pour aboutir au même résultat tout en réduisant le temps d'éxecution d'une page.
Avec cette classe il est possible de gérer un système de thème et de mettre en cache.
Je ne vois pas en quoi je "remplace" echo(), si j'aurais voulus remplacer echo(), j'aurais utiliser print() :)

signaler à un administrateur
Commentaire de webdeb le 19/06/2007 00:07:36

>> Pourquoi rajouter un setter alors qu'avec l'attribut public, nous pouvons accéder au variable de la session ? Surtout que c'est pas comme si c'était un identifiant de base de donnée ou tout autre variable critique...

Une classe se définit ainsi : 1 nom,  des données membres (attributs), 1 constructeur et des méthodes. Quand tu définis une classe, tu modélises un objet. Cet objet a ses propres propriétés (attributs) et ses propres actions (méthodes). En déclarant tes attributs privés, tu forces la visibilité et l'accès à ces derniers par l'objet lui même. Seul l'objet doit pouvoir mettre à jour ses données membres via l'utilisation de setter(). Je prends un exemple métaphorique, peut-être peu approprié mais qui illustre ce principe.

Prends un être humain. Le+ corps humain est composé d'organes (ses attributs) et est capable d'agir (courrir, respirer, marcher, réfléchir). On visualise donc ici une modélisation schématique du corps humain composé d'attributs et de méthodes. Admettons que le corps humain d'une personne tombe malade. Le foie (attribut) est touché par une hépatite C. Comment le guérir ? Solution pour le patient : il doit avaler différents médicaments. Dans ce cas, cela signifie que seul lui même peut se guérir en avalant un médicament. Il appelle donc l'action avalerMedicament() qui va mettre à jour l'état de son foie mais il ne peut pas appliquer directement $corpsHumain->foie = 'truc'

J'essaie de montrer par cet exemple un peu tiré par les cheveux, l'intérêt d'utiliser des setters pour mettre à jour les attributs d'une classe.

++

signaler à un administrateur
Commentaire de coucou747 le 19/06/2007 00:12:34

c'est pas si capilotracte que ca, en general, moi pour explique de l'objet, j'imagine un chat, je compte ses pates et je l'epille...

signaler à un administrateur
Commentaire de Alain Proviste le 19/06/2007 06:00:46 administrateur CS

moi jsuis plutot classification...
animaux mamiferes etc.

signaler à un administrateur
Commentaire de hametsu21 le 19/06/2007 08:30:44

Webdev, j'avais pas vu ça comme çà :D et tu as raisons ;) Merci pour l'exemple ;)
L'utilisation d'un setter aide pour la mise en place d'un poka-yoké (http://www.nexen.net/articles/dossier/15024-le_filtrage_poka-yoke.php). Une mise à jour s'impose ;p

signaler à un administrateur
Commentaire de webdeb le 19/06/2007 09:30:54

Chacun sa méthode ^^ Je plains les chats par contre... Je vais te dénoncer à la SPA et à l'association Brigitte Bardot Coucou747 ^^

signaler à un administrateur
Commentaire de Renfield le 19/06/2007 09:36:47 administrateur CS

a chaque fois qu'il épile pas les chats, étrangement, Lara Fabian sort un disuqe peu de temps après...

à bien écouter, remarques, on comprend un peu mieux ^^

signaler à un administrateur
Commentaire de FhX le 20/06/2007 16:15:08

Heu.... :o

"Une classe se définit ainsi : 1 nom,  des données membres (attributs), 1 constructeur et des méthodes."
Pour ca, on est tous d'accord. On peut rajouter quelques trucs, mais la base y est.

"Il appelle donc l'action avalerMedicament() qui va mettre à jour l'état de son foie mais il ne peut pas appliquer directement $corpsHumain->foie = 'truc'"
Pourquoi ? Parce que ta méthode avalerMedicament fait appel à d'autres procédés avant d'arriver à une purification de ton foie. Voila pourquoi ta propriété foie doit être privé/protégé dans ce cas précis.
Maintenant, jouons la autrement.

Notre foie est toujours malade. Mais nous allons ajouter une propriété "auto_soin_foie" qu'on va mettre à vrai.
Hors, pour une raison X ou Y, on se retrouve avec : $corpsHumain->auto_soin_foie = false;

Mais de toute facon, que la réparation du foie soit automatique ou non, on va faire avaleMedicament().

Ici, auto_soin_foie n'a pas besoin d'être privé, car, bien que son comportement influe sur l'instance, il n'est pas nécessaire de faire un controle strict dessus.
Pas la peine de faire :
public function setAutoSoin($var) {
  $this->auto_soin_foie = (bool) $var;
}
public function getAutoSoin() {
  return $this->auto_soin_foie;
}

La par exemple, le privé/protégé ne sert à rien.
Si tu me dis "nan on ne controle pas ce qui rentre..." bien sur que si, c'est du vrai/faux. Et regarde, si je jète un oeil à ma méthode avaleMedicament(), j'ai ca :
if ( (bool) $this->auto_soin_foie ) {
      //
} else {
      //
}

J'ai réglé tout mes problèmes.


Pour un traitement de nombres/chaines/objets/flottants etc... tu peux/doit passer par du get/set, surtout à cause du set.
Pour un traitement en booléan, bof bof :)

signaler à un administrateur
Commentaire de bonsai le 25/06/2007 10:17:40

Hello tous,

En fait les get/set ont d'autres raisons d'être systématiques; par exemple, quand on met à jour la valeur d'un attribut, il peut y avoir d'autres choses à faire (test de valeurs limites, autre(s) attribut(s) à modifier, etc.). Si ce n'est pas le cas, rien ne dit que les évolutions de l'application ou de l'objet n'amèneront pas ces contraintes. Si on n'a pas mis les get/set, il faut modifier tout le code qui modifie les attributs publiques...

Enfin, la philosophie objet (en tous les cas tel que je la perçois) dit que l'on doit utiliser un objet comme une boite noire, donc que l'on n'a pas savoir ce qui se passe dedans, donc les attributs en private et des get/Set.

signaler à un administrateur
Commentaire de webdeb le 25/06/2007 11:25:22

Je suis aussi de ton avis Bonsai :)

signaler à un administrateur
Commentaire de hametsu21 le 25/06/2007 12:43:58

Et à par ce petit débat fort sympathique, avez-vous des suggestions sur les classes (mises à jour) ?

signaler à un administrateur
Commentaire de coucou747 le 25/06/2007 12:56:07

les classes en general, ou dans ton projet ?

en general, disons que moi, ce qui me manque terriblement, c'est la surcharge d'operateurs, et les namespaces.

pour ton projet, je crois que tout a ete dit

signaler à un administrateur
Commentaire de FhX le 25/06/2007 14:45:35

"Si ce n'est pas le cas, rien ne dit que les évolutions de l'application ou de l'objet n'amèneront pas ces contraintes."

Si on utilise les propriétés publiques, on se doute bien qu'au final il n'y aura pas d'évolution dans ce domaine. Je m'explique.
Prenons le cas d'une propriété de débug. Pas besoin de get/set pour du débug, on s'en carre le cornichon :)
Même si il y a évolution du projet derrière :

class x {
public $debug = false;
//
}
class y extends x {
//
}

$y = new y;
$y->debug = true;

Bon et voila :)
Dans ce cas la, le "public" fonctionne très bien et tu n'as pas besoin de faire :
$y->setDebug(true); ou $y->ActiveDebug();
C'est une perte de temps :o

Comme dit Coucou, ce qui manque, c'est la redéclaration des méthodes. Rien de plus beau (comme en Java) de faire :
public function __construct($var);
public function __construct($var, $truc);
public function __construct(Object $x, Object $y);
Sans avoir à se faire chier avec func_*() et autre fonction de ce genre.
Le namespace, tu peux y arriver via le statissisme :
class x {
static public function x1();
}

x::x1();
Et tu peux très bien arriver à un résultat de ce genre :
x::x1()->...()->...->...::...()->...();
Techniquement, je crois que ca passe.

Pour en revenir plus, chacun est libre de faire comme il veut.
Pour ma part, c'est simple :
abstract class Item {
public $debug = false;
}
abstract class Factory extends Item {
//
}
abstract class Element extends Item {
//
}
class NewsFactory extends Factory {
//
}
class News extends Element {
//
}

Pas besoin de m'ennuyer avec des méthodes qui servent à rien :)

signaler à un administrateur
Commentaire de coucou747 le 25/06/2007 14:56:00

et mettre une classe dans un namespace ? :)

je ne parlais pas seulement de l'overloading de functions, mais aussi d'operator, faire :
$a=new Vector(1, 3, 5);
$b=new Vector(5, 3, 1);
$c=$a+$b;
comme on peut le faire en Cpp... moi ca me manque (d'autant plus que j'ai fait quelques classes lignes pour positionner des points en "live")

signaler à un administrateur
Commentaire de FhX le 25/06/2007 15:56:37

En effet, ca manque aussi.
D'après ce que j'ai lu, il semblerait que ce soit pour PHP6.

Peut être :)

signaler à un administrateur
Commentaire de hametsu21 le 25/06/2007 20:54:31

j'ai pas trop compris vos recommendations. Sont-elles de l'ordre générale sur PHP et ses possibilités en POO ou de la source ?

signaler à un administrateur
Commentaire de FhX le 26/06/2007 08:53:24

Je parlais du public/private au départ, mais avec Coucou on parlait du manque niveau POO :)

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

cache du navigateur [ par booth ] c'est encore moa....Désolé mais j'ai un projet à terminer dans peu de temps alors...J'ai pas trouvé le moyen de forcer le navigateur (et le proxy pend probleme de classe en php [ par Elkaire ] Donc voila mon probleme!!dans une premiere page je rensegne les insances de mon objet. Une fois renseigné je peux réutiliser les instances cet objet d Vider le cache de l'explorer en programmation Php ou JS [ par Cr0w ] Bonjour,J'aimerai savoir si il existe une fonction en Php ou JavaScript permettant de vider le cache de l'explorer.En effet, j'ai conçu dans le cadre Pb avec classe en php, Affichage [ par matou82 ] Je voudrais savoir comment surcharger l'affichage d' echo ou print pour une classePour avoir:$obj = new Maclass;echo $obj;Cela affiche : "Object" Je s cache limiter [ par brok ] quand j'appelle ma page page.php, je recoit le message d'erreur suivant:Warning: Cannot send session cache limiter - headers already sent (output star php, classe COM et excel [ par Faboun ] bonjour,Voici mon problème j'vais développé un script qui a partir dune bd mysql me permettait de générer un fichier xls, puis de l enregistrer sur mo classe PHP pour accés BDD [ par cuicui ] Bonjour,Je recherche des classes en PHP qui perùet d'acceder à des des bases de données tel que INTERBASE ou MySQL.Merci à touscuicui... classes et sessions [ par davwart ] Hello all,là je desespere..voial j'ai deux fichiers.fichier1: classe.inc.php&lt;?phpclass User{}?&gt;fichier2: index.php&lt;?phpinclude("classe.inc.ph AIDE - Classe en php 5 [ par el_pecheur ] J'ai besoin d'un gros coup de main ... J'ai trouver un logiciel http://uml2php5.zpmag.com/windows.php qui permet de donner le code d'une classe en ph PHP - classe [ par missceline33 ] Bonjour &#224; tous, j'ai un probl&#232;me avec mes classes PHP. Je voudrais d&#233;finir plusieurs constructeurs &#224; ma classe mais quand je rajou


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Comparez les prix Nouvelle version


LG KP501

Entre 9€ et 159€


Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,406 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.