Comment obtenir l'opcode d'un script PHP ?

Cet article a été publié depuis plus de 6 mois, cela signifie que le contenu peut ne plus être d'actualité.

Si vous suivez un peu ce qui se passe dans la sphère PHP, vous avez peut-être vu passer une explication d'Igor WIEDLER concernant l'utilisation de l'instruction goto dans une librairie qu'il a écrit. Pour justifier son choix, Igor s'est appuyé sur l'opcode résultant de l'interprétation de son code. Je me suis alors demandé comment est-il possible de générer l'opcode résultant d'un script PHP.

Avant toute chose, je vais rappeler rapidement ce qu'est l'opcode. Lorsqu'un script PHP est exécuté, la machine virtuelle PHP va transformer le script lu en un langage intermédiaire qui représente des opérations de base. Ces instructions de bas niveau sont généralement appelé "opcode".

Il y a plusieurs raisons qui peuvent pousser un développeur à visualiser l'opcode d'un fichier PHP. Tout d'abord par curiosité intellectuelle afin de comprendre comment fonctionne le langage. Il faut également savoir que par défaut, la machine virtuelle PHP n'optimise pas le code source qui est lu. Dans le cas, où il n'y a ni mécanisme d'optimisation, ni cache d'opcode, il peut être intéressant de connaitre l'opcode généré afin de faire quelques optimisations de son code.

Le moyen qui est certainement le plus simple pour visualiser l'opcode d'un code PHP est de se rendre sur le site 3v4l qui permet de tester du code sur plusieurs versions de PHP, mais il fournit également l'opcode résultant aussi bien pour le ZendEngine (la machine virtuelle PHP) que pour HHVM (la machine virtuelle de Facebook compatible PHP).

La solution précédente est simple, mais vous oblige à posséder une connexion Internet et à copier/coller vos différents scripts sur le site. Une autre solution consiste alors à installer une extension PHP qui nous permettra de visualiser la représentation interne des scripts exécutés.

L'extension en question s'appelle Vulcan Logic Disassembler. Cette dernière s'installe facilement au travers la commande pecl ou en récupérant son code source et en le compilant.

$ pecl install vld-beta

Une fois l'extension installée, vous pourrez visualiser l'opcode d'un script via la commande :

$ php -dextension=vld.so -dvld.active=1 mon-script.php

Finding entry points
Branch analysis from position: 0
Return found
filename:       /in/t0fJ6
function name:  (null)
number of ops:  2
compiled vars:  none
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   3     0  >   ECHO                                                     'Hello+World'
         1    > RETURN                                                   1

Si vous vous intéressez au fonctionnement interne de PHP, je ne peux que vous conseillez de lire ce livre collaboratif expliquant et décrivant le fonctionne interne de PHP.

Vous pourrez également en apprendre un peu plus avec le livre développer une extension PHP de Pascal MARTIN, qui tient également un blog où chaque mois, il résume ce qui se passe sur @internals, la mailing-list des développeurs de PHP.


  • L'issue Github dont il est question dans l'article
  • Un article de Pascal MARTIN sur une utilisation avancée de Vulcan Logic Disassembler.