Using Titanium Desktop with PHP

(NOTE: These Programming Guides only pertain to Titanium Desktop 1.1 or earlier.)

The Titanium Desktop SDK includes a PHP module, which allows developers to run PHP code from within their applications. Here's a quick demonstration of what this means:

<script>
    function my_php_function($item)
    {
        $result = array();
        for ($index = 0; $index < $item->count(); $index++)
        {
            $result[] = $item[$index] + 2;
        }
        return $result;
    }
</script>
 
<script>
    alert(my_php_function([1, 2, 3, 4]));
</script>
The PHP module for each platform is bundled with PHP 5.3.1. Your users should not need to install any extra dependencies to use your PHP code. PHP 4 code is not supported.

Including PHP in your pages

There are a few ways to include PHP scripts on your Titanium pages. As demonstrated above, you can include a script tag with type=&quot;text/php.&quot; If you have a PHP source file that you want to include there are two ways to accomplish this:

<!-- method one -->
<script type="text/php" src="my_file.php"/>
 
<!-- method two -->
<script type="text/php">
    include("my_other_file.php");
</script>
PHP code included in either of these ways has full access to the DOM and the Titanium object as usual. There is one important difference between these two methods. When including PHP via the include or require commands you should surround your code with &lt;?php ?&gt; tags. When including via &lt;script&gt; tags, you should not surround your code with &lt;?php ?&gt; tags.

Preprocessed PHP

If you do surround your PHP code with &lt;?php ?&gt; and place it in a file that ends in the .php extension it will be preprocessed. Preprocessed Titanium works very much like PHP code on an Apache server. The script contents are replaced with the script output before the content is rendered by the browser. Preprocessed PHP does not have access to the Titanium object and cannot interact directly with the DOM.

Say you have a file named test.php with the contents:

<?php
     echo("PHP preprocessed output!");
?>
If you navigate your application to this file, the contents of the web view will be:
PHP preprocessed output!

The Kroll / PHP Bridge

Kroll is the underlying object and communication system in Titanium. It has its own object system, including its own spectrum of types. Whenever you call Python from JavaScript or JavaScript from Python, your data will be flowing through Kroll.

Numbers

Since all JavaScript Numeric variables are floating-point, when they are passed into PHP, they will be converted into PHP doubles. JavaScript numerics are converted by value rather than converted by reference.

<script>
    var globalNumber = 23;
</script>
<script type="text/php">
    $globalNumber = 13; // globalNumber will change
 
    function changeNumber($number)
    {
        global $globalNumber;
        $number = 10; // globalNumber will not change
        $globalNumber = 10; // globalNumber will change
    }
    changeNumber($globalNumber)
</script>
One important result of all Kroll numbers being floating point numbers is that if you send a number into JavaScript and then back into PHP, that number will always be a PHP double.

Booleans

JavaScript Booleans are also converted by value directly to a PHP boolean and vice-versa.

Null and Undefined

JavaScript null and undefined both map to null in PHP. PHP null maps to null in JavaScript.

Strings

JavaScript strings maps to PHP strings and PHP strings map to JavaScript strings.

Objects

Passing a JavaScript object to PHP involves wrapping the JavaScript object in a PHP object. This means that if you change a JavaScript object in PHP, that change will be reflected in the original object. When dealing with data that flows from one language context to another, it suffices to think of them as the same object.

<script>
     var globalObject = new Object();
     globalObject.foo = "string";
</script>
<script type="text/php">
     $globalObject->foo = "string2"; # globalObject will change
 
     function changeNumber($obj)
     {
         # obj is passed by reference so globalObject will change
         $obj->foo = "string3";
     }
     changeNumber($globalObject)
</script>
PHP objects work the same way when moving to JavaScript. Here's an example:
<script type="text/php">
      class MyObject {
          public $publicVariable;
 
          function __construct()
          {
              $this->publicVariable = "bar";
          }
 
          public function publicMethod()
          {
              return "foo";
          }
      }
 
      $globalObject = new MyObject()
</script>
<script>
      alert(globalObject.publicVariable);
        alert(globalObject.publicMethod());
 
        globalObject.publicVariable = "propagain";
        alert(globalObject.publicVariable);
</script>

PHP arrays in JavaScript

PHP arrays, when passed to JavaScript, are Objects whose properties are just dict accesses. For instance:

<script type="text/php">
    $globalObject = array();
    $globalObject['foo'] = "string";
</script>
<script>
    alert(globalObject.foo);
</script>

JavaScript arrays in PHP

JavaScript arrays in PHP are wrapped in an object similar to an ArrayObject.

<script>
     var globalArray = [1, 2, 3, 4];
</script>
<script type="text/php">
     $globalArray->append(3);
     $globalArray->append(4);
     $window->alert($globalArray[0]);
</script>

JQuery + Titanium + PHP fun

Thanks to @funkatron for this nice mind blowing example:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
    <script type="text/javascript" src="jquery-1.3.2.js"></script>      
</head>
<body>
    <div style="border-top:1px solid #404040">
       <div style="padding:10px">
        Welcome to Titanium
       </div>
    </div>
 
    <form>
       <input type="button" name="invokePHP"
               value="Fade-in with PHP" id="invokePHP"/>
    </form>
 
    <div id="phpjQ" style="display:none; background-color:black; padding:10px">
       This is PHP controlling jQuery
    </div>
 
    <script type="text/php">
      $jQuery()->ready( function () use (&$jQuery) {
 
        $jQuery('#invokePHP')->live('click', function () use (&$jQuery) {
 
            $jQuery('#phpjQ')->css('color', 'red')->fadeIn(2000);
 
        } );
 
      } );
    </script>
</body>
</html>

Known issues

  1. Top-level classes can be accessed in &lt;script&gt; tags, but they must be prefixed by a top-level namespace specifier.

    <script type="text/php">
        $x = new \SimpleXMLElement($someText);
    </script>

  2. require_once does not seem to work properly. Tinu Coman suggested this workaround:

    if(!class_exists('MyClass'))
    {
        include "class1.php";
        include "file2.php";
        include "file3.php";
        include "file4.php";
    }