AJAX
[ class tree: AJAX ] [ index: AJAX ] [ all elements ]

Source for file AJAX.php

Documentation is available at AJAX.php

  1. <?php
  2. /**
  3.  * OO AJAX Implementation for PHP
  4.  *
  5.  * @category   HTML
  6.  * @package    AJAX
  7.  * @author     Joshua Eichorn <josh@bluga.net>
  8.  * @copyright  2005 Joshua Eichorn
  9.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  10.  * @version    Release: @package_version@
  11.  * @link       http://pear.php.net/package/PackageName
  12.  * @todo       Decide if its good thing to support get
  13.  * @todo       pass server side warnings to the client as exceptions or something like that
  14.  * @todo       Add some sort of debugging console
  15.  */
  16. class HTML_AJAX {
  17.     /**
  18.      * An array holding the instances were exporting
  19.      *
  20.      * key is the exported name
  21.      *
  22.      * row format is array('className'=>'','exportedName'=>'','instance'=>'','exportedMethods=>'')
  23.      *
  24.      * @var object 
  25.      * @access private
  26.      */    
  27.     var $_exportedInstances;
  28.  
  29.     /**
  30.      * Set the server url in the generated stubs to this value
  31.      * If set to false, serverUrl will not be set
  32.      * @var false|string
  33.      */
  34.     var $serverUrl = false;
  35.  
  36.     /**
  37.      * What encoding your going to use for serializing data from php being sent to javascript
  38.      * @var string  JSON|null
  39.      */
  40.     var $serializer = "JSON";
  41.  
  42.     /**
  43.      * What encoding your going to use for unserializing data sent from javascript
  44.      * @var string  JSON|null
  45.      */
  46.     var $unserializer = "JSON";
  47.  
  48.     /**
  49.      * Content-type map
  50.      *
  51.      * Used in to automatically choose serializers as needed
  52.      */
  53.     var $contentTypeMap = array(
  54.             'JSON'  => 'application/json',
  55.             'Null'  => 'text/plain',
  56.             'Error' => 'application/error',
  57.         );
  58.  
  59.     /**
  60.      * Set a class to handle requests
  61.      *
  62.      * @param   object  $instance 
  63.      * @param   string|bool $exportedName  Name used for the javascript class, if false the name of the php class is used
  64.      * @param   array|bool $exportedMethods  If false all functions without a _ prefix are exported, if an array only the methods listed in the array are exported
  65.      */
  66.     function registerClass(&$instance$exportedName = false$exportedMethods = false{
  67.         $className strtolower(get_class($instance));
  68.  
  69.         if ($exportedName === false{
  70.             $exportedName $className;
  71.         }
  72.  
  73.         if ($exportedMethods === false{
  74.             $exportedMethods $this->_getMethodsToExport($className);
  75.         }
  76.  
  77.  
  78.         $this->_exportedInstances[$exportedName= array();
  79.         $this->_exportedInstances[$exportedName]['className'$className;
  80.         $this->_exportedInstances[$exportedName]['exportedName'$className;
  81.         $this->_exportedInstances[$exportedName]['instance'=$instance;
  82.         $this->_exportedInstances[$exportedName]['exportedMethods'$exportedMethods;
  83.     }
  84.  
  85.     /**
  86.      * Get a list of methods in a class to export
  87.      *
  88.      * @param string    $className 
  89.      * @return array  the list
  90.      * @access private
  91.      */    
  92.     function _getMethodsToExport($className{
  93.         $funcs get_class_methods($className);
  94.  
  95.         foreach ($funcs as $key => $func{
  96.             if ($func === $className || substr($func,0,1=== '_'{
  97.                 unset($funcs[$key]);
  98.             }
  99.         }
  100.         return $funcs;
  101.     }
  102.  
  103.     /**
  104.      * Generate the client Javascript code
  105.      *
  106.      */
  107.     function generateJavaScriptClient({
  108.         $client "";
  109.  
  110.         foreach($this->_exportedInstances as $name => $data{
  111.             $client .= $this->generateClassStub($name);
  112.         }
  113.         return $client;
  114.     }
  115.  
  116.     /**
  117.      * Return the stub for a class
  118.      *
  119.      * @param   string  $name 
  120.      */
  121.     function generateClassStub($name{
  122.  
  123.         if (!isset($this->_exportedInstances[$name])) {
  124.             return "";
  125.         }
  126.  
  127.         $client = "// Client stub for the {$this->_exportedInstances[$name]['className']} PHP Class\n";
  128.         $client .= "function $name(callback) {\n";
  129.         $client .= "\tmode = 'sync';\n";
  130.         $client .= "\tif (callback) { mode = 'async'; }\n";
  131.         $client .= "\tthis.serializer = '$this->serializer';\n";
  132.         $client .= "\tthis.unserializer = '$this->unserializer';\n";
  133.         $client .= "\tthis.className = '$name';\n";
  134.         if ($this->serverUrl{
  135.             $client .= "\tthis.dispatcher = new HTML_AJAX_Dispatcher(this.className,mode,callback,'{$this->serverUrl}');\n}\n";
  136.         }
  137.         else {
  138.             $client .= "\tthis.dispatcher = new HTML_AJAX_Dispatcher(this.className,mode,callback);\n}\n";
  139.         }
  140.         $client .= "$name.prototype  = {\n";
  141.         foreach($this->_exportedInstances[$name]['exportedMethods'as $method{
  142.             $client .= $this->_generateMethodStub($method);
  143.         }
  144.         $client = substr($client,0,(strlen($client)-2))."\n";
  145.         $client .= "}\n\n";
  146.         return $client;
  147.     }
  148.  
  149.     /**
  150.      * Returns a methods stub
  151.      * 
  152.      *
  153.      * @param string the method name
  154.      * @return string the js code
  155.      * @access private
  156.      */    
  157.     function _generateMethodStub($method) {
  158.         $stub = "\t$method: function() { return this.dispatcher.doCall('$method',arguments); },\n";
  159.         return $stub;
  160.     }
  161.  
  162.     /**
  163.      * @todo move the get _GET check someplace else so get variabled dispatch isn't the hardcoded method
  164.      * @todo is it worth it to figure out howto use just 1 instance if the type is the same for serialize and unserialize
  165.      */
  166.     function handleRequest() {
  167.         if (isset($_GET['c']) && isset($_GET['m'])) {
  168.  
  169.             set_error_handler(array(&$this,'_errorHandler'));
  170.  
  171.             $class = $_GET['c'];
  172.             $method = $_GET['m'];
  173.             
  174.             if (!isset($this->_exportedInstances[$class])) {
  175.                 // handle error
  176.                 trigger_error("Unknown class: $class");
  177.             }
  178.             if (!in_array($method,$this->_exportedInstances[$class]['exportedMethods'])) {
  179.                 // handle error
  180.                 trigger_error("Unknown method: $method");
  181.             }
  182.  
  183.             $unserializer = $this->_getSerializer($this->unserializer);
  184.             
  185.             $args $unserializer->unserialize($this->_getClientPayload());
  186.             $ret = call_user_func_array(array(&$this->_exportedInstances[$class]['instance'],$method),$args);
  187.             
  188.             
  189.             restore_error_handler();
  190.             $this->_sendResponse($ret);
  191.  
  192.             return true;
  193.         }
  194.         return false;
  195.     }
  196.  
  197.     /**
  198.      * Send a reponse adding needed headers and serializing content
  199.      *
  200.      * @param   mixed content to serialize and send
  201.      * @access private
  202.      */
  203.     function _sendResponse($response) {
  204.             $serializer = $this->_getSerializer($this->serializer);
  205.             $output $serializer->serialize($response);
  206.             header('Content-Length: '.strlen($output));
  207.  
  208.             // headers to force things not to be cached: 
  209.             header('Expires: Mon, 26 Jul 1997 05:00:00 GMT')
  210.             header('Last-Modified: ' . gmdate"D, d M Y H:i:s" 'GMT')
  211.             header('Cache-Control: no-cache, must-revalidate')
  212.             header('Pragma: no-cache');
  213.  
  214.             if (isset($this->contentTypeMap[$this->serializer])) {
  215.                 header('Content-type: '.$this->contentTypeMap[$this->serializer]);
  216.             }
  217.  
  218.             echo $output;
  219.     }
  220.  
  221.     /**
  222.      * Get an instance of a serializer class
  223.      * @access private
  224.      * @todo    figure out howto manage some error handling here while still allowing any custom user serializer class
  225.      */
  226.     function _getSerializer($type) {
  227.         $class = "HTML_AJAX_Serializer_$type";
  228.  
  229.         // include the class
  230.         require_once "HTML/AJAX/Serializer/$type.php";
  231.  
  232.         $instance = new $class();
  233.         return $instance;
  234.     }
  235.  
  236.     /**
  237.      * Get payload in its submitted form, currently only supports raw post
  238.      */
  239.     function _getClientPayload() {
  240.             global $HTTP_RAW_POST_DATA;
  241.             return $HTTP_RAW_POST_DATA;
  242.     }
  243.  
  244.     /**
  245.      * Error handler that sends it errors to the client side
  246.      */
  247.     function _errorHandler($errno, $errstr, $errfile, $errline) {
  248.         if (error_reporting()) {
  249.             $e = new stdClass();
  250.             $e->errNo   = $errno;
  251.             $e->errStr  = $errstr;
  252.             $e->errFile = $errfile;
  253.             $e->errLine = $errline;
  254.             $this->serializer = 'Error';
  255.             $this->_sendResponse($e);
  256.  
  257.             die();
  258.         }
  259.     }
  260. }
  261. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

Documentation generated on Mon, 11 Mar 2019 14:16:00 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.