<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="/rss.xsl"?><rss version="2.0"><channel><title>phpmsajax Forum Rss Feed</title><link>http://www.codeplex.com/phpmsajax/Project/ListForums.aspx</link><description>phpmsajax Forum Rss Description</description><item><title>NEW POST: Using the ASP.NET AJAX Control Toolkit with PHP.</title><link>http://www.codeplex.com/phpmsajax/Thread/View.aspx?ThreadId=8404</link><description>&lt;div class="wikidoc"&gt;
Has anyone out there successfully used the ASP.NET AJAX Control Toolkit with PHP?&lt;br /&gt; &lt;br /&gt;If so, please post some sample code for the world using any of the controls.  Thanks!&lt;br /&gt;
&lt;/div&gt;</description><author>ockham</author><pubDate>Wed, 21 Mar 2007 00:34:06 GMT</pubDate><guid isPermaLink="false">NEW POST: Using the ASP.NET AJAX Control Toolkit with PHP. 20070321123406A</guid></item><item><title>Some php code improvement: </title><link>http://www.codeplex.com/phpmsajax/Thread/View.aspx?ThreadId=3933</link><description>PHP uses copy-on-write, so code {{$a = $b;}} doesn't copy any memory. Thus code {{$a = &amp;$b;}} is in fact slower than {{$a = $b;}}. Enlightment is: Don't use reference assignments where not necessary.

PHP construct {{echo}} is very fast. Several {{Response.Write}} were slow in ASP but it doesn't hold for PHP. Code {{$a = ""; $a .= "..."; echo $a;}} is similarly fast, but {{$a = array(); $a[] = "..."; echo implode("", $a);}} is in fact slower because it allocates more than double of memory needed for output (first for array, second for imploded string + overhead costs for array manipulation).</description><author>vrana</author><pubDate>Tue, 13 Feb 2007 10:31:20 GMT</pubDate><guid isPermaLink="false">Some php code improvement:  20070213103120A</guid></item><item><title>Developer Forum: RE: Some php code improvement</title><link>http://www.codeplex.com/phpmsajax/Project/DisplayThread.aspx?ForumId=3568&amp;ThreadId=3933&amp;ANCHOR#LastPost</link><description>Wow, thank you very much!

I'm a pro at the Microsoft AJAX Library, but a novice at PHP, so this kind of help is greatly appreciated.

Skimming the changes you propose, they look great.  I'll take a deeper look over the next few days when I get a chance and incorporate them into the next release.

Thanks again for taking the time to help.  If you're interested in being more involved in the project, email me (Steve.Marx@microsoft.com).  I could always use more help on the PHP side of things.</description><author>SteveMarx</author><pubDate>Fri, 26 Jan 2007 06:07:17 GMT</pubDate><guid isPermaLink="false">Developer Forum: RE: Some php code improvement 20070126060717A</guid></item><item><title>Developer Forum: RE: Some php code improvement</title><link>http://www.codeplex.com/phpmsajax/Project/DisplayThread.aspx?ForumId=3568&amp;ThreadId=3933&amp;ANCHOR#LastPost</link><description>damn! ... I suppose this link should be better: http://www.3site.eu/freedownload/dist.zip

Regards :-)</description><author>andr3a</author><pubDate>Thu, 25 Jan 2007 10:55:26 GMT</pubDate><guid isPermaLink="false">Developer Forum: RE: Some php code improvement 20070125105526A</guid></item><item><title>Developer Forum: Some php code improvement</title><link>http://www.codeplex.com/phpmsajax/Project/DisplayThread.aspx?ForumId=3568&amp;ThreadId=3933&amp;ANCHOR#LastPost</link><description>Hello guys, I've viewed your php code and I thinks it's not much optimized for this simple cool idea.

Here You can view two revisited version of each class that should increase performance and make code more efficient.
I've not tested any part of this code but I suppose if there's some error it's simple to solve.

Best regards,
Andrea Giammarchi


[code]
&lt;?php

# [Andrea Giammarchi] 2007/01/25
# You have the same check on MSAjaxProxyGenerator.php file too ... don't You think
# just one check is enought ?
if (strpos($_SERVER['REQUEST_URI'], __FILE__) !== FALSE)
	exit;

# [Andrea Giammarchi] 2007/01/25
# I think require should be enought ... however, any change
# However, this class depends on MSAjaxProxyGenerator ... output generation has been moved there
require_once 'MSAjaxProxyGenerator.php';

class MSAjaxService
{
	# This feels like a hack... but it seems to work. :-)
	# If anyone has a better solution of how to cast to an arbitrary class, please contribute it!
	# [Andrea Giammarchi] 2007/01/25
	# a bit faster with ternary operator and modfied substr (You need first ":" of serialized array too)
	# I suppose a null value should be a better response (false should be ambigous)
	function typecast($old_object, $new_classname) {
		return class_exists($new_classname) ?
			'O:'.strlen($new_classname).'"'.$new_classname.'"'.substr(serialize($old_object), 1) : false
	}
	
	# [Andrea Giammarchi] 2007/01/25
	# few optimizzations, less redundance code ... faster
	function processRequest() {
		try {
			$path = &amp;$_SERVER['REQUEST_URI'];
			if (substr($path, strlen($path) - 3) === '/js')
				call_user_func(array(new MSAjaxProxyGenerator, 'generateClientProxy'), $this);
			else {
				$methodName = substr($path, strrpos($path, '/') + 1);
				$reflect = new ReflectionObject($this);
				$method = $reflect-&gt;hasMethod($methodName) ? $reflect-&gt;getMethod($methodName) : null;
				$ctype = isset($_SERVER['HTTP_CONTENT_TYPE']) ? 'HTTP_CONTENT_TYPE' : 'CONTENT_TYPE';
				if(is_null($method) || $method-&gt;isStatic() || !$method-&gt;isPublic() || $method-&gt;getDeclaringClass()-&gt;getName() === 'MSAjaxService'))
					throw new Exception('Method ' . $methodName . ' not found');
				if($_SERVER['REQUEST_METHOD'] !== 'POST')
					throw new Exception('Wrong HTTP method, should be POST');
				if(strpos($_SERVER[$ctype], 'application/json') !== 0)
					throw new Exception('Wrong content-type, should be application/json');
				$args = array();
				if(strlen($postData = trim(file_get_contents('php://input')))) {
					$argsAsParams = json_decode($postData, true);
					foreach($method-&gt;getParameters() as $i =&gt; &amp;$param)
						$args[$i] = $param-&gt;getClass() ?
							$this-&gt;typecast(
								$argsAsParams[$param-&gt;getName()],
								$param-&gt;getClass()-&gt;getName()
							) :	$argsAsParams[$param-&gt;getName()];
				}
				# I suppose this class should produce everytime a new output, use false otherwise
				call_user_func(array(new MSAjaxProxyGenerator, 'newJsonContent'), $method-&gt;invokeArgs($this, $args), true);				
			}
		}
		catch(Exception $e) {
			header('HTTP/1.0 500 Internal Server Error');
			# I suppose this class should produce everytime a new output, use false otherwise
			call_user_func(array(new MSAjaxProxyGenerator, 'newJsonContent'), $this-&gt;newJsonContent(array(
				'Message' =&gt; $e-&gt;getMessage(),
				'ExceptionType' =&gt; get_class($e),
				'StackTrace' =&gt; $e-&gt;getTraceAsString()
			)), true);
		}
	}
}

?&gt;
[/code]

[code]
&lt;?php 

# [Andrea Giammarchi] 2007/01/25
# You have the same check on MSAjaxProxyGenerator.php file too ... don't You think
# just one check is enought ?
if (strpos($_SERVER['REQUEST_URI'], __FILE__) !== FALSE)
	exit;

class MSAjaxProxyGenerator
{

	# [Andrea Giammarchi] 2007/01/25
	# no cache and json encoding (think about Pear alternative for PHP &lt; 5.2)
	# example: http://www.devpro.it/code/140.html
	# alternative: http://www.phpclasses.org/browse/file/17166.html
	function newJsonContent($returnValue, $newOutput = true){
		$returnValue = json_encode($returnValue);
		header('Content-Type: application/json');
		header('Content-Length: '.strlen($returnValue));
		if($newOutput) {
			header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
			header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
			header('Cache-Control: no-store, no-cache, must-revalidate');
			header('Cache-Control: post-check=0, pre-check=0', false);
			header('Pragma: no-cache');
		}
		echo $returnValue;
	}
	
	# [Andrea Giammarchi] 2007/01/25
	# make code more efficient, write less having more control or simple mantainment ;-)
	private	function __valid_method(&amp;$method){
		return !$method-&gt;isStatic() &amp;&amp; $method-&gt;isPublic() &amp;&amp; $method-&gt;getDeclaringClass()-&gt;getName() !== 'MSAjaxService';
	}
	
	# [Andrea Giammarchi] 2007/01/25
	# few performance improvements, less redundance, better code ? I hope
	# P.S. echo is slow (print is even slower) ... don't write 6238737172163 in your scripts if You care about performances
	function generateClientProxy($obj) {
		$applicationRoot = dirname($_SERVER['SCRIPT_NAME']);
		$reflect = new ReflectionObject($obj);
		$classname = $reflect-&gt;getName();
		$line = "\r\n";
		$output = array(
			'var ', $classname, '=function(){', $line,
			$classname, '.initializeBase(this);', $line,
			'this._timeout=0;this._userContext=null;this._succeeded=null;this._failed=null;', $line
			'};', $line, $classname, 'prototype={', $line
		);
		$second = 0;
		foreach ($reflect-&gt;getMethods() as $m =&gt; &amp;$method) {
			if($this-&gt;__valid_method($method)) {
				if($second == 1)
					$output[] = ','.$line;
				$output[] = $method-&gt;getName().':function('
				foreach ($method-&gt;getParameters() as $p =&gt; &amp;$param)
					$output[] = $param-&gt;getName().',';
				$output[] = 	'succeededCallback,failedCallback,userContext){'.$line.
						'return this._invoke('.$classname.'.get_path(),"'.$method-&gt;getName().'",false,{';
				$second = 0;
				foreach ($method-&gt;getParameters() as $p =&gt; &amp;$param) {
					if($second == 1)
						$output[] = ',';
					$output[] = $param-&gt;getName().':'.$param-&gt;getName();
					$second = 1;
				}
				$output[] = '},succeededCallback,failedCallback,userContext);}';
				$second = 1;
			}
		}
		array_push($output, '};', $line,
			$classname, '.registerClass("', $classname, '",Sys.Net.WebServiceProxy);', $line,
			$classname, '._staticInstance=new ', $classname, ';', $line,
			$classname, '.set_path=function(value){', $classname, '._staticInstance._path=value};', $line,
			$classname, '.get_path=function(){return ', $classname, '._staticInstance._path};', $line,
			$classname, '.set_timeout=function(value){', $classname, '._staticInstance._timeout=value};', $line,
			$classname, '.get_timeout=function(){return ', $classname, '._staticInstance._timeout};', $line,
			$classname, '.set_defaultUserContext=function(value){', $classname, '._staticInstance._userContext=value};', $line,
			$classname, '.get_defaultUserContext=function(){return ', $classname, '._staticInstance._userContext};', $line,
			$classname, '.set_defaultSucceededCallback=function(value){', $classname, '._staticInstance._succeeded=value};', $line,
			$classname, '.get_defaultSucceededCallback=function(){return ', $classname, '._staticInstance._succeeded};', $line,
			$classname, '.set_defaultFailedCallback=function(value){', $classname, '._staticInstance._failed=value};', $line,
			$classname, '.get_defaultFailedCallback=function(){return ', $classname, '._staticInstance._failed};', $line	
		);
		$pathWithoutProxy = $_SERVER['REQUEST_URI'];
		$pathWithoutProxy = substr($pathWithoutProxy, 0, strlen($pathWithoutProxy) - 3);
		$pathWithoutProxy = addslashes($pathWithoutProxy);
		$output[] = $classname.'.set_path("'.$pathWithoutProxy.'");'.$line;
		foreach ($reflect-&gt;getMethods() as $m =&gt; &amp;$method) {
			if ($this-&gt;__valid_method($method)) {
				$output[] = $classname.'.'.$method-&gt;getName().'=function(';
				$params = '';
				foreach($method-&gt;getParameters() as $p =&gt; $param)
					$params .= $param-&gt;getName() . ',';
				array_push($output, $params, 'onSuccess,onFailed,userContext){', $classname, '._staticInstance.', $method-&gt;getName(), '(', $params, 'onSuccess,onFailed,userContext)};', $line);
				# use false if You don't need a new layout [cached classes]
				$this-&gt;newJsonContent(implode('', $output), true);
			}
		}
	}
}
?&gt;
[/code]</description><author>andr3a</author><pubDate>Thu, 25 Jan 2007 10:53:27 GMT</pubDate><guid isPermaLink="false">Developer Forum: Some php code improvement 20070125105327A</guid></item></channel></rss>