Sajax With JSON Support In PHP
A while ago, I wanted to recreate the cool functionality you get with DWR in PHP. There are a ton of frameworks out there that come close, but miss completely. Thus, I finally caved and created my own solution that is nothing more than patching the existing software into my desired hack. From the simple ingredients of:
Hacked-SAJAX was born.
- Download here.
Example code is included and it can be used as follows:
- Create your PHP function
- Export your PHP function
- Call sajax_init()
- Call your PHP function from Javascript just like any other asynchronous function
$obj->name = "wyatt " . $obj->name;
return $obj;
}
sajax_export("addNameToObject");
sajax_init();
x_addNameToObject(myObj, function (obj2) {console.log(obj2); } );
This is of course released under the GPL or whatever means that I’m giving away my modifications, please cite everyone who had a part in it. My changes to the code base are as follows
//parse out the args array
$newArgArray = array();
$arraySize = sizeof($args);
for($i = 0; $i < $arraySize; $i++) {
//decode the JSON object
$tmpArg = json_decode(stripslashes($args[$i]));
array_push($newArgArray, $tmpArg);
}
$result = call_user_func_array($func_name, $newArgArray);
//encode the result in to JSON
$retString = json_encode($result);
//echo "var res = " . trim(sajax_get_js_repr($result)) . "; res;";
echo "var res = " . $retString . "; res;"
:215
for (i = 0; i < args.length-1; i++) {
//uri += "&rsargs[]=" + escape(args[i]);
uri += "&rsargs[]=" + escape(args[i].toJSONString());
}
:227
for (i = 0; i < args.length-1; i++) {
//post_data = post_data + "&rsargs=" + esscape(args[i]);
post_data = post_data + "&rsargs[]=" + escape(args[i].toJSONString());
}
The original rant is here:
I have been scouring the Internet for two days for looking for a suitable PHP alternative to DWR(read the previous post for more information) and haven’t found a single one so I’ve hacked out my own.
I had been looking at xajax in the hopes that it would get me what I was looking for, but it didn’t. So the next one I found was SAJAX. This project appears to be less active than xajax; however, disappointment strikes again. SAJAX does not support JavaScript objects, only basic variables. While that’s all well and good, when I need to pass larger objects, that’s extremely fricken annoying!!!
But wait … a glimmer of hope on the horizon … Sanjer promises to combine SAJAX and JSON. Only one major problem, it’s not actively maintained and it’s based on the 0.10 version of SAJAX which had some serialization bugs.
So to end the frustration for me and anyone else on the Internet who would ever want to do something this stupid (it apparently has to be stupid since no one else is willing to pull this off), I present my solution to the problem … hacking SAJAX. Before I delve into what changed, I’m going to give you the files so you can just run with it in the event that you aren’t interested in that crap. This zip includes everything you need to pull this off: Crockford’s json.js from http://www.json.org/, hacked up version of Sajax.php from me, and a simple index.php file that gives a super simple example of how it works. Oh yeah, since this is all based on GPL/Open source code, my derivation falls under the same licensing and comes with absolutely no warranty. Now, on to the other stuff that most people don’t really care about.
Fortunately, the people who wrote the SAJAX framework did a really good job a keeping a very nice code separation. All that had to happen to tweak this was:
- JSON Encode the arguments before they are passed to the proxied PHP code
- Create a new argument array of decoded JSON objects
- Pass in the new argument array
- JSON Encode the function result
Now I know that I could put this encode and decode inside every PHP function; however, I’m lazy and I don’t want to do that, especially if it’s a framework and it should do it for me.
Well, that’s it. Really fricken hard, eh? Yeah, didn’t think so. I’m sure that this version will work for most uses; however, if you do find a bug, feel free to leave a comment or send it to me at wyatt neal on my GMail account and I’ll do my best to help you out. Hopefully this will inspire someone else with more time to come up with a better PHP framework that is a lot closer to the coolness you get from DWR.
If you have one that does what DWR does, drop a comment and let me know. SAJAX, PAJAX, and XAJAX don’t count because I’ve looked at them and I know they don’t provide the same level of use. The only one that comes close is PAJAX but it fails because it does synchronous instead of asynchronous calls by default (what where you thinking people?!?).
Popularity: 6% [?]

Wyatt says:
Update: Tony pointed out and I found as well that the following needs to be changed:
//decode the JSON object
$tmpArg = json_decode($args[$i]);
array_push($newArgArray, $tmpArg);
}
to
//decode the JSON object
$tmpArg = json_decode($args[$i]);
array_push($newArgArray, $tmpArg);
}
I’ve updated the zip to include this fix; however, if you find yourself walking off the array, then this is probably your issue. Thanks again for reminding me to put the fix here Tony.
15 April 2007, 12:01 amWyatt says:
Ubunt has done something to their libapache2-mod-php5 verison and you need to change your json_decode to the following:
//decode the JSON object
$tmpArg = json_decode(stripslashes($args[$i]));
array_push($newArgArray, $tmpArg);
}
Wyatt says:
Sorry about the broken link to those that request it. Fallout from a Wordpress upgrade that I wasn’t paying any attention to.
7 August 2007, 8:57 pmJamie LeBlanc says:
I have updated my sajax.php with the one you provided in the zip file, and also installed the JSon javascript file as shown in your index.php page, but I am still getting the error. “Caught error [object Error]: Could not eval var res = …..
I have noticed in FF this all works perfectly fine, but in IE it dies.
I have an HTML form I am putting in to be displayed, and if I take the tag out of what is to be returned, it all works in IE. So this eval error seems to not like using a form tag in the html returned. Has anyone tested this fix above to see if you can return an html form with IE? I tested my program to see what little code could break it, and returning a simple piece of html like this breaks…
I like SAJAX
Any ideas on how to fix this?
28 August 2007, 2:52 pmJamie LeBlanc says:
sorry about my last post, I forgot it would render the html vs showing it…
here it is…
I like SAJAX
28 August 2007, 2:57 pmJamie LeBlanc says:
arrrgggg… this is working….. how about a third time….
I like SAJAX
28 August 2007, 2:59 pmJamie LeBlanc says:
ok, I give up, I can’t paste any code in here to show you, basically I can’t get any form to render at all using sajax, even if it is the most basic of forms.
28 August 2007, 3:00 pmWyatt says:
Updated
I needed to add the following to get base64 to work properly (stupid ‘+’ sign). I hope this doesn’t break IE compatibility, it doesn’t seem to; however, let me know if it does.
for (i = 0; i < args.length-1; i++) {
//uri += "&rsargs[]=" + escape(args[i]);
//uri += “&rsargs[]=” + escape(args[i].toJSONString());
uri += “&rsargs[]=” + encodeURIComponent(args[i].toJSONString());
}
Wyatt says:
Jamie, please try to repost your code using the codesnippet capabilites on the post located here. You should be able to put HTML code like the following:
<head>
<title>hello world</title>
</head>
<body>
hello world
</body>
</html>
Wrap your code like this:
28 August 2007, 8:33 pm[code lang="html"]
html code here
[/code]
Jamie LeBlanc says:
Ok, here is the code that won’t render with sajax….
${title}
<b>PDQ Phase:</b>${pdq_phase}
<b>Category:</b>${ncats}
<b>Comments:</b>
${comments}
Wyatt says:
The following code works for me:
require_once("Sajax.php");
function checkObject($obj1) {
return $obj1;
}
function writeForm($obj) {
$html = "";
$html .= "<form action=\"javascript:void(0);\" method=\"post\" name=\"enp\">";
$html .= "<input type=\"text\" id=\"note_action\" name=\"action\" value=\"$obj\"/>";
$html .= "";
return $html;
}
$sajax_request_type = "POST";
sajax_init();
sajax_export("checkObject");
sajax_export("writeForm");
sajax_handle_client_request();
?>
<html>
<head>
<script type="text/javascript" src="json.js"></script>
<script>
<?php
sajax_show_javascript();
?>
function doCall() {
var myObj = new Object();
myObj.name = "wyatt";
myObj.type = "boy";
myObj.atest = new Array();
for(var i = 0; i < = 5; i++) {
myObj.atest[i] = i;
}
x_checkObject(myObj, cb_checkObj);
}
function doCall2() {
var myString = "wyatt";
//x_checkObject(myString, cb_checkObj);
x_writeForm(myString, cb_writeHTML);
}
function cb_checkObj(jsObj) {
if(jsObj.name && jsObj.type) {
alert("name:" + jsObj.name + ",type:" + jsObj.type);
for (var i = 0; i <= 5; i++) {
console.log(jsObj.atest[i]);
}
} else {
alert(jsObj);
}
}
function cb_writeHTML(htmlCode) {
var div = document.getElementById(‘div1′);
div.innerHTML = htmlCode;
}
</script>
</script></head>
<body>
Test Page
<button onclick="doCall()" value="do call">Object Test</button>
<button onclick="doCall2()" value="do call 2">Variable Test</button>
<div id="div1">
I should change.
</div>
</body>
</html>
Wyatt says:
Someone asked how to get the Javascript into it’s own separate file instead of clogging up the top of your page:
file_put_contents(’exported_javascript.js’, sajax_get_javascript());
?>
Then just include the file in your HTML like normal. Found here
30 August 2007, 11:47 amWahoo says:
Thank you for sharing!
5 October 2007, 9:05 pmClose says:
Thanks, this is very interesting. Do I understand this right, there’s no need anymore to send variables with a separator like below?
Wyatt says:
@Close
19 January 2008, 3:20 pmThat’s correct. With my implementation, the Javascript/PHP objects transition back and forth as your containers. I should note that this implementation only supports basic serialized objects. Complex entities such as functions and self-references are not supported for obvious reasons
Close says:
Well, that is great. So I can get rid of using explode() and searching for item[0], item[1] etcetera… Thanks again, I will try this tomorrow.
19 January 2008, 4:31 pmClose says:
The website I am working on is on PHP4 which has no JSON support. I could solve that, but then arose problems because most of the content is still in ISO-8859-1 (this used to be a problem with Sajax too but that could be solved). However JSON only supports utf-8…
21 January 2008, 6:40 pmThird, it became very slow compared to my old sajax. As long as i’m still on PHP4, I give up for now.
Wyatt says:
Sorry it’s not going to work out for you; however, I am curious about your slow down issues. I’ve been running some pretty hefty PHP on the backend an my worst time is 500ms for a query that’s pulling back around 10,000 rows.
21 January 2008, 11:47 pmYaronGo says:
Small hack for using JSON2 (grab from json.org):
L217: Switch from
to
L229: Switch from
to
Ben says:
Great tweak. This has officially made sajax a must have for our projects.
It’s almost too easy to implement. Seems like cheating.
21 March 2008, 12:20 amWyatt says:
Ben, glad it’s what you are looking for. Let me know when you make something cool
21 March 2008, 11:04 pmMattias says:
Great work whit this!
4 September 2008, 4:31 amI just love the object funktion you added. Still ran in to a problem trying u’re sajax version out.
I’m from sweden and we got some special chars: å ä ö Å Ä Ö.
And when I try to return myobj.name= “Göran”;
It seams like Sajax cuts the word at ö and returns only “G”.
Do you have any idea, how to fix this?
Once again great sajax version!
Mattias says:
Ahh found the problem and the code get’s a new encoding on the way.
Change my encoding from blabla to utf8.
Sry for last post
4 September 2008, 7:18 amWyatt says:
Glad you found it and you put it here. Hopefully if someone else has the same problem you’ll have given them the right answer
mawan says:
Mattias: How did you change the encoding again ? would anyone please inform me about it ?
28 September 2008, 10:01 pmI put the swedish character in it and still doesnt work even i put meta charset utf-8.
öåä
mawan says:
when i put måwan it gives “m%uFFFDwan” as result
28 September 2008, 10:03 pmWyatt says:
mawan, I’m not sure what the change is that Mattias made. It could be anything from changing the page encoding to changing the PHP/JavaScript functions to understand UTF-8. I’ll see what I can do and get back with you. You could try changing the Sajax.php file around lines 216 and 229 to use encodeURI() instead of encodeURIComponent().
for (i = 0; i < args.length-1; i++) {
//uri += "&rsargs[]=" + escape(args[i]);
uri += "&rsargs[]=" + encodeURI(args[i].toJSONString());
}
:229
for (i = 0; i < args.length-1; i++) {
//post_data = post_data + "&rsargs[]=" + escape(args[i]);
post_data = post_data + "&rsargs[]=" + encodeURI(args[i].toJSONString());
}
Tim Powell also has a solution over here. You’d need to take his function and include them into the Sajax.php before the JavaScript gets written to the page if you wanted to replace the encodeURIComponent() with his encodeURIComponentNew().
Of course, I’ve not tested any of this so your mileage may vary. Again, I’ll see if I can find out what Mattias did to make it work and let you know.
mawan says:
Heyy Wyatt,
Thanks a lot for your great reply !
I was actually able to fixed the problem after couple hours stuck on my laptop.
It was my application that did “utf8_encode()” of an already utf8 values from the database. Among all other encoding configuration problems, but due to this I was able to learn a lot bout it.
Your tweaks on sajax+json rocks ! seriously, now I can continue develop my apps so it’ll be able to run functions on background without all those explode function and appending delimiters.
29 September 2008, 7:05 pm