My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.
Showing posts with label Jaxer. Show all posts
Showing posts with label Jaxer. Show all posts

Thursday, August 06, 2009

PAMPA-J Destiny?

One of my favorite Windows Desktop Application Project, PAMPA-J, is not dead ... it is simply "waiting events", if any.

What Is Going On With Aptana Jaxer


I have no idea! The most exciting news about PAMPA was the J at the end: Jaxer.
Apparently this project is in stand-by: while it has been always present in the Aptana Home Page, it disappeared even from Aptana Cloud Page - apparently, they are not hosting Jaxer anymore ... cool! What should I do then? I know is there a way to go in the Jaxer page, but at the same time precedent signs let me think something truly bad happened to this project. Does anybody have any idea about it?

What Is Going On To PECL For Windows


We all know the "official site" is useless since ages:

The pecl4win build box is temporarily out of service. We're preparing a new build system.

I know PHP 5.3 put in core a lot of PECL libraries such mbstring, iconv, APC, APD, etc etc ... but I wonder when we will be able to add our favorite custom libraries without compiling them for a single machine. I am particularly waiting for runkit and operator, but apparently these two extensions are not going anywhere and PHP 5.3 support is not ready yet. Does anybody have an idea about PECL?

What Is Going On With PHP 5.3


Apparently, the PHP team has to celebrate a lot for their 5.3 release. It is the first time in years they come out with a release that is not overpatched after few days.
As soon as they announced PHP 5.3 I installed it in PAMPA-J without problems (change the php.32 folder, overwrite a couple of apache dedicated files, that's it, some minor simple change in the php.ini and nothing else).
At the same time I was sure in few days they would have patched 5.3 with a 5.3.0.1 but it did not happen. After holidays, and too many days from the event, I am waiting for the 5.3.1 already available as dev distribution.

What Is Going On With MySQL


Good question! After I released PAMPA-J, MySQL has been acquired by Oracle. Right now I have no idea how is the MySQL development status, neither which version should I put in the next PAMPA-J.

What Is Going On With Apache


Nothing so far, but at least I realized for Apache 2, 2.X in PAMPA-J, the suggested PHP version is the one compiled in VS2005 and not 2008 (suggested for IIS). Next PAMPA-J will contain the right version of PHP to guarantee better stability.

What Is Going On With Me


I have to admit I am a bit bored by PHP Programming Language. The language itself is great and fun, but its intrinsic limitations plus missed PECL plus people still writing $email to retrieve a posted mail field, plus articles that are never up to date and suggest PHP4 code, plus people still complaining about short tag while PHP problems are, trust me, much more than that ... plus me working over C# and .Net since months, plus me interested in django, plus ... well, you got the point, PHP is behind as programming language, even behind JavaScript, surely behind Python, Ruby, Java, C#, and others.
I am not talking about "what you can do with PHP look there is Wikipedia and Facebook", I am talking about language malleability, features, etc etc ... just the fact somehow operator overload is not supported slashed me on the floor every time I think about the next revolutionary library able to make everything type hintable. No way ... they are pushing so much to badly clone Java language without considering missed overload, mess with public and static, slow OOP against procedural, double API for everything (OOP/procedural) ... guys, what the hell is becoming PHP language? The Emperor of hybrids languages, so hybrids that one day it will be slower than every ther due to SPL massive usage from everybody trying to surpass PHP limits. Ok, it's malleable cause SPL let us do that stuff, but how much slower is an OO application entirely based on getter and setter for a language that was truly fast when used procedurally? Make a decision, take a direction ... frameworks are castrated right now and there is something wrong we should get rid of ASAP. That's me about PHP.

Sorry for delay, hopefully next PAMPA will arrive soon!

Sunday, March 01, 2009

PHP to Jaxer Server And Vice-Versa

Basis

If we have a configuration Jaxer + PHP, as is as example in my pampa-j project, we should know that these two languages cannot directly interact as is, for example, with Jaxer and Java.
The interpreted and executed order is this one:

  1. the PHP module parses the request and the page before Jaxer module

  2. after PHP has finished its stuff, the Jaxer Server module parses the page which could has been modified during PHP execution

  3. after the Jaxer Server has finished its stuff, the user receives the generated page

Above order means that we can pass variables to Jaxer but we cannot pass back results to PHP

<?php // simple variable from PHP to Jaxer
$myVar = 'Hello World';
echo '<script runat="server">
myPHPVar = '.json_encode($myVar).';
onload = function(){
// will show Hello World
document.body.innerHTML = myPHPVar;
};
</script>';
?>

As summary, if we print out a script tag wth a valid JavaScript for server, client, or both, Jaxer Server will consider that tag as part of the page to execute.


The Other Way Round?


Since Jaxer Server parses tha page after PHP has finished, and since PHP will not be connecte to the Jaxer Module and will simply close its thread, during Jaxer page generation/parsing we cannot use PHP because there is no connector as is for Java.
At this point we could create a workaround using one of these strategies and considering that all we gonna do will be on the server, before the client will receive the page:

  • create a socket via PHP and connect to it via Jaxer during its page parsing

  • call somehow PHP runtime during Jaxer Execution


While the first point requires skills and the possibility to change server configuration, the second option could be implemented via Synchronous Ajax call from Server to Server.


Sounds Insane, but it is working!

These is a simple test case I created to show you how it is possible to communicate PHP to Jaxer (creating a specific object) and vice-versa, calling PHP functions runtime via Jaxer.
The final concept is showed in next snippet:

<?php
// require the Jaxer.php file to prepare
// the Jaxer.PHP object
// Jaxer is interpreted after PHP
require 'Jaxer.php';
?>
<script runat="server">
// a simple test case, monitor the tme
var t = new Date;
onload = function(){

// retrieve the length of a string
var len = Jaxer.PHP.call("strlen", "test"), // 4
myFuncResult;
try {

// change runtime the page to call
Jaxer.PHP.url = 'myFunc.php';

// call a function defined in that page
myFuncResult = Jaxer.PHP.call("myFunc"); // "Hello Jaxer Server"

// call something undefined to test errors
myFuncResult = Jaxer.PHP.call("noFunc"); // shows an error on the catch
} catch(e) {

// show the error
document.body.appendChild(document.createTextNode(e.message)); // error from PHP, if any
document.body.appendChild(document.createElement("br"));
};

// take the elapsed time
t = (new Date - t) / 1000;

// show some information
document.body.appendChild(document.createTextNode(len + " - " + myFuncResult));
document.body.appendChild(document.createElement("hr"));
document.body.appendChild(document.createTextNode("Executed in " + t + " seconds"));
};
</script>

To make above code possible, all we need are a couple of files, the Jaxer.php interpreter:

<?php
/** Runtime Jaxer to PHP
* (C) Andrea Giammarchi
* Mit Style License
*/

// @string your secret password, it will NOT be showed in the client
$JaxerSecret = sha1('my secret pass');

// if Jaxer Server sent a request with a valid secret and a function to call ...
if(isset($_POST['JaxerSecret'], $_POST['Jaxer']) && $_POST['JaxerSecret'] === $JaxerSecret){

/** Error manager
* @param int error level
* @param string file that generated the error
* @param int line that generated the error
* @param mixed the context (optional, not used)
*/
function JaxerError($level, $message, $file = null, $line = null, $context = null){
echo ":".json_encode(array('level' => $level, 'message' => $message, 'file' => $file, 'line' => $line));
exit(0);
}

/** Exception manager
* @param Exception the generic generated Exception
*/
function JaxerException(Exception $e){
JaxerError($e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine());
}

// error manager configuration
@set_error_handler('JaxerError');
@set_exception_handler('JaxerException');

// Jaxer variable is a serialized object with two properties
// - the name of the function to call
// - one or more arguments to send to use with called function
$js = json_decode($_POST['Jaxer']);

// the Jaxer to PHP result is always a JSON serialized result
echo json_encode(call_user_func_array($js->name, $js->arguments));
} else

// Jaxer needs to know the secret
// and to use the Jaxer.PHP
// this is created runtime via PHP
echo '<script runat="server">'.
str_replace(
'{JaxerSecret}',
$JaxerSecret,
file_get_contents('Jaxer.php.js') // read the file
).
'</script>';
?>

the Jaxer.php.js file with the JavaScript runtime created object:

/** Runtime Jaxer to PHP
* (C) Andrea Giammarchi
* Mit Style License
*/
Jaxer.PHP = {

// the url with Jaxer.php file
url:"Jaxer.php",

// the PHP.call function
// Accepts the name of the PHP function to call
// plus zero, one, or more arguments to send
call:function(slice){
var send = {
async:false,
method:"POST",
onsuccess:function(response){
if(response.charAt(0)===":"){
var result = JSON.parse(response.substring(1)),
e = new Error;
for(var key in result)
e[key] = result[key];
send.result = null;
throw e;
} else
send.result = JSON.parse(response);
}
};
return function(name){
send.url = Jaxer.PHP.url;
Jaxer.XHR.send(
// {JaxerSecret} is replaced via PHP
"JaxerSecret={JaxerSecret}&Jaxer=" + encodeURIComponent(
JSON.stringify({name:name, arguments:slice.call(arguments, 1)}
)), send);
return send.result;
}
}(Array.prototype.slice)
}

... and finally, a generic page with one or more functions defined, in this case the myFunc.php file:

<?php
// require the Jaxer to PHP manager
// if this page is called directly
// the secret will NOT be whoed
// while if this page is called
// via Jaxer.PHP, the manager
// will simply execute the required code
require 'Jaxer.php';
function myFunc(){
return 'Hello Jaxer Server';
}
?>

The secret is a truly simple security system to avoid direct php page calls and since it is interpreted only on the server, the client will never know this secret (unless our server is not exposing source codes, in this case the secret should be already hashed via sha1 in the source).


Pros And Cons

This strategy could sound cool but it is not the ideal way to interact between these two different modules. The Jaxer to Java way is much better but at least here we have the possibility to send back something or to do via PHP something impossible to do via Jaxer. The fact I put a timer to monitor the delay means you should pay attention because this way is extremely slow. The ideal case scenario is, when absolutely necessary, call PHP only once, creating a clever function able to receive one or more arguments, delegates tasks in the current PHP code, and send back a single object with one or more results. In few words, if you are able to perform one single call to send and receive everything you need, this solution could be fine. In every other case, this solution could require an insane stress for the server and for a single page to show.

In any case, have fun :)

P.S. Here I am with a zip file to test directly this post code

Monday, January 26, 2009

PAMPA-J calls for tests

More downloads, and as usual more problems caused by different configurations.
I would like to leave a single official 1.0 release in Google Code PAMPA-J Project page but I need your tests to do this.

Test I would like to perform with your configurations:

  • PAMPA starts (default configuration: Apache, MySQL, PHP, Jaxer)

  • PAMPA works from every folder (Desktop, Documents, others)

  • PAMPA closes processes on stop and/or exit

  • PAMPA works from network as well (old version could be launched from another PC without problems and respecting paths)


All above tests passed without problems for me, but I would like to be sure it works properly in other environments. Would you help me? Cheers :-)

Saturday, January 24, 2009

PAMPA 1.0 - Jaxer included!

Update - Windows Home Fixed!
Version 1.0b contains hot fixes for Window$ Home Edition plus some little change to make PAMPA more robust than before during process managment.
If you already downloaded version 1.0 you can download only the Tray executable and rename it as PAMPA.exe

Please tell me if you have still problems, hoping this b version will be the final 'till 1.1 ;-)

Update
Final Version 1.0 now served via Google Code ;-)



I am proud to announce the first Release Candidate final 1.0 release of my tiny precious PAMPA, jumped from version 0.7 to 1.0 and rewrote from the scratch considering every suggestion its users gave me during these years (project born in 2006 and completely revisited for version 1.0)

What is PAMPA-J


PAMPA means Portable Apache, MySQL, and PHP Application, in this release with Aptana Jaxer included!
(shell I consider PAMPA-J a portable Aptana Cloud?)

What does it mean: Portable


PAMPA is the first customizable and portable WAMP environment that includes Jaxer and that is completely free (but of course donations are always appreciated).
You can launch PAMPA from an USB driver, a CD-ROM (without native database write capabilities), an external Hard Disk, your Hard Disk itself, configuring MySQL data folders, session folders via php.ini, Apache folders, Jaxer folders, and reading logs, changing configuration, in a truly simple way.

Where is it?


For some reason Google Code policy is to ask sourceforge about projects with the same name, so in Google Code I had to change PAMPA project name into PAMPA-J, considering that somebody created an empty PAMPA project in sourceforge 1 year ago, while PAMPA exists at least since February 2006 ... anyway, the link I provided already should not show the RC release yet, while this one, directly from the svn, is the unofficial Release Candidate 1 Direct Download

How does it work?


All you need to do is to choose a folder to decompress PAMPA and then launch PAMPA.exe from that folder, wherever it is.
The result, by default, should be a fully configured Apache, MySQL, PHP, and Jaxer environment for your Window$ 2000/XP/Vista/7 Operating System.
I am working to create a better "splash page" to introduce PAMPA, but right now the Release Candidate shows simply the Document Root with links for some file, Jaxer public folder included ;-)

What's in



  • Apache 2.2.11

  • MySQL 5.1.30-community

  • PHP 5.3.0 alpha 3 (RC1)

  • Jaxer 1.0.2.4347

  • phpMyAdmin 3.1.2



Why all this effort for a Release Candidate?
Because I am looking forward for your feedback, in order to release the first portable WAMP plus Jaxer environment with all you need to develop for your own or for distributions your applications and with all you need (in a reasonable way :D)


PAMPA-J is out, have fun! 8-)

Thursday, March 06, 2008

Jaxer and packed.it ... not possible yet

Unfortunately, my experience with Jaxer has been really cool but this project is too young to be used as a server side project, and this is only my opinion.

First of all, the simple File API is great, but if you look for binary safe in the search form, you'll be redirect in an empty page ... quite hilarious, isn't it?!

Anyway, I did not test the file.open("wb") mode, probably it's working, probably not ... who care about that? Me, because to pre compile packed.it projects using MyMin and then Zlib I need to write in binary mode ... no way guys!

At the same time, there's not a true bridge for Java, at least that what I was looking for, since Jaxer could be integrated with TomCat, I wonder what are they waiting for to create an easy interface to call directly Java, or whatever mature server language you want.

It will be an extreme start up improvement for your project, what's not possible yet, will be with some Java, Mono, Python, Ruby, PHP, or whatever is it, wrapper.

Is this in your roadmap? None, I can read about DRW but come on guys, the server before the client!

You can have the best Ajax based solution on client, but if the server could do things that a basic PHP / JS interaction could do since 2000 or before, I wonder why you are putting so much effort on client side, where we have a lot of choice, while what we do not have, is simply Jaxer, but on server ;)

Finally, good stuff, and good project, I wish you all the best but please, think about Ajax after a good bridge ... and of course, I eat JavaScript in the morning and I compile them during the night :lol: ... are you still looking for a JS ninja ?

Enjoy Jaxer, at least for fun, this project will become awesome the day it will integrate JS2 engine!


P.S. I created a parseIni method as well ... this is not probably perfect but hey, about 20 minutes debug included :geek:

MyMin = {Creator:function(){}};
MyMin.Creator.prototype.parseValue = function(value){
var result;
switch(true){
case value instanceof Array:
result = [];
for(var i = 0, length = value.length; i < length; i++)
result[i] = this.parseValue(value[i]);
break;
case /^true$/i.test(value):
result = true;
break;
case /^false$/i.test(value):
result = false;
break;
case /^[0-9]+$/i.test(value):
result = parseInt(value);
break;
case /^[0-9]*\.[0-9]+$/i.test(value):
result = parseFloat(value);
break;
default:
result = value;
break;
};
return result;
};
MyMin.Creator.prototype.parseIni = function(fileContent){
var self = this,
pos = 0,
result = {},
trim = /^\s+|\s+$/g,
section,
name,
value;
while(pos < fileContent.length){
pos = fileContent.indexOf("[");
if(pos < 0)
break;
fileContent = fileContent.substr(++pos);
pos = fileContent.indexOf("]");
if(pos < 0)
break;
section = fileContent.substr(0, pos++);
if(!section)
continue;
fileContent = fileContent.substr(pos);
pos = 0;
result[section] = {};
fileContent.replace(/(\[.+\]|.+=[^;\n\r]+)/gm, function(match, sub, p){
if(pos === 0 && /^\[.+\]/.test(match))
pos = p;
else if(pos === 0){
value = match.split("=");
name = value[0].replace(trim, "");
if(/\]$/.test(name)){
name = name.substr(0, name.indexOf("["));
if(!result[section][name])
result[section][name] = [];
result[section][name].push(self.parseValue(value[1].replace(trim, "")));
}
else
result[section][name] = self.parseValue(value[1].replace(trim, ""));
}
});
fileContent = fileContent.substr(pos);
pos = 0;
};
return result;
};