Grummfy on mars 25th, 2010

Pour une fois, un article sous Ms Windows. Stage oblige, je passe du temps sous celui-ci (XP :( ). Afin d’optimiser son travail, il y a parfois des petites choses bien pratiques, telles que ce que je vais vous présenter.

XDebug est un outil merveilleux, parfois capricieux, certes, mais très utile. Il permet, notamment1 :

  • Affichage de tracé d’erreur
  • Meilleures lectures des exceptions
  • Débogage pas-à-pas
  • Profiling d’application

Bref, des choses essentielles en développement. Et, contrairement à ce que certains IDE2 font, il permet surtout de le faire sur un serveur « réel », donc avec une utilisation « réel ».

Le but de ce billet n’est pas de présenter XDebug, d’autres le font mieux que moi 3, mais bien de vous présenter un petit script vous permettant d’activer et désactiver XDebug sur wampserver.

Installation

  1. Téléchargez le fichier 4 et décompressez-le.
  2. Suivez les instructions d’installation décrite dans le fichier installe. Il y a seulement 1 fichier à modifier + 1 fichier par version de PHP installée.
  3. Relancer wampserver et tester!

Si vous avez des questions, n’hésitez pas.

Plus d’informations

  1. On parle de serveur web avec PHP …
  2. Par exemple, Zend Studio permet un débogage pas à pas mais en interne donc réduit …
  3. cf. plus d’informations
  4. XDebug quick switch menu for wampserver
  • Delicious
  • Technorati Favorites
  • Twitter
  • Facebook
  • Google Bookmarks
  • Netvibes Share
  • Share/Bookmark

Tags : , , , , , , , ,

Grummfy on mars 23rd, 2010

La vitesse d’affichage d’une page web est actuellement, et ce depuis un certain temps, devenu importante. Surtout en ce qui concerne l’optimisation et par conséquent le référencement. Afin de gagner ces quelques millisecondes qui feront la différence, il existe plusieurs méthodes et techniques. En voici quelques-unes, avec des exemples.

Diminuer le nombre de requêtes HTTP

Chaque requête HTTP au sein du fichier prend un certain temps, mais surtout bloque le chargement global de la page web. En effet, HTTP et HTML chargent les ressources au fur et à mesure que la page le demande.

Lire le reste de l’article »

  • Delicious
  • Technorati Favorites
  • Twitter
  • Facebook
  • Google Bookmarks
  • Netvibes Share
  • Share/Bookmark

Tags : , , , , , ,

Grummfy on mars 20th, 2010

Mon blog va évoluer d’ici quelques mois, des changements sont en perspectives.

Tout d’abord, passons en revue les sujets qui seront abordés. Encore et toujours Zend Framework, je compte continuer de publier. C’est un sujet qui m’intéresse et qui je trouve est très intéressant. Par ailleurs, je compte faire une série d’articles sur CMIS. Si vous ignorez ce que c’est … alors tant mieux!
En dehors de ces sujets principaux, seront aussi abordés des projets. Dans ceux-ci on pourra citer principalement deux choses : FSB dont le développement va reprendre (enfin …) et des projets sous Android.

Bref, des choses intéressantes et alléchantes, mais ce n’est pas tout! Je compte faire du nettoyage. Hé oui, le printemps arrive, les oiseaux chantent, et certains sortes les balais et les caisses pour le « nettoyage de printemps », ce sera donc mon cas. Depuis trop longtemps, je remet a plus tard de me faire un vrai site avec un contenu qui me correspondent et non des « machins » accumulés et qui date …

Donc :

  • des projets a réalisé
  • des sujets à aborder
  • un site renouvelé

Voilà le programme!

Mais aussi, et c’est une idée qui me trotte dans la tête depuis longtemps, éventuellement un nouveau blog ou site consacré à la cuisine.

Vous avez le menu, reste à savoir si le chef sera dans les temps.

  • Delicious
  • Technorati Favorites
  • Twitter
  • Facebook
  • Google Bookmarks
  • Netvibes Share
  • Share/Bookmark

Tags : , , , ,

Un script PHP en ligne de commande pour activer // désactiver le wifi sur un modem D-Link DSL-2640B. Cela permet d’illustrer un peu l’intérêt de faire du scripting …

Je ne ferais pas de commentaires, mais n’hésitez pas à poser des questions …

#!/usr/bin/php
<?php
 
//Variable definition
//
//router
$login = 'admin';
$password = 'admin';
$ip = '192.168.1.1';
 
//
//wifi
$wifi = array(
	// /!\ don't touch this /!\
	'wlSsidIdx'	=> 0,
	'wlEnbl'	=> 1,
	'wlCountry'	=> 'GB',
	'wlBasicRate'	=> '',
 
	//ssid name
	'wlSsid'	=> 'monSuperRéseauxWifi',
	//0 = visible, 1 = hide
	'wlHide'	=> 0,
	//number of chanel or 0 for auto selection
	'wlChannel'	=> 1,
	//Transmission Speed
	'wlRate'	=> 0,
	//wifi mode 0=802.11b only, 1=Mixed 802.11g and 802.11b, 4=802.11g only
	'wlgMode'	=> 4,
 
	'wlWpaGTKRekey'	=> 750,
	'wlWpa'			=> 'aes',
	'wlAuthMode'	=> 'psk2',
	//authentification mode : 0 = none, 1 = wep, 2 = auto (wpa or wpa2), 3 = wpa2 only, 4 = wpa only
	'wlAuth'	=> 0,
	'wlWpaPsk'	=> 'masuperclefdelamortquitue',
	'wlWep'		=> 'disabled',
	'wlPreauth'	=> 0
);
 
/////////////////////
 
class cli
{
	const LINE_BREAK = "\r\n";
	const LINE_NO_BREAK = '';
	const LINE_RETURN = "\r";
	const LINE_NOTHING = ' ';
 
	protected $_TEMP = 250000;//1/4 of seconds
	protected $_MULTIPLICATOR = 4; //1/4 -> 4
 
	protected $_LENGTH = 60;
 
	protected function _write_empty_space($lng)
	{
		while($lng < $this->_LENGTH)
		{
			echo ' ';
			$lng++;
		}
	}
 
	protected function _echo($message, $break)
	{
		echo $message, $break;
		if ($break == self::LINE_NO_BREAK)
		{
			$this->_write_empty_space(strlen($message));
		}
	}
 
	protected function _sleep($second)
	{
		$second = $second * $this->_MULTIPLICATOR;
		$i = 0;
		$j = 0;
		while ($i < $second)
		{
			usleep($this->_TEMP);
 
			if ($i % 4)
			{
				$this->_echo('.', self::LINE_NOTHING);
				$i++;
			}
			else
			{
				if($j % 2)
				{
					$this->_echo('', self::LINE_RETURN);
					$this->_write_empty_space(0);
					$this->_echo('', self::LINE_RETURN);
				}
				else
				{
					$this->_echo('Please wait', self::LINE_NOTHING);
					$i++;
				}
				$j++;
			}
		}
		$this->_echo('', self::LINE_RETURN);
	}
}
 
class wifi extends cli
{
	protected $_ch;
	protected $_baseUrl;
 
	public function __construct($wifi, $ip, $login, $password, $activation)
	{
		$this->_baseUrl = 'http://' . $ip . '/';
 
		$this->_ch = curl_init();
		curl_setopt($this->_ch, CURLOPT_HEADER, false);
		curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, true);
 
		$this->_auth($login, $password);
 
		$activation = intval($activation);
 
		if ($activation == 1)
		{
			$this->_activation($wifi);
		}
		else
		{
			$this->_disactivation($wifi);
		}
	}
 
	public function __destruct()
	{
		curl_close($this->_ch);
	}
 
	protected function _activation($wifi)
	{
		$this->_echo('Activation ...', self::LINE_NO_BREAK);
 
		$wifi['wlBasicRate'] = ($wifi['wlgMode'] == 4) ? 'wifi2' : 'default';
 
		$this->_doQuery($this->_baseUrl . 'wirelesssetting.wl?' . http_build_query($wifi, '', '&'));
		$this->_sleep(5);
	}
 
	protected function _disactivation($wifi)
	{
		$this->_echo('Disactivation ...', self::LINE_NO_BREAK);
 
		$wifiDown = array(
			'wlEnbl'	=> 0,
			'wlSsidIdx'	=> $wifi['wlSsidIdx'],
			'wlCountry'	=> $wifi['wlCountry'],
		);
 
		$this->_doQuery($this->_baseUrl . 'wirelesssetting.wl?' . http_build_query($wifiDown, '', '&'));
		$this->_sleep(5);
	}
 
	protected function _doQuery($url, $post = '')
	{
		curl_setopt($this->_ch, CURLOPT_URL, $url);
 
		if (!empty($post))
		{
			curl_setopt($this->_ch, CURLOPT_POST, true);
			curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $post);
		}
		else
		{
			curl_setopt($this->_ch, CURLOPT_HTTPGET, true);
		}
 
		if(curl_exec($this->_ch) === false)
		{
			$this->_echo('', self::LINE_BREAK);
			$this->_echo('Error Curl : ' . curl_error($this->ch), self::LINE_BREAK);
		}
		else
		{
			$this->_echo('DONE', self::LINE_BREAK);
		}
	}
 
	protected function _auth($login, $password)
	{
		$this->_echo('Authentification ...', self::LINE_NO_BREAK);
 
		$post = array(
			'username'	=> $login,
			'password'	=> $password
		);
 
		$this->_doQuery($this->_baseUrl . 'index.html', http_build_query($post, '', '&'));
	}
}
 
if ($argc != 2)
{
	echo ' synthaxe : scriptname.php 1 for activation or 0 for desactivation ';
	exit();
}
 
new wifi($wifi, $ip, $login, $password, $argv[1]);
 
# EOF

Certes, le script ne gère pas tout, mais le but était de jouer avec la ligne de commande tout en n’allant pas dans les extensions exotiques de gestion de celle-ci ….

  • Delicious
  • Technorati Favorites
  • Twitter
  • Facebook
  • Google Bookmarks
  • Netvibes Share
  • Share/Bookmark

Tags : , , , , ,

Grummfy on janvier 21st, 2010

Un planet sur Zend Framework, pour les francophones est née!

Tout d’abord qu’est-ce qu’un planet?
Un planet est un agrégateur de flux rss concernant un même sujet. Le but est de promouvoir mais surtout de concentrer les articles publié sur le sujet.

Pour ceux qui désirerait y goûter, je vous renvoi vers le site : zf planet

N’hésitez pas à demander a en faire partie.

  • Delicious
  • Technorati Favorites
  • Twitter
  • Facebook
  • Google Bookmarks
  • Netvibes Share
  • Share/Bookmark

Tags : , ,

Grummfy on janvier 10th, 2010

Dans la plupart des cas lorsque l’on affiche un listing provenant d’une requête sql on aimerait pouvoir offrir le tri à l’utilisateur. Dans l’article qui suit, je vous propose de découvrir une manière de le faire assez facilement.

Lire le reste de l’article »

  • Delicious
  • Technorati Favorites
  • Twitter
  • Facebook
  • Google Bookmarks
  • Netvibes Share
  • Share/Bookmark

Tags : , ,

Grummfy on janvier 2nd, 2010

Ceci est une note rapide … j’espère produire un article plus intéressant une autre fois …

Nous allons regarder les bases de l’auto-complétion  avec ZF et Dojo. Dojo simplement parce qu’il est le mieux intégré des frameworks javascript. Sachant que pour l’instant seul jQuery et Dojo sont intégré

Le code

application/views/scripts/test/index.phtml

<?php
$this->dojo()->enable();	//activation de dojo
 
echo $this->comboBox(
	'toto',	//id html de l'élément
	'',	//valeur par défaut
	array(
		'autocomplete'	=> true,								//activation de l'auto-complétion
		'store'		=> 'stateStore',
		'storeType'		=> 'dojo.data.ItemFileReadStore',
		'storeParams'	=> array('url' => $this->baseUrl('/test/records')),	//url où les données JSON sont récupérée
		'searchAttr'		=> 'title',								//donnée recherchée pour remplir le combobox
	)
);
?>

application/layoutes/scripts/layout.phtml

// ...
		if ($this->dojo()->isEnabled())	//Évite les chargement inutile ....
		{
			$this->dojo()->setDjConfigOption('isDebug', (APPLICATION_ENV == 'development'));	//affiche une console de deboguage si on est en mode dev
			$this->dojo()->setDjConfigOption('usePlainJson', true);						//utilise du json texte
			$this->dojo()->setLocalPath($this->baseUrl('/themes/js/dojo/dojo/dojo.js'));			//chemin vers les fichier dojo
			$this->dojo()->addStyleSheetModule('dijit.themes.tundra');					//thème à chargé
			echo $this->dojo();												//affichage du tout ...
		}
// viennent ensuite nos jabvascript, css, etc
//...
//</head>
// ne pas oublier la class tundra dans le body
<body class="tundra">
//...

application/Bootstrap.php

//...
//dans _initView()
		//dojo
		Zend_Dojo::enableView($view);
//...

application/controllers/TestController.php

<?php
 
class TestController extends Zend_Controller_Action
{
	public function indexAction()
	{
	}
 
	public function recordsAction()
	{
		// on désactive l'affichage
		$this->_helper->layout()->disableLayout();
 
		//on va cherchée les données et les met dans un objet Zend_Dojo_Data
		$book = new Default_Model_DbTable_Book();
		$dojo = new Zend_Dojo_Data('title', $book->fetchAll());
		echo $dojo->toJson();
 
		// on sort ... c'est pas joli mais en attendant cela fonctionne!
		exit();
	}
}
 
# EOF

Choses à retenir comprendre

Les choses à retenir :

  • storeParams est l’url où les donnée au format JSON seront prise
  • searchAttr est l’élément qui va servir pour recherchée les données dans la masse de donnée JSON
  • ne pas oublier de mettre la class css ‘tundra’
  • Dojo peut, via ses styles css modifier votre rendu …

Remarque

Version de ZF : 1.9.6

Version de Dojo (fourni avec zf dans extras) : 1.3

  • Delicious
  • Technorati Favorites
  • Twitter
  • Facebook
  • Google Bookmarks
  • Netvibes Share
  • Share/Bookmark

Tags : , , , , ,

Grummfy on décembre 30th, 2009

Il y a des moment où l’on se dit que la doc est vraiment incomplète … Voici un exemple assez tordu…

Rappel

  • L’aide de vue (view helper)  cycle permet d’alterner des valeurs dans la vue,
  • L’aide de vue partialLoop permet de faire une boucle sur une vue (fichier) afin de l’incorporer dans un autre fichier…

Utilisation

Pour utiliser les deux ensembles, par exemple dans le cas d’un listing dont la sortie serait dans un tableau, il vous suffit de définir les valeurs assigner au cycle avant de faire le partialLoop.
Exemple :
Vue views/scripts/membres/listing.phtml

<table class="table">
	<thead>
		<tr>
			<th>Nom</th>
			<th>Prénom</th>
			<th>Adresse</th>
			<th>Code postal</th>
			<th>Ville</th>
			<th>Pays</th>
			<th>Téléphone</th>
		</tr>
	</thead>
	<tbody>
	<?php
		$this->cycle()->assign(array('tr_1', 'tr_2', 'tr_3'), '_user_listing');
		echo $this->partialLoop('utilisateurs/_user_list_listing.phtml', $this->entries);
	?>
	</tbody>
</table>

Vue views/scripts/utilisateurs/_user_list_listing.phtml

<tr class="<?php echo $this->cycle(array(),'_user_listing')->next()?>">
	<td><?php echo $this->escape($this->name) ?></td>
	<td><?php echo $this->escape($this->firstName) ?></td>
	<td><?php echo $this->escape($this->Addrese) ?></td>
	<td><?php echo $this->postCode ?></td>
	<td><?php echo $this->escape($this->cityName) ?></td>
	<td><?php echo $this->escape($this->countryName) ?></td>
	<td><?php echo $this->tel_prefix ?></td>
</tr>

  • Delicious
  • Technorati Favorites
  • Twitter
  • Facebook
  • Google Bookmarks
  • Netvibes Share
  • Share/Bookmark

Tags : , , , ,