Category Archives: Tutoriel

PHP 5.3 et PHP 5.2 en parallèle sur un serveur

Peut-être certains administrateurs serveur se sont déjà posés cette question… Comment avoir plusieurs version de PHP sur un même serveur, par exemple PHP4 et PHP5 ? Ou PHP 5.3.1 et PHP 5.2.6 comme moi aujourd’hui. Ceux qui ont peut-être déjà essayé se sont probablement tirés les cheveux, comme moi :)

Pour tous ceux qui aimeraient pouvoir le faire sur leur serveur, voici une solution :)

Pré-requis

  • Tout d’abord, il vous faut un serveur, soit en 32, soit en 64 bits c’est égal (la solution marche sur les 2). Personnellement j’avais une Debian Lenny en 64 bits, donc ce tuto sera plutôt expliqué pour Debian/Ubuntu que pour CentOS ou autres distributions linux existantes.
  • Du temps devant soi

Installation de la solution LAMP normale (PHP 5.2)

Tout d’abord, il vous faudra avoir une installation LAMP (Linux Apache MySQL PHP) qui fonctionne.
Sous Debian, nous allons utiliser la façon la plus rapide. En étant root, ou avec sudo devant :

apt-get install apache2 php5 php5-mysql mysql-server phpmyadmin


Lorsque ceci est fait, vous pouvez normalement afficher une page (“It works!”) en allant à l’adresse suivante (si en local) ou avec l’adresse ip du serveur :
http://localhost
(Pour la suite du tutorial, nous prendrons comme adresse : 192.168.1.40)

Maintenant, je vous propose de voir votre configuration PHP actuelle, grâce à un fichier “phpinfo.php”, que vous mettrez dans /var/www/ (si pas configuré plus en détail votre Apache).

Donc vous allez créer et remplir ce fichier avec la commande suivante :

echo "<?php phpinfo(); ?>" > phpinfo.php


Lorsque vous allez à l’adresse http://192.168.1.40/phpinfo.php vous verrez une page dans ce genre là (dépendra de votre version PHP et de votre système) :

screen_php_1

Nous voyons donc que chez moi, la version PHP installée est la version 5.2.6.

Le problème, c’est que moi, maintenant, j’aimerais faire de l’objet, et utiliser les Late Static Binding qui ne sont disponibles que depuis la version 5.3.

Compilation de PHP 5.3.1

Maintenant, il nous faut compiler une nouvelle version de PHP, par exemple pour la version 5.3.1 (cela peut être n’importe quelle autre version de PHP, par exemple la PHP 4)

Tout d’abord, alors récupérer PHP depuis le site php.net, par exemple pour moi, le fichier se trouve à l’adresse suivante : http://ch2.php.net/get/php-5.3.1.tar.bz2/from/this/mirror

Je vais donc le télécharger sur le serveur, et l’extraire, grâce à la commande suivante :

cd ~ && wget http://ch2.php.net/get/php-5.3.1.tar.gz/from/this/mirror && tar xvzf php-5.3.1.tar.gz && cd php-5.3.1


Lorsque ceci est fait, il va falloir installer une liste de paquet (dépendra de vous, et ce que vous voulez inclure avec php). Par exemple, moi, je voulais avoir le support MySQL et Curl, plus 2-3 petites choses. La liste des paquets dépendra de la commande suivante.

apt-get install build-essential mysql-client libmysql++-dev libxml2-dev  libcurl4-openssl-dev libpng-dev libicu-dev libmcrypt-dev libxslt-dev


Ensuite, dans le répertoire de php-5.3.1 (nous y sommes déjà normalement), lancez la commande suivante (vous pouvez personnaliser cette commande selon vos besoins. Il est pas contre important de ne pas mettre le chemin par défaut pour le “–prefix” ainsi que pour le “–with-config-file-path” :

./configure --prefix=/usr/local/php53 --with-config-file-path=/usr/local/php53/etc/php/ --disable-ipv6 --with-curl --enable-ftp --with-gd --enable-intl --enable-mbstring --with-mcrypt --with-pdo-mysql=mysqlnd --enable-soap --with-xsl --with-zlib --with-openssl --with-pear=/usr/local/php53/share/php --with-mysql


Si tout se passe bien, vous devriez arriver avec un message du genre :
+--------------------------------------------------------------------+
| License: |
| This software is subject to the PHP License, available in this |
| distribution in the file LICENSE. By continuing this installation |
| process, you are bound by the terms of this license agreement. |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point. |
+--------------------------------------------------------------------+
Thank you for using PHP.

Dans le cas contraire, il vous manque des paquets que vous devez installer afin de pouvoir compiler PHP.

Lorsque tout est bon, on lance la compilation, et nous allons vite boire le café en attendant :)

make && make install


Maintenant, php 5.3.1 est installé, mais ne peut pas encore être utilisé, pour cela, nous allons feinter, et utilisé un module d’apache s’appelant “SUPHP”

SUPHP, et comment gérer ses versions!

Afin de gérer nos différentes version PHP, nous allons utilisé le module SUPHP, d’apache.

Pour cela, installer le paquet suivant :

apt-get install libapache2-mod-suphp


Il nous faut ensuite désactiver le module php d’apache2, pour cela :
a2dismod php5
Ensuite, il faut configurer suphp pour gérer nos version. Nous allons pour cela lui ajouter un Handler dans le fichier de configuration /etc/suphp/suphp.conf .Après la ligne application/x-httpd-php=php:/usr/bin/php-cgi, ajoutez la ligne suivante :

x-httpd-php-5-3="php:/usr/local/php53/bin/php-cgi"


Bien sûr, le chemin spécifié (/usr/local/php53/bin/php-cgi) est à modifier selon la ligne que vous avez utilisée pour la configuration de PHP au-dessus.

Ensuite, il faut modifier le fichier /etc/apache2/mods-enable/suphp.conf et rajouter les lignes suivantes après le premier suPHP_AddHandler application… :

AddType x-httpd-php-5-3 .php53
 suPHP_AddHandler x-httpd-php-5-3

Il faut aussi modifier le fichier de configuration du VirtualHost par défaut, afin d’autoriser les .htaccess
Par défaut, c’est le fichier /etc/apache2/sites-enabled/000-default/. Il faut modifier le AllowOverride None en AllowOverride All (dans le “<Directory />”), ainsi que celui dans le <Directory /var/www>

Il faut aussi ajouter la ligne suivante à /etc/apache2/apache2.conf :

AddType x-httpd-php-5-3 .php53


Et pour finir, on redémarre apache!

/etc/init.d/apache2 restart

On teste!

Maintenant, il reste plus qu’à tester si cela fonctionne correctement.

Pour cela, il nous faut créer un htaccess dans /var/www avec le contenu suivant :

AddHandler x-httpd-php-5-3 .php


Cela va indiquer à SuPHP/Apache que lorsque la page est appelée, il doit utilisé le Handler php 5.3, et pas celui par défaut.

Ensuite nous pouvons retourner sur le “phpinfo”, et nous verrons la nouvelle version de PHP :)

screen_php_2

Problème de “Internal Server error” ?

Dans le cas où une erreur interne apparaît, il est probable que cela soit pour une seule raison :

Le fichier PHP (ici phpinfo.php) NE doit PAS appartenir à root pour être exécuté.

Pour corriger ce problème, 2 solutions :

Changer dans la configuration de SuPHP les valeurs pour le min_uid et min_guid.

Changer le propriétaire du fichier, pour mettre un utilisateur normal. Je vous conseille ce choix, pour des raisons de sécurité.

Donnée d’une table -> objet en PHP

Bonjour :)

Aujourd’hui une petite manipulation qui peut-être très pratique… Chargez les données depuis une base de données, directement dans un objet.

Prenons par exemple la gestion des utilisateurs. Lorsque l’utilisateur se connecte, plutôt que de s’amuser à stocker les informations dans une session normale du genre :

$_SESSION['username'] = $data['user'] ;

on va utilisé une méthode bien plus rapide et pratique.

Tout d’abord, on va créer une classe, la classe user . Voici un début de classe :

     * @version     0.1 [29.05.2009]
     */
    class User {
		/**
		* Attribut
		*/
        private $id_user;
		private $login;
		private $password;
		private $name;
		private $first_name;
		private $title;
		private $address;
		private $NPA;
		private $city;
		private $pays;
		private $tel;
		private $fax;
		private $email;
		private $societe;
		private $connected;
		private $active;
		private $active_code;
		private $sql;
		private $password_uncrypted;
 
        /**
		* Construct the class
		*/
        public function __construct($sql){
			$this -&gt; sql = $sql;
        }
 
        /**
		* Function toString
		*
		*  - Return : the login
		*/
        public function __toString(){
			return $this -&gt; login;
        }
		/**
		* Function used to insert the user in database
		*
		*   - Return : the query to execute
		*/
		public function getInsertString(){
			$query = 'INSERT INTO t_user (login, password, name, first_name,  address, NPA, city, pays, tel, fax, email, societe,active_code) VALUES ';
			$query .= '("'.$this -&gt; login.'",';
			$query .= '"'.$this -&gt; password.'",';
			$query .= '"'.$this -&gt; name.'",';
			$query .= '"'.$this -&gt; first_name.'",';
			$query .= '"'.$this -&gt; address.'",';
			$query .= '"'.$this -&gt; NPA.'",';
			$query .= '"'.$this -&gt; city.'",';
			$query .= '"'.$this -&gt; pays.'",';
			$query .= '"'.$this -&gt; tel.'",';
			$query .= '"'.$this -&gt; fax.'",';
			$query .= '"'.$this -&gt; email.'",';
			$query .= '"'.$this -&gt; societe.'",';
			$query .= '"'.$this -&gt; active_code.'")';
			return $query;
		}
 
		/**
		* Function used to connect an user
		*
		*   - Return : the query to execute
		*/
 
		public function connect(){
			$query = 'SELECT * FROM t_user WHERE login = "'.$this -&gt; login.'" AND password = "'.$this -&gt; password.'"';
			$query = mysql_fetch_assoc($this -&gt; sql -&gt; Query($query));
			$keys = array_keys($query);
			for($i=0;$i {$keys[$i]} =  $query[$keys[$i]];
 
			}
 
			if($query['active']){
				$this -&gt; connected = true;
			}
			else{
				$this -&gt; connected = false;
			}
		}
 
		/**
		* Fonction used to know if a user already exist in DB
		*/
 
		public function existInDb(){
			$bResult = false;
			$query = 'SELECT COUNT(login) as Nbr FROM t_user WHERE login = "'.$this -&gt; login.'"';
			$query = mysql_fetch_assoc($this -&gt; sql -&gt; Query($query));
			if($query['Nbr'] &gt; 0){
				$bResult = true;
			}
			return $bResult;
		}
 
		/**
		*	Function used to generate an activation code
		*/
		public function generateActivationCode(){
			$len = 10;
			$base='ABCDEFGHKLMNOPQRSTWXYZabcdefghjkmnpqrstwxyz123456789';
			$max=strlen($base)-1;
			$activatecode='';
			mt_srand((double)microtime()*1000000);
			while (strlen($activatecode)&lt;$len+1)
			  $activatecode.=$base{mt_rand(0,$max)};
 
			$this -&gt; active_code = $activatecode;
		}
 
		/**
		*	Function used to send the confirmation mail
		*/
 
		public function sendConfirmationMail(){
     		        $headers = 'From: "example"'."\n";
     		        $headers .= 'Reply-To:example@example.ch'."\n";
     		        $headers .= 'Content-Type: text/html; charset="iso-8859-1"'."\n";
     		        $headers .= 'Content-Transfer-Encoding: 8bit';
 
			$message = '';
			$message .= '
<h1>Activation de votre compte</h1>
';
			$message .= 'VOTRE MAIL';
 
			$message .= '
<h1>Vos informations</h1>
';
			$message .= 'Nom d\'utilisateur : '.$this -&gt; login ;
			$message .= 'Mot de passe : '.$this -&gt; password_uncrypted ;
			$message .= '
 
 Garder ce mail précieusement...';
			$message .= '';
			mail($this -&gt; email, 'Création du compte', $message, $headers);
		}
 
		public function activeUser($user,$code){
			$query = 'UPDATE t_user SET active = "1" WHERE login = "'.mysql_real_escape_string($user).'" AND active_code = "'.mysql_real_escape_string($code).'"';
			$query = $this -&gt; sql -&gt; Query($query);
			return true;
		}
 
		/**
		* Magic Function set
		*/
        public function __set($key, $value){
                $this-&gt;$key = $value;
        }
 
		/**
		* Magic Function get
		*/
        public function __get($key){
                return $this-&gt;$key;
       }
    }
?&gt;

Il faut que la classe aie les mêmes champs que la base de données. C’est à dire que si la base de données à un champ “login”, un champ “password”, et un champ “first_name”, il faut absolument que la classe PHP aie les champs “login”, “password”, et “first_name” . Elle peut avoir d’autre champ si vous vous voulez.

Alors au niveau des fonctions interessante, il y a tout d’abord celles là :

public function __set($key, $value){
                $this-&gt;$key = $value;
        }
 
		/**
		* Magic Function get
		*/
        public function __get($key){
                return $this-&gt;$key;
       }

Cette fonction magique permet de générer les getter/setter pour la classe. Ensuite lorsque vous avez instancié la classe dans votre code, vous pourrez faire :

$class -&gt; attribut = 'value';

pour mettre vos valeurs.

L’autre fonction intéressante est celle-ci :

             public function connect(){
			$query = 'SELECT * FROM t_user WHERE login = "'.$this -&gt; login.'" AND password = "'.$this -&gt; password.'"';
			$query = mysql_fetch_assoc($this -&gt; sql -&gt; Query($query));
			$keys = array_keys($query);
			for($i=0;$i {$keys[$i]} =  $query[$keys[$i]];
 
			}
 
			if($query['active']){
				$this -&gt; connected = true;
			}
			else{
				$this -&gt; connected = false;
			}
		}

Elle vous permettra lors de l’appel à cette fonction, de sauvegarder le résultat de la requête dans la classe. C’est à dire que l’utilisateur se connecte, et toutes ses informations seront stocké dans l’objet $user (pour moi). Après il suffit de stocker cette classe dans la session, et vous pourrez l’utiliser sur toutes vos pages :)

Cette fonction va donc récupéré l’array de données de la base de données, ensuite récupéré les clés, et grâce à la syntaxe

1
$this -&gt; {$var} =...

on va pouvoir stocké la valeur, dans l’attribut ayant cette clé. C’est pour cela que je demandais d’avoir les mêmes noms entre la base de données et votre classe php.

Voilà pour ce petit tutoriel…

Bonne nuit :)

L’API Ovh, ça rock’s

Bonjour,

Aujourd’hui, on va faire un petit cours sur comment on utilise l’API d’ovh, nommée SOAPI.

Nous allons prendre comme exemple, comment savoir si un nom de domaine est libre, ou pas :)

Voici une fonction toute faite qui permet de savoir cela :

function isAvailable($domain){
	//Load OVH's Webservice
	$soap = new SoapClient('https://www.ovh.com/soapi/soapi-re-1.3.wsdl');
	//login
	try {
	        $login = "USER OVH";
		$password = "PASSWORD";
		$session = $soap-&gt;login($login,$password,null);
	} catch(SoapFault $fault) {
		echo  "Error : ".$fault . '';
	}
 
        //domainCheck, and set value to available if it is.
	try {
	   	$result = $soap-&gt;domainCheck($domain); //$domain est au format domain.tld
	   	foreach($result as $value) {
	  	        if($value-&gt;predicate == 'is_available'){
			        $available = $value-&gt;value;
	  	        }
	        }
	} catch(SoapFault $fault) {
		echo  "Error : ".$fault . '';
	}
	//logout
	try {
		$result = $soap-&gt;logout($session);
	} catch(SoapFault $fault) {
		echo "Error : ".$fault . '';
	}
	//Return answer
	return $available;
}

Pour pouvoir exécuté tout cela, il vous faudra tout d’abord activer les extensions openssl, ainsi que l’extension “soap”.

Au début, nous nous connectons au webservice d’ovh, grâce à notre utilisateur et mot de passe :

	//Load OVH's Webservice
	$soap = new SoapClient('https://www.ovh.com/soapi/soapi-re-1.3.wsdl');
	//login
       try {
	        $login = "USER OVH";
		$password = "PASSWORD";
		$session = $soap-&gt;login($login,$password,null);
	} catch(SoapFault $fault) {
		echo  "Error : ".$fault . '';
	}

Bien sûr, l’user et le mot de passe sont les votre.

Ensuite on utilise la fonction domainCheck de l’API, afin de vérifier la disponibilité du domaine, et on le stock dans une variable “available”. L’api nous retourne un array, qu’il faut donc “parser” grâce au foreach, afin de récupéré uniquement si la valeur du is_available, car l’api nous retourne aussi si il est transférable et si il est renouvelable.

1
2
3
4
5
6
7
8
9
10
11
	 //domainCheck, and set value to available if it is.
	try {
	   	$result = $soap-&gt;domainCheck($domain); //$domain est au format domain.tld
	   	foreach($result as $value) {
	  	        if($value-&gt;predicate == 'is_available'){
			        $available = $value-&gt;value;
	  	        }
	        }
	} catch(SoapFault $fault) {
		echo  "Error : ".$fault . '';
	}

Et pour finir nous nous déconnectons du webservice, et on retourne le résultat.

	//logout
	try {
		$result = $soap-&gt;logout($session);
	} catch(SoapFault $fault) {
		echo "Error : ".$fault . '';
	}
	//Return answer
	return $available;

Voilà.

Pour avoir plus d’info concernant cette API, dirigez-vous ICI où se trouve toute la documentation de l’API, ainsi qu’un générateur de code…

Bonne journée :)