On peut tout faire avec PHP, sauf le café…

Ou du moins on peut faire pas mal de choses. Utilisé en majorité pour du web (Internet, intranet..) le PHP peut néanmoins surprendre pour peu que l’on cherche à faire autre chose avec. Sans entrer dans les spécificités de la 5ème mouture du langage, il est des points mal-connus de PHP qui, s’ils sont actuellement plutôt considérés comme gadget par certains, pourraient bien un jour entrer dans la cour des grandes fonctionnalités. J’en veux pour exemple l’utilisation de PHP-GTK couplée à PHPBlender. Pour des raisons de "c’est pas trop mon truc" et de "y a de très bons tutos ailleurs", les procédures d’installations ne seront pas détaillées ici.

Présentation des participants

PHP-GTK

PHP-GTK est un ensemble de classes permettant de développer des applications contenant des boutons, des fenêtres, des barres d’outils, des menus … Ca vous rappelle quelque chose ? Java ? .NET ? Il y a de quoi . Ces deux derniers fonctionnent de la même manière au niveau des applications en mode fenêtre. Pour Java, le code est compilé en un format spécifique, le Javabyte code, ce qui le rend indépendant de la plate-forme car ce code est ensuite exécuté par la machine virtuelle (JVM) qui l’optimise pour la plate forme sur laquelle elle tourne, comme s’il était compilé. Pour .NET, le code est lui aussi compilé dans un format intermédiaire (MSIL) puis exécuté au sein de l’architecture .NET comme une application du domaine. Pour PHP-GTK, enfin, le code est simplement envoyé au serveur (Apache par exemple) qui retournera le rendu de l’application.

PHPBlender

PHPBlender permet de distribuer vos scripts PHP sous forme d’exécutable en .EXE. Un compilateur ? Non car il ne convertit pas le code source en code compilé. En fait il réunit au sein d’un seul élément votre code PHP et l’interpréteur PHP lui-même. De ce fait, vous n’avez plus qu’à placer les librairies(dll) spécifiques requises par votre code (le cas échéant) et votre code/script/appli peut tourner de façon autonome.

Ca y est ? Vous voyez ce que la mise en relation des deux entités peut apporter ? Bon alors c’est parti…

PHP-GTK : on ouvre les fenêtres

Le GTK ne vous dit rien ? GTK correspond à GIMP Tool Kit, et n’est à la base qu’un ensemble de widgets (éléments de control : bouton, liste, boite de dialogue…) utilisables pour développer une application. THE GIMP est quant à lui un logiciel de création et de retouche d’images, un Photoshop en libre en quelque sorte. Le GTK a évolué et fait parti désormais d’un ensemble de librairies, appelé GTK+, écrites en C. De type orienté objet, GTK+ fait partie intégrante de Gnome, un gestionnaire de bureau sous Linux. PHP-GTK désigne donc l’ensemble de classes qui permettent l’utilisation de ces widgets par le langage PHP.

Il est essentiel d’avoir de bonnes bases en POO avant d’aller plus loin dans la présentation. En effet, l’utilisation de PHP-GTK ne se fera qu’en manipulant des classes et si l’exemple ci-dessous vous semble incompréhensible ou illisible, il va falloir travailler un peu avant. ;p


# On instancie la classe Gtk Button.
$button = &new GtkButton("Cliquez ici"); 
# On appelle la fonction connect en lui passant  deux paramètres :
#     - le nom du signal à capturer (clicked)
#     - le nom de la fonction à exécuter lorsque le signal est capturé (buttonClicked)
$button->connect("clicked""buttonClicked");


Cela indique que lorsque le bouton émet un signal ‘clicked’, la fonction buttonClicked est appelée. Donc si on a la fonction buttonClicked :

function buttonClicked() 

echo 
‘Vous avez clique sur le bouton.’
}


alors lorsque le bouton sera cliqué, le message ‘Vous avez cliqué sur le bouton.’ sera affiché à l’écran.
Affiché à l’écran car il est à noter que l’appel se fait en ligne de commande donc pendant que l’application tourne en mode fenêtre, la console est ouverte et vous permet d’y afficher des sorties écrans, sans qu’elles n’apparaissent dans votre application. La console peut alors servir de débuggeur ou de contrôleur de l’application pendant que l’application elle-même tourne à côté.

Donc, comme il faut bien se jeter à l’eau, voici un ‘petit’ bout de code. Il permet de créer une fenêtre contenant des menus. Cet exemple illustrera notre propos et clôturera notre présentation de PHP-GTK pour ce post.

<?php
# On charge l'extension PHP-GTK
if(strtoupper(substr(PHP_OS0,3)) == 'WIN'dl('php_gtk.dll');
else 
dl('php_gtk.so');

# Création de la fenêtre
$w = &new gtkwindow();
$w->realize();
$gdkwindow  $w->window;
$accelgroup = &new GtkAccelGroup();
$w->add_accel_group($accelgroup);

# Création du menu
$menu = &new menu($gdkwindow,$accelgroup);
$w->add($menu->bar);
$menu->add_menu_item('file',null,'file');
$menu->add_menu_item('open',$parent='file',$label='_open file',$callback='openfilefunctionname',$imgfile='img/button/16x16-save.xpm');
$menu->add_sep('file');
$menu->add_menu_item('quit',$parent='file',$label='_quit',$callback='shutdown',
$imgfile='img/button/16x16-exit.xpm');
$menu->add_menu_item('help',null,'help');
$menu->add_menu_item('about','help','about','about_function_name');

# Gestion des évenements
$w->connect('destroy-event','shutdown');
$w->connect('delete-event','shutdown');
$w->set_position('center');

# Affiche la fenêtre
$w->show_all();

# Démarre la boucle principale d'écoute
gtk::main();

function 
shutdown(){
  
gtk::main_quit();
}

/**
easy way to create menu with optionnal icons
@author jonathan gotti nathan@the-ring.homelinux.net
@licence http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public Licence
@date 2004-06-08
*/
class menu{

  var 
$bar;
  
/** the gdkwindow used to create pixmaps */
  
var $gdkwindow;
  
/** the accel group to manage accelkeys */
  
var $accel_group;
  
/** used for easy access to menus */
  
var $menus;
  
/** used for easy access to menuitems */
  
var $items;
  
/**
  constructor function
  you can pass null as gdkwindow but in this case you MUST pack the menu->bar before adding entry,
  to permit him to be realize (it must have a window as top level container to be realized).
  @param gdkwindow $gdkwindow the gdkwindow used to create pixmaps
  @param gtkaccelgroup &$accel_group the accelgroup to use (it will create one if null)
  @param int GTK_SHADOW_TYPE (GTK_SHADOW_ETCHED_IN as default)
  @return menu object
  **/
  
function menu($gdkwindow=null,$accel_group=null,$shadowtype=GTK_SHADOW_ETCHED_IN){
    if(
is_a($gdkwindow,'gdkwindow'))
      
$this->gdkwindow = &$gdkwindow;
    
$this->bar        = &new GtkMenuBar();
    
$this->bar->set_shadow_type($shadowtype);
    if(
is_a($accel_group,'GtkAccelGroup')){
      
$this->accel_group = &$accel_group;
    }else{
      
$this->accel_group = &new GtkAccelGroup();
    }
  }
  
/**
  add an handlebox as box propertie
  and pack the bar into it so you will need to pack $this->box instead of $this->bar
  */
  
function add_handlebox(){
    
$this->box = &new Gtkhandlebox();
    
$this->box->add($this->bar);
  }
  
/**
  will add a separator to $parent menu
  @param string $parent the parent menu keyindex
  */
  
function add_sep($parent){
    
$this->add_menu_item('SEP',$parent);
  }
  
/**
  add an item to the menu
  @param string $key is the keyindex to acces the item inside the objects
  @param string $parent the parent's keyindex
  @param string $label the text to display for this item (can be null to get a separator)
  @param mixed  $callback the function name or array(object,methodname) to call on select
  @param string $imgfile optionnal file path to an icon
  @param bool   $sensitive
  @param bool   $is_checkmenuitem
  @param bool   $is_checked
  */
  
function add_menu_item($key,$parent,$label=null,$callback=null,$imgfile=null,$sensitive=TRUE,
$is_checkmenuitem=FALSE,$is_checked=FALSE){
    while(
$this->items[$key]){ # ensure a unike keyid
      
preg_match("!(\d+)$!",$key,$m);
      
$int=$m[1];
      if(
is_numeric($int))
        
$key substr($key,0,- strlen($int)).($int+1);
      else
        
$key.='1';
    }
    if( (!
$label)&& $this->menus[$parent]){
      
$this->items[$key] = &new gtkmenuitem();
      
$this->items[$key]->set_sensitive(FALSE);
      
$this->menus[$parent]->append($this->items[$key]);
      return;
    }
    if(!
$is_checkmenuitem){
      
$this->items[$key]= &new gtkmenuitem($label);
    }else{
      
$this->items[$key]= &new gtkcheckmenuitem($label);
      
$this->items[$key]->set_active($is_checked);
    }
    
$lb $this->items[$key]->child;
    
# add icon if needed
    
if(file_exists($imgfile)){
      if(! 
$this->gdkwindow){ # try to get a gdkwindow if we have none
        
$this->bar->realize();
        
$this->gdkwindow $this->bar->window;
      }
      if(
$img Gdk::pixmap_create_from_xpm($this->gdkwindow,null,$imgfile)){
        
$img = &new GtkPixmap($img[0], $img[1]);
        
$this->items[$key]->remove($lb);
        
$box = &new gtkhbox();
        
$box->pack_start($img,0,0,2);
        
$box->pack_start($lb,0,0,2);
        
$this->items[$key]->add($box);
      }
    }
    
# adding to parent menu
    
if(!$parent){
      
$this->bar->append($this->items[$key]);
    }else{
      if(! 
$this->items[$parent]){
        echo 
"[ERROR] menu::add_menu_item to non-existent parent '$parent'\n";
        return 
FALSE;
      }
      if(! 
$this->menus[$parent]){
        
$this->menus[$parent] = &new GtkMenu();
        
$this->items[$parent]->set_submenu($this->menus[$parent]);
      }
      
$this->menus[$parent]->append($this->items[$key]);
    }
    
# add accellkey if needed
    
if(substr_count($label,'_')){ # ajoute un raccourcis clavier
      
$acckey $lb->parse_uline($label);
      
$this->items[$key]->add_accelerator('activate',$this->accel_group,$acckey,GDK_CONTROL_MASK,
GTK_ACCEL_VISIBLE);
    }
    
#connect to callback
    
if($callback)
      
$this->items[$key]->connect('activate',$callback,$key);
  }
  function 
destroy(){
    if(
$this->box)
      
$this->box->destroy();
    else
      
$this->bar->destroy();
  }
}

?>


Toujours vivant après cette lecture ? Bon. Enregistrez ce code sous un nom de votre choix, tiens menu.php par exemple. Maintenant, dans une fenêtre DOS, faites un petit

C:\>php -q menu.php

Vous aurez alors un joli menu, pour 6Ko de code, qui s’affichera (vous l’aurez noté, sans les images, ce qui est normal, ne vous inquiétez pas), comme celui-ci :

Image du rendu

C’est beau hein ? Vous avez tout de même remarqué ? Vous êtes des bons vous hein ? En effet, j’ai triché, ce n’est pas la capture d’écran du script ci-dessus (regardez la barre en haut, à coté de l’icône GTK…). Cette capture est celle de la version exécutable du menu. Eh oui, parce que maintenant, nous allons rendre exécutable l’utilisation du menu…



PHPBlender : et on s’exécute, plus vite que ça

Ne vous inquiétez pas, la partie qui suit et certainement la plus simple de tout le processus.
Nous nous rendons donc, via une fenêtre DOS, dans le répertoire où est installé PHPblender, par exemple C:\priadoblender et nous allons rendre exécutable le fichier menu.php que nous y avons placé auparavant. Nous faisons donc un petit :

blender.exe menu.php menu.exe

car : blender.exe <input File> <Output>
- <input File>: Emplacement du code que vous voulez rendre exécutable. Ce chemin peut être relatif ou absolu.
- <output File>: Le nom de l’exécutable une fois le code compile. Par exemple output.exe (ne pas indiquer simplement output et ne pas spécifier de chemin, juste donner le nom du fichier).

Nous avons donc maintenant un joli menu.exe de 19Ko. Vous avez cliqué sur votre exe ? Ben nan il marche pas, un peu de patience. Bon placez dans un dossier de votre choix votre exe, par exemple C:\menu puis copiez-y les fichiers contenu dans le répertoire C:\priadoblender\bundle. C’est le minimum vital de vos exécutables. Quoi ? Vous avez encore clique dessus et ça marche toujours pas ? Mais un peu de calme s’il vous plait. Souvenez-vous de ce que j’ai mentionné en début de post : « vous n’avez plus qu’à placer les librairies(dll) spécifiques requises par votre code (le cas échéant) et votre code/script/appli peut tourner de façon autonome » . En l’occurrence les dll de GTK.

Pour ce faire, vous auriez besoin de vous rendre dans le php\extension de votre installation et copier les dll commençant par ‘php_gtk’ dans votre dossier c:\menu. Vous auriez aussi besoin des librairies libgdk et libglib qui sont des dépendances de GTK. Bref beaucoup de clics pour rien. Donc le meilleur moyen, c’est d’appliquer la méthode USAir Force, aussi connue sous le nom de proverbe troll : dans le doute frappe encore. Donc vous prenez toutes les dll contenues dans le package PHP-GTK et vous les collez dans votre répertoire c:\menu.

Vous aurez alors quelque chose dans le genre :

Et là vous pouvez cliquer : Votre menu apparaît bien.


Voilà, cette présentation est terminée, vous pouvez éteindre votre ordinateur. Moi j’ai trop parlé/écrit, je vais me coucher et rêver de mes prochains développements…