About the Author

Chris Shiflett

Hi, I'm Chris, a web developer and a founding member of Analog. I live and work in Brooklyn, NY.


PHP Advent Calendar Day 22

Today's entry is provided by Derick Rethans. Today also happens to be Derick's birthday, so I hope you'll join me in wishing him a very happy birthday. (Because I'm a little late posting this, and Derick lives in Norway, I'm afraid this is a belated birthday wish. Sorry, Derick!)

Derick Rethans

Name
Derick Rethans
Blog
derickrethans.nl
Biography
Derick Rethans has contributed in a number of ways to the PHP project, including the mcrypt, date, and filter extensions; bug fixes; additions; and leading the QA team. He now works as project leader for the eZ components project for eZ systems A.S. In his spare time he likes to work on Xdebug, watch movies, travel, and practice photography.
Location
Skien, Telemark, Norway

This might not seem like a useful gem to most of you, but it has a coolness factor that I hope you appreciate. I am a geek and engineer, and I like to know how things work. Because I deal with lots of PHP things, I want to know how PHP works. So, I spend lots of time figuring this out while working on Xdebug, but that doesn't always go deep enough.

So, some years ago, I starting hacking on a little tool called VLD. The original goal was to turn this into an encoder, but as I don't really care about encoding PHP files, it never made it that far.

What does it do? For each script, function, class, and method, this extension shows the internal execution units that represent your PHP code. There are a couple of things that you have to do before VLD shows you any output. First, of course, you have to install it. Follow the instructions, and add extension=vld.so to your php.ini file. If all is well, there should be a VLD section in your phpinfo() output. Because VLD outputs all of the opcodes to standard error, it's not really useful to run it through Apache; it is more suited to run from the command line.

Let's see what it does for the following script:

<?php
 
$a = 42;
 
if ($a < 50) {
    for ($b = 0; $b < $a; $b++) {
        echo sqrt($b), "\n";
    }
} else {
    echo "The value $a is too high.\n";
}
 
?>

After running this with the following command:

php -dvld.active=1 -dvld.verbosity=0 example1.php

You see output like this:

filename:       /tmp/example1.php
function name:  (null)
number of ops:  23
compiled vars:  !0 = $a, !1 = $b
line   #  op                     fetch  ext  return  operands
-------------------------------------------------------------
   3   0  ASSIGN                                     !0, 42
   5   1  IS_SMALLER                         ~1      !0, 50
       2  JMPZ                                       ~1, ->15
   6   3  ASSIGN                                     !1, 0
       4  IS_SMALLER                         ~3      !1, !0
       5  JMPZNZ                          9          ~3, ->14
       6* POST_INC                           ~4      !1
       7* FREE                                       ~4
       8* JMP                                        ->4
   7   9  SEND_VAR                                   !1
      10  DO_FCALL                        1          'sqrt'
      11  ECHO                                       $5
      12  ECHO                                       '%0A'
   8  13  JMP                                        ->6
   9  14  JMP                                        ->21
  10  15* INIT_STRING                        ~6
      16* ADD_STRING                         ~6      ~6, 'The+value+'
      17* ADD_VAR                            ~6      ~6, !0
      18* ADD_STRING                         ~6      ~6, '+is+too+high.%0A'
      19* PRINT                              ~7      ~6
      20* FREE                                       ~7
  13  21* RETURN                                     1
      22* ZEND_HANDLE_EXCEPTION

For every executable unit (script, function, method), it generates this type of output, showing the filename and function/method name, the number of opcodes, the IDs of compiled variables, and the opcodes (execution units) themselves.

By playing with the verbosity, you can control what kind of information VLD displays. A verbosity of 1 will add code path analysis to the output, showing which parts of the code can be executed (indicated by the * after the opcode #). A verbosity of 4 shows all possible information VLD can gather about the execution units. You can also instruct VLD not to execute the script you feed to PHP. Simply add the -dvld.execute=0 statement to the command line.

Interpreting this data is non-trivial, but I am sure you can figure it out. As a hint, !0 is a compiled variable, ~1 is a temporary value and ->15 is a jump instruction. In case you have questions, feel free to send me an email.

One last warning (just in case the big red warning on the site is not enough): VLD cannot be used to decode encoding files. Please do not ask me questions about this.

About This Post

PHP Advent Calendar Day 22 was posted on Sat, 22 Dec 2007 at 22:55:30 GMT.

1 Comments

1. Vincent's GravatarVincent said:

Happy belated birthday!

Sun, 23 Dec 2007 at 12:06:34 GMT Link


Post A Comment

Personal Details and Comment

Style Guide

Line breaks are converted to paragraphs. Also use:

  • <a href="" title="">text</a>1
  • <em>text</em>
  • <blockquote><p>text</p></blockquote>
  • <code>2  <?php  if ($foo) {      $foo = TRUE;  }  ?></code>
  1. Note: <code> can be used inline (e.g. in paragraphs) or in a block as shown. Include whitespace and newlines in blocks.

Please enter Chris (my first name) below. This is a primitive spam prevention technique, and I apologize for the inconvenience.

Preview and Submit

Upcoming Talks

ConFoo

10 - 12 Mar 2010

At Hilton Montréal Bonaventure, Montréal, Canada.

South by Southwest

12 - 16 Mar 2010

At Austin Convention Center, Austin, Texas.

Dutch PHP Conference

10 - 12 Jun 2010

At TBD, Amsterdam, Netherlands.

O'Reilly Open Source Convention

19 - 23 Jul 2010

At Oregon Convention Center, Portland, Oregon.

New Comments

liukang wrote:

I have problem with this example. In my php.ini magic_quotes_gpc is off so i'm using only addsla...

Posted in addslashes() Versus mysql_real_escape_string()
RyanTheGreat wrote:

Well, I'm not Chris, but I will do my best to address the questions raised in the comments by Ian...

Posted in Security Corner: Cross-Site Request Forgeries
Chris Shiflett wrote:

Thanks for the kind words, Simon. I'm glad you liked the tutorial. In case it's helpful, here'...

Posted in Webstock
Chris Shiflett wrote:

Hi Robin, I plan to post something about it, but it's going to be hard to express everything i...

Posted in Webstock
Simon Mahony wrote:

Hi Chris, I really enjoyed your workshop on the Evolution of Security at Webstock. I think I g...

Posted in Webstock

Browse Comments


Work and Books

Analog Essential PHP Security HTTP Developer's Handbook