Exploring the Question of Embedded Java in PHP

5 04 2014

flickr: by Mangiwau

Today, I discovered a curious tweet by Volker Dusch that may cause one to consider the wild possibility of embedding Java in PHP.

 Dusch displays some code which appears essentially, as follows:

<?php
System.out.print("Hello");

Between the opening and closing PHP tags astoundingly lies a line of code with the unmistakable trappings of Java for outputting a string. Dusch tweets that the code works remarkably well, and offers a link if you wish to view it. But, one should observe that the example at the URL has error reporting turned off, which allows the code to run without distracting error notices that this code attracts.

The bizarre snippet has caused some to question if this coding style represents a more desirable way to output string data in PHP.   The answer bluntly in one word is a resounding “No.”  The code merely gives the illusion that Java may execute within PHP while nothing of the sort occurs. A review of the opcodes that the script generates, reveals the clever deception.    The following lists the critical information, also available here:

 

line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   3     0  >   SEND_VAL                                                 0
         1      DO_FCALL                                      1          'error_reporting'
   5     2      FETCH_CONSTANT                                   ~1      'System'
         3      FETCH_CONSTANT                                   ~2      'out'
         4      CONCAT                                           ~3      ~1, ~2
         5      PRINT                                            ~4      'Hi'
         6      CONCAT                                           ~5      ~3, ~4
         7      FREE                                                     ~5
         8    > RETURN                                                   1

 

Ignore the first two opcodes; they simply turn off error reporting.  Instead, focus on the next two marked “FETCH-CONSTANT” which depict System and out as constants, although the script never defines them. Consequently, their values are their names, i.e. “System” and “out” as opcodes 2 and 3 show. These values get assigned respectively to  temporary variables  ~1 and ~2.  (Note, a tilde prefixed to a number represents a temporary variable.)  At this point, you may recall mention of the suppressed error messages.  They number two and together   they inform the user about the script containing undefined constants whose values are assumed to be their respective names.  The PHP manual (“Manual”) confirms this behavior.  Perl describes such constants as “bare words” and allows them.  PHP, sitting on the fence, tries to discourage this usage by emitting an error notice while allowing the code to execute.

Returning to the opcodes listing, the next line concatenates ~1 and ~2, storing the result in ~3.  The PRINT opcode occurs next and is responsible for displaying the greeting.  The print operation finishes by returning the value 1 which ~4 acquires.  Opcode 6 concatenates  ~3 and ~4  so that ~5 takes on the value of  “Systemout1”.  You can see this result for yourself by using a var_dump, as follows:

<?php
error_reporting(0);
var_dump(System.out.print('Hi'));

Since ~5 needlessly takes up memory — it has no use whatsoever in this case — the subsequent opcode destroys it, freeing up the memory it occupies.  Lastly the script returns 1 signifying true and indicative of successful execution.

Practically-speaking, this phun Java-esque snippet is perhaps best reserved for an  April Fool’s joke.   Or, for the classroom, since it clearly demonstrates that the period character has a distinctly different purpose in PHP as compared with Java. And, as long as the case remains the same, PHP may safely steer clear of the danger of turning into Java.

Before concluding, I’d like to address the corollary question of how to avoid using undefined constants. PHP aids in this endeavor by offering the function defined which tests for a constant rather than creating one as define does. One caveat about using defined, you must be sure to quote its argument. I erroneously reworked the original snippet as follows:

<?php
error_reporting(E_ALL);
if ( defined(System) && defined (out)) {
    System.out.print('Hi');
}
else {
     echo "No Java here :)";
}

The parser perceived the use of an undefined constant, namely the argument for the first call to defined, resulting in an error notice appearing. But, the second call to that function  for some odd reason failed to produce any such message. Otherwise, the code ran successfully displaying the expected “No Java here :)”

Note, that defined is inapplicable if you need to test for a magic constant, in which case one needs to directly test such a constant against its own string value, as follows:

<?php
if (__FILE__ === "__FILE__") {
     echo "The constant is undefined.";
}

This work is licensed under a Creative Commons License

Advertisements

Actions

Information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: