📄 server.php
字号:
<?php
/**
* OO AJAX Implementation for PHP
*
* @category HTML
* @package AJAX
* @author Joshua Eichorn <josh@bluga.net>
* @copyright 2005 Joshua Eichorn
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @version Release: @package_version@
*/
/**
* Require the main AJAX library
*/
require_once 'HTML/AJAX.php';
/**
* Class for creating an external AJAX server
*
* Can be used in 2 different modes, registerClass mode where you create an instance of the server and add the classes that will be registered
* and then run handle request
*
* Or you can extend it and add init{className} methods for each class you want to export
*
* Client js generation is exposed through 2 _GET params client and stub
* Setting the _GET param client to `all` will give you all the js classes needed
* Setting the _GET param stub to `all` will give you stubs of all registered classes, you can also set it too just 1 class
*
* @category HTML
* @package AJAX
* @author Joshua Eichorn <josh@bluga.net>
* @copyright 2005 Joshua Eichorn
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @version Release: @package_version@
* @link http://pear.php.net/package/PackageName
*/
class HTML_AJAX_Server
{
/**
* Client options array if set to true the code looks at _GET
* @var bool|array
*/
var $options = true;
/**
* HTML_AJAX instance
* @var HTML_AJAX
*/
var $ajax;
/**
* Set to true if your extending the server to add init{className methods}
* @var boolean
* @access public
*/
var $initMethods = false;
/**
* Location on filesystem of client javascript library
* @var false|string if false the default pear data dir location is used
*/
var $clientJsLocation = false;
/**
* An array of options that tell the server howto Cache output
*
* The rules are functions that make etag hash used to see if the client needs to download updated content
* If you extend this class you can make your own rule function the naming convention is _cacheRule{RuleName}
*
* <code>
* array(
* 'httpCacheClient' => true, // send 304 headers for responses to ?client=* requests
* 'ClientCacheRule' => 'File', // create a hash from file names and modified times, options: file|content
* 'ClientCacheExpects'=> 'files', // what type of content to send to the hash function, options: files|classes|content
* 'httpCacheStub' => true, // send 304 headers for responses to ?stub=* requests
* 'StubCacheRule' => 'Api', // create a hash from the exposed api, options: api|content
* 'StubCacheExpects'=> 'classes', // what type of content to send to the hash function, options: files|classes|content
* )
* </code>
*
* @var array
* @access public
*/
var $cacheOptions = array(
'httpCacheClient' => true,
'ClientCacheRule' => 'file',
'ClientCacheExpects' => 'files',
'httpCacheStub' => true,
'StubCacheRule' => 'api',
'StubCacheExpects' => 'classes',
);
/**
* Javascript library names and there path
*
* the return of $this->clientJsLocation(), is prepended before running readfile on them
*
* @access public
* @var array
*/
var $javascriptLibraries = array(
'all' => 'HTML_AJAX.js',
'html_ajax' => 'HTML_AJAX.js',
'html_ajax_lite'=> 'HTML_AJAX_lite.js',
'json' => 'serializer/JSON.js',
'request' => 'Request.js',
'main' => array('Compat.js','Main.js','clientPool.js'),
'httpclient' => 'HttpClient.js',
'dispatcher' => 'Dispatcher.js',
'util' => 'util.js',
'loading' => 'Loading.js',
'phpserializer' => 'serializer/phpSerializer.js',
'urlserializer' => 'serializer/UrlSerializer.js',
'haserializer' => 'serializer/haSerializer.js',
'clientpool' => 'clientPool.js',
'iframe' => 'IframeXHR.js',
'alias' => 'Alias.js',
'queues' => 'Queue.js',
'behavior' => array('behavior/behavior.js','behavior/cssQuery-p.js'),
// rules to help you use a minimal library set
'standard' => array('Compat.js','clientPool.js','util.js','Main.js','HttpClient.js','Request.js','serializer/JSON.js',
'Loading.js','serializer/UrlSerializer.js','Alias.js','behavior/behavior.js','behavior/cssQuery-p.js'),
'jsonrpc' => array('Compat.js','util.js','Main.js','clientPool.js','HttpClient.js','Request.js','serializer/JSON.js'),
'proxyobjects' => array('Compat.js','util.js','Main.js','clientPool.js','Request.js','serializer/JSON.js','Dispatcher.js'),
// BC rules
'priorityqueue' => 'Queue.js',
'orderedqueue' => 'Queue.js',
);
/**
* Custom paths to use for javascript libraries, if not set {@link clientJsLocation} is used to find the system path
*
* @access public
* @var array
* @see registerJsLibrary
*/
var $javascriptLibraryPaths = array();
/**
* Array of className => init methods to call, generated from constructor from initClassName methods
*
* @access protected
*/
var $_initLookup = array();
/**
* Constructor creates the HTML_AJAX instance
*
* @param string $serverUrl (Optional) the url the client should be making a request too
*/
function HTML_AJAX_Server($serverUrl = false)
{
$this->ajax = new HTML_AJAX();
// parameters for HTML::AJAX
$parameters = array('stub', 'client');
// keep in the query string all the parameters that don't belong to AJAX
// we remove all string like "parameter=something&". Final '&' can also
// be '&' (to be sure) and is optional. '=something' is optional too.
$querystring = '';
if (isset($_SERVER['QUERY_STRING'])) {
$querystring = preg_replace('/(' . join('|', $parameters) . ')(?:=[^&]*(?:&(?:amp;)?|$))?/', '', $this->ajax->_getServer('QUERY_STRING'));
}
// call the server with this query string
if ($serverUrl === false) {
$serverUrl = htmlentities($this->ajax->_getServer('PHP_SELF'));
}
if (substr($serverUrl,-1) != '?') {
$serverUrl .= '?';
}
$this->ajax->serverUrl = $serverUrl . htmlentities($querystring);
$methods = get_class_methods($this);
foreach($methods as $method) {
if (preg_match('/^init([a-zA-Z0-9_]+)$/',$method,$match)) {
$this->_initLookup[strtolower($match[1])] = $method;
}
}
}
/**
* Handle a client request, either generating a client or having HTML_AJAX handle the request
*
* @return boolean true if request was handled, false otherwise
*/
function handleRequest()
{
if ($this->options == true) {
$this->_loadOptions();
}
//basically a hook for iframe but allows processing of data earlier
$this->ajax->populatePayload();
if (!isset($_GET['c']) && (count($this->options['client']) > 0 || count($this->options['stub']) > 0) ) {
$this->generateClient();
return true;
} else {
if (!empty($_GET['c'])) {
$this->_init($this->_cleanIdentifier($this->ajax->_getVar('c')));
}
return $this->ajax->handleRequest();
}
}
/**
* Register method passthrough to HTML_AJAX
*
* @see HTML_AJAX::registerClass for docs
*/
function registerClass(&$instance, $exportedName = false, $exportedMethods = false)
{
$this->ajax->registerClass($instance,$exportedName,$exportedMethods);
}
/**
* Change default serialization - important for exporting classes
*
* I wanted this for the xml serializer :)
*/
function setSerializer($type)
{
$this->ajax->serializer = $type;
$this->ajax->unserializer = $type;
}
/**
* Register a new js client library
*
* @param string $libraryName name you'll reference the library as
* @param string|array $fileName actual filename with no path, for example customLib.js
* @param string|false $path Optional, if not set the result from jsClientLocation is used
*/
function registerJSLibrary($libraryName,$fileName,$path = false) {
$libraryName = strtolower($libraryName);
$this->javascriptLibraries[$libraryName] = $fileName;
if ($path !== false) {
$this->javascriptLibraryPaths[$libraryName] = $path;
}
}
/**
* Register init methods from an external class
*
* @param object $instance an external class with initClassName methods
*/
function registerInitObject(&$instance) {
$instance->server =& $this;
$methods = get_class_methods($instance);
foreach($methods as $method) {
if (preg_match('/^init([a-zA-Z0-9_]+)$/',$method,$match)) {
$this->_initLookup[strtolower($match[1])] = array(&$instance,$method);
}
}
}
/**
* Register a callback to be exported to the client
*
* This function uses the PHP callback pseudo-type
*
*/
function registerPhpCallback($callback)
{
if (!is_callable($callback)) {
// invalid callback
return false;
}
if (is_array($callback) && is_object($callback[0])) {
// object method
$this->registerClass($callback[0], strtolower(get_class($callback[0])), array($callback[1]));
return true;
}
// static callback
$this->ajax->registerPhpCallback($callback);
}
/**
* Generate client js
*
* @todo this is going to need tests to cover all the options
*/
function generateClient()
{
$headers = array();
ob_start();
// create a list list of js files were going to need to output
// index is the full file and so is the value, this keeps duplicates out of $fileList
$fileList = array();
if(!is_array($this->options['client'])) {
$this->options['client'] = array();
}
foreach($this->options['client'] as $library) {
if (isset($this->javascriptLibraries[$library])) {
$lib = (array)$this->javascriptLibraries[$library];
foreach($lib as $file) {
if (isset($this->javascriptLibraryPaths[$library])) {
$fileList[$this->javascriptLibraryPaths[$library].$file] = $this->javascriptLibraryPaths[$library].$file;
}
else {
$fileList[$this->clientJsLocation().$file] = $this->clientJsLocation().$file;
}
}
}
}
// do needed class init if were running an init server
if(!is_array($this->options['stub'])) {
$this->options['stub'] = array();
}
$classList = $this->options['stub'];
if ($this->initMethods) {
if (isset($this->options['stub'][0]) && $this->options['stub'][0] === 'all') {
$this->_initAll();
} else {
foreach($this->options['stub'] as $stub) {
$this->_init($stub);
}
}
}
if (isset($this->options['stub'][0]) && $this->options['stub'][0] === 'all') {
$classList = array_keys($this->ajax->_exportedInstances);
}
// if were doing stub and client we have to wait for both ETags before we can compare with the client
$combinedOutput = false;
if ($classList != false && count($classList) > 0 && count($fileList) > 0) {
$combinedOutput = true;
}
if ($classList != false && count($classList) > 0) {
// were setup enough to make a stubETag if the input it wants is a class list
if ($this->cacheOptions['httpCacheStub'] &&
$this->cacheOptions['StubCacheExpects'] == 'classes')
{
$stubETag = $this->_callCacheRule('Stub',$classList);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -