Espace de nom PHP et chargement automatique

PHP 5.3 ajoute une notion intéressante : les espaces de nom (ou namespace en anglais). Les espaces de nom permettent de séparer différents … « espace« , permettant ainsi d’avoir deux classe portant le même nom. Idéal pour l’utilisation de framework mais aussi de « l’isolation » de certains composants. Voyons voir comment créer un chargeur automatique (ou autoloader) comprenant les espaces de nom.

Si vous êtes sous Ms Windows, aucun problème un simple spl_autoload_register(); suffit. Malheureusement, sous *nix un bug existe il faudra donc implémenté une solution maison.

Le code

Ce code provient du « PHP Standards Working Group » :

function autoload($className)
{
	$className = ltrim($className, '\\');
	$fileName  = '';
	$namespace = '';
	if ($lastNsPos = strripos($className, '\\'))
	{
		$namespace = substr($className, 0, $lastNsPos);
		$className = substr($className, $lastNsPos + 1);
		$fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
	}
	$fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
 
	require $fileName;
}

Pour l’utiliser, il faut définir deux choses :

  1. Ne pas oublier de modifier l’include path si nécessaire.
  2. Ajouter cette fonction au chargeur de classes présent.

L’exemple

Voici un exemple un peu plus complet.
index.php

<?php
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/lib/');//on ajoute le dossier lib dans l'include path
spl_autoload_register();//sur windows ceci devrait suffire .
//le code pour les autres
//----------------------------------------------------------
function autoload($className)
{
	$className = ltrim($className, '\\');
	$fileName  = '';
	$namespace = '';
	if ($lastNsPos = strripos($className, '\\'))
	{
		$namespace = substr($className, 0, $lastNsPos);
		$className = substr($className, $lastNsPos + 1);
		$fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
	}
	$fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
 
	require $fileName;
}
spl_autoload_register('autoload');
//----------------------------------------------------------
//fin du code de fix
 
use grummfy\test\Test;
Test::sayHello();
 
\grummfy\std\Test::sayHello();
 
# EOF

./lib/grummfy/test/Test.php

<?php
namespace grummfy\test;//pour rappel ceci doit-être la première instruction php (et on ne doit pas avoir de HTML avant)
echo 'Je suis inclus (' . __FILE__ . ')!';
class Test
{
	public static function sayHello()
	{
		echo 'Bonjour depuis ' . __CLASS__;
	}
}
 
# EOF

./lib/grummfy/std/Test.php

<?php
namespace grummfy\std;
echo 'Je suis inclus (' . __FILE__ . ')!';
class Test
{
	public static function sayHello()
	{
		echo 'Bonjour depuis ' . __CLASS__;
	}
}
 
# EOF

Le résultat devrait être :

Je suis inclus (/.../lib/grummfy/test/Test.php)!
Bonjour depuis grummfy\test\Test
Je suis inclus (/.../lib/grummfy/std/Test.php)!
Bonjour depuis grummfy\std\Test

Wampserver : quick switch xdebug menu

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

Future … et projets

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.

Activation, désactivation du wifi sur un D-Link DSL-2640B via PHP

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 ….