phpInfo.netLes ArchivesLes éléPHPants

  
  Accueil
  Trucs & Astuces
  Scripts
  Regex
  Annuaire
  Articles

.
      
 Articles   Objets COM en PHP, une première approche  Par Arnaud LIMBOURG   Août 2001  

 »  Avant-propos
 »  Pourquoi ?
 »  Objets COM -> Rappel
 »  COM -> toute première fois, tout toute première fois
 »  Environnement
 »  But du script
 »  COM-> Deux erreurs
 »  Erreurs
 »  Petites précisions

 Avant-propos Comme vous pourrez le remarquer dans cet article j'ai fait des erreurs qui peuvent paraître grossières.
Je tiens cependant à préciser que je viens du monde de l'ASP et que je ne pratique le PHP que depuis peu. Je demande donc à tous de l'indulgence pour ce qui suit, merci.
 Pourquoi ? Dans le cadre du développement d'une application j'ai du me frotter aux objets COM. Venant du monde l'ASP, je pensais qu'il serait assez facile de transposer leur utilisation en PHP.

L'histoire fut bien entendu tout autre et la crise de nerfs ne tarda point à montrer le bout de son nez (j'ai du laisser quelques traces sur le forum d'ailleurs ;).

C'est pourquoi j'ai décidé d'écrire ce tutorial.
 Objets COM -> Rappel La technologie COM est issue de l'imagination fertile des gens de chez Microsoft.

En gros, c'est un cadre général de gestion des divers objets qui composent une application sous environnement Windows (je pourrais m'étendre mais ce n'est pas le but du présent document).
 COM -> toute première fois, tout toute première fois Le script de base de la documentation PHP (que l'on retrouve dans le tutorial sur PHPBbuilder.com) est très simple et n'explique pas grand chose.

Il utilise des appels très simples sur un objet Word. Il fonctionne, certes, mais lorsque j'ai voulu l'adapter à mes besoins je me suis retrouvé avec une foultitude d'erreurs de script et de non moins innombrables plantages Apache.
 Environnement Je préciserais en premier que le petit exemple de script que je vais donner fonctionne sous l'environnement suivant : Windows NT Workstation, Apache 1.3.20, PHP 4.0.6, MySQL 3.23.39.

Le tout a été installé "à la main", EasyPHP n'a pas l'air d'apprécier du tout ces chers petits objets COM; je ne connais pas du tout le comportement des autres packages disponibles sur le marché.
 But du script Mon but très précis est d'utiliser l'équivalent de la commande "Insertion->Fichier", le nom de la méthode correspondante est InsertFile.

Mais tout d'abord, la création de l'objet Word

<?php
$word
= new com("word.application") or die("Unable to instantiate Word");
?>

Si cette commande plante Apache, désolé mais je ne peux pas vous aider. Je n'ai jamais eu de problème avec…

Ensuite, j'ajoute un nouveau document

<?php
$word
->Documents->Add();
?>

Je suis ensuite allé sous Word, j'ai créé une nouvelle macro, fais Insertion->Fichier, puis j'ai pris le code correspondant.
L'équivalent sous PHP donne ceci :

<?php
$word
->Selection->InsertFile(nomdufichierici);
?>

C'est là que les ennuis ont commencé…
 COM-> Deux erreurs Les Warnings ont commencé à pleuvoir, en voici quelques exemples

Warning: Invoke() method failed : unable to lookup InsertFile
Warning: Invoke() method failed : no description available

Ayant l'habitude de programmer des macros en VBA, j'étais pourtant complètement perdu, ne reconnaissant absolument pas cette erreur (j'ai demandé à un expert VBA qui n'a pas su, lui non plus, me répondre).

Dans mon premier script je testais plusieurs méthodes les unes à la suite des autres. J'entends par là que j'essayais différentes syntaxes à la suite les unes des autres pour voir laquelle allait fonctionner.

NE FAITES PAS CA !!!

Croyez-moi, j'ai mis une journée à m'en apercevoir, évitez de perdre du temps comme je l'ai fait.

Cela suffit à faire disparaître le premier message d'erreur.

En ce qui concerne le deuxième message j'ai compris lorsque je me suis aperçu de la façon de l'appeler.

En VB, le code est le suivant

Selection.InsertFile "Chemin\FICHIER.doc"

En PHP, j'avais donc essayé

<?php
$word
->Selection->InsertFile("nomdufichierici");
?>

Ce qui ne fonctionne pas.

Après je fut happé par un trou spatio-temporel et je ne me souviens plus de la façon dont je suis arrivé à la solution suivante.

Le fait est que j'en suis arrivé à utiliser le code :

<?php
$filetoinsert
= $row[$cnt]['chemin_vers_le_document'];

// Cette variable est égale à C:\CHEMIN\Doc1.DOC par exemple
?>

Avec l'appel:

<?php
$word
->Selection->InsertFile($filetoinsert);
?>

Et là, ô miracle, ca fonctionne, Apache ne plante pas, bref tout va pour le mieux dans le meilleur des mondes !!

Presque …

C'était sans compter sur quelques petits bugs.
 Erreurs Dans mon tableau $row certaines lignes étaient vides, l'appel à la méthode InsertFile me provoquait donc l'erreur citée plus haut :

Invoke() method failed : No description available

Je me suis donc assuré que le tableau contenait bien des valeurs sur chaque ligne.
J'ai de plus ajouté un test sur l'existence du fichier car cela peut aussi provoquer une erreur.

Enfin, le final qui est la sauvegarde du document généré ainsi que la destruction des objets pour libérer la mémoire.

<?php
$filename
= $HTTP_SESSION_VARS["mavar"].time().'.doc';
$saveto = 'C:\\temp\\'.$filename;

$document->SaveAs($saveto);

$word->Quit();
$word = null;
unset (
$word);
?>

Cela vous donne une idée sur la façon de procéder.
 Petites précisions Pour ceux d'entre vous qui connaissent les macros Word, vous pouvez remarquer que j'utilise l'équivalent de

Application.Selection.InsertFile

Or, si cette méthode fonctionne bien à l'intérieur d'une même application (de Word à Word par exemple), il en va tout autrement lors de l'automatisation de Word avec des appels venant d'Excel. Dans ce cas-là, l'utilisation de Selection n'est pas recommandée.

La méthode InsertFile supporte aussi l'objet Range, je n'ai pas encore essayé cet méthode à partir de PHP (dans un prochain article peut-être).

Avec la méthode utilisée l'insertion a lieu à partir l'endroit où se trouve le curseur. Dans le code de cet article ce n'est pas gênant car je crée un nouveau document.
Attention cependant si vous utilisez un modèle, veillez à ce que le curseur se trouve bien à la fin du document pour que l'insertion n'est pas lieu au début ou au milieu du modèle (à moins que ce ne soit le but recherché bien entendu).

Merci de votre attention.

Si vous désirez me poser des questions, n'hésitez pas, je suis souvent sur le forum. Tout le monde pourra en profiter, ce qui n'est pas le cas d'un échange de mails.

Dans un prochain article (si celui-ci est utile à certains d'entre vous), je parlerai de l'utilisation des propriétés personnalisées d'un document (champ PROPRIETEDOC), et peut-être des signets.
Synseo