
NuSphere have been promising it for ages, but its taken a man known only as iflo to build the Firefox etension for the DBG debugger. Now I can start a debug or profiling session right from Firefox. Thank you iflo. Note that Firefox may complain about the extension having an invalid hash, but it will install ok nevertheless.
Now, that does bring me to a little side note about PHP IDEs. I have spent months at a time in both Zend Studio and PhpEd, both of which have their ups and downs. I find Zend's IDE to be a bit buggy and slow. Sometimes it takes a whole minute to display the interface when switching between apps. Maybe that's a Java issue... as perhaps is the mouse selection bug I often get which requires a restart of the app. On the plus side, it has a great profiler - better than the NuSphere one, for sure - but I'd prefer not to have to install an entire server platform in order to use it. The Nusphere debugger/profiler is just a PHP extension. Simple and easy to install and configure. Plus the IDE is fast and supports handy stuff missong from Zend - smarty syntax highlighting, better HTML support (code templates, toolbars etc) and configurable help (eg: you can add MySQL 5 and ADODB help files so they can be accessed from the IDE). After 18 months of trying every other IDE (Eclipse, PHP Edit etc) I always come back to PhpEd, which I've now officially made my home with a pro license :)
| [ 0 trackbacks ] | permalink | related link |




( 3 / 38 )I know, this is a pretty specific problem, but I solved it nonetheless :)
Basically, if you are using NuSOAP Web services and you want to register a static class function then you need to use ".." instead of "::".
For example,
class object{
private $soap;
__construct($soap=null)
if($soap !== null){
$this->soap = $soap;
$this->soap->register('object..static_fn');
}
static function static_fn($in){
return $in;
}
}
| [ 0 trackbacks ] | permalink | related link |




( 2.9 / 29 )Still using HTMLArea for your CMS and other HTML editing in the browser? Maybe you should check out Xinha (pronounced Zena, as in warrior princess).
| [ 0 trackbacks ] | permalink | related link |




( 3.1 / 28 )I love stuff like this. IE Tab is a FireFox extension that lets you open the current page in a new FireFox tab using Internet Explorer! This is great for Web testing, but it's also an awesome back-up plan for those damn Web sites out there that just don't work in FireFox/Mozilla. Just middle-click the "View this page in IE tab" from the FireFox right-click menu and blammo....
| [ 0 trackbacks ] | permalink | related link |




( 3.1 / 29 )I've done a fair bit of test driven development (TDD) using Nunit (ASP.NET) and PHPunit/SimpleTest (PHP), and they're great frameworks. There's nothing like watching all your green lights turn on after a hard day's coding, knowing that you've added to the code base but broken nothing in the process...
Unfortunately, working with AJAX means that a lot of your business logic needs to be moved or replicated in the client (ie: browser). While you can isolate the business code from the presentation layer per se, your server-side tests aren't ging to pick up errors in your JavaScript.
What I've found is that even JavaScript unit testing isn't going to solve the problem outright, as some errors involve display issues found in certain browsers or under certain conditions. If you need to know that an HTML element is visible and in exactly the right location, you need to do visual testing. That usually involves humans (damn! damn! damn!).
And that brings me, finally, to the point of this entry. Selenium IDE is a FireFox extension that can record your Web usage and save the result as a test - complete with assertions and validation. You can also run your tests in any browser to ensure that your site is working across the board. While it's no replacement for unit testing your server side code, it is a marriage made in heaven - at least as far as I am concerned.
More green lights and more automation, two of my favourite things :)
| [ 0 trackbacks ] | permalink | related link |




( 3.1 / 27 )Just a quick mention of a bug I came across in XAJAX today. When passing objects or associative arrays back to PHP via xajax.call() the ObjectToXML function fails to pass and parameters with numeric values.
It appears that the replace() function fails as integers are, well, not strings... So my workaround is to convert the object parameters to strings first. Not elegant, but functional - although my validation routines can no longer test is_int() from PHP and I need to use intval() instead. Of course, I could rewrite the xajax.ObjectToXML() function, but I'll wait to see whether anyone else can verify this as a bonafide bug first :)
| [ 0 trackbacks ] | permalink | related link |




( 3 / 28 )Earlier today I wrote about using PHP class constructors to wire-up public methods to xajax. After some perusing of the xajax source code I discovered another way of doing this. It's simpler in some ways, but not as versatile. It's called "registerCallableObject()"!
If you are registering your class public methods with xajax like this:
$this->xajax->registerFunction(array('js_method_name', $this, 'public_method_name'));
Then you should think about doing this instead:
$this->xajax->registerCallableObject($this);
This automatically exposes all the public methods of the object to ajax.
For example, I am using a database insert method that works like this:
public function insert_ajax($array, $callback = null, $args = null){
//--snip--
//insert record via insert method
$this->id = $this->insert();
$objResponse = new xajaxResponse();
//assign new id to JS variable
$objResponse->Script("new_id = ".$this->id.";");
//make JS variable available to calling function via a callback
if (!is_null($callback)){
$objResponse->Script("$callback;");
}
return $objResponse;
}
This way I can pass an array/object to xajax and then work with the new insert ID value in the callback function:
function new_object(){
my_data = new Array();
my_data['name'] = 'BugFeatures';
//this is the undocumented bit!
//you need an array to pass to call() that contains an array of parameters to send to your class method
options = new Array();
//the callback can be a function in a link JS file, but I'll use an alert here for now
callback = "alert(\"New ID = \" + new_id);";
//these are the paramaters to send to my PHP class method
parameters = new Array(my_data,callback);
//add the paramters to the xajax options array
options['parameters'] = parameters;
//do it!
xajax.call("insert_ajax",options);
}
As expected, when I call new_object() a database record is inserted and an alert appears with the new ID!
Why would I do this? It's significantly less code and it's automated.
Why wouldn't I do this? If you have multiple objects instantiated in the same class then xajax will pick the first one it finds, and that may not be what you want. It's fine for static functions like data inserts, for example, but not for data updates etc.
| [ 0 trackbacks ] | permalink | related link |




( 2.9 / 35 )The Sydney Morning Herald posted a news item yesterday questioning the ongoing feasibility of viral marketing. The problem they identify is that Web users are no longer interested in thinly disguised advertising campaigns masquerading as entertainment. Fair enough. Even if there is a prize to be won, most people would rather be surfing sites with interesting content than participating in advertising schemes.
So the bad news for the advertising and marketing folks is that people are becoming a little more informed and wising up to the game. The good news for Web site co-ordinators is that the mechanism of viral marketing is as valid as ever. The catch is that you have to provide something of value to your visitors...
For me - as a 'Micro-ISV' with a viral marketing style product (Send2Friend) - I see it as a renewed movement away from gimmicky pseudo-sites towards content-focused sites. People will still refer your site to a friend if it offers something useful. That's partly why (interesting) blogs are such a good way of getting noticed.
My conclusion is this. Rather than spending big dollars on a glossy advertising campaign that has a built-in lifespan, you're better off diverting resources to improving your core Web site - tutorials, help, tips, news etc (and now for the thinly disguised marketing campaign...). Then you use a low-cost referral tool (like, say, for instance, maybe Send2Friend!) to allow your visitors to share that content with their friends and colleagues.
Whether you build it yourself or you use a service provider, it has to be easy to use, good-looking and not interfere with the Web browsing process (ie: no popups or page refreshes). That's why Send2Friend uses AJAX and GUI themes. If you can build an opt-in mailing list at the same time, you've got a double whammy!
| [ 0 trackbacks ] | permalink | related link |




( 2.9 / 37 )You would think that this is a simple thing to do, but there is a problem that eludes many newcomers to AJAX. I talked about this in my last entry on PHP classes with built-in AJAX functions, but now I want to wrap the whole thing up properly without confusing the issue (too much).
Here's the code I showed before:
var my_var = null;
function doajax(){
xajax_call_that_sets_my_var();
alert(my_var);
}
doajax();
doajax();
The first alert will show null, whereas the secoond alert will show the value of my_var set by the first call to doajax()! This is because the ajax call is asynchronous and isn't completed until your current script block has completed. Thus, any variables you set or HTML elements you change are not executed until after your function or script block is completed. That's why, I discovered after much trial and error, you cannot write a function in JavaScript that inserts a database record and then displays the new ID value like this:
var new_id = null;
function insert_record(){
xajax_call_that_inserts_record();
alert(new_id);
}
Assuming you are doing something like this in the PHP:
$objResponse->Script("new_id = ".$this->id.";");
The value of new_id is not set until after insert_record() is executed. So, how do you get the value of a variable set by an ajax call from within the same function that called it? The secret is to move the code that refernces the variable into another function that is called from within the response object. Have I lost you yet? Here's the answer as code:
$objResponse->Script("new_id = ".$this->id.";");
$objResponse->Script("function access_new_id(){alert(_new_id);}");
$objResponse->Script("access_new_id();");
This will work because the function access_new_id() will be executed after the ajax call is complete! It's so simple but so elusive, and there are dozens of threads about it on the xajax forums but no-one makes it painfully clear (at least they didn't to me!).
Now, depending on what you are trying to do with the variable, you could put the access_new_id() function in the javascript of the page instead. This way, you can create a library of tasks in a linked JavaScript file that are called from within your PHP class methods!
Hope this helps!
| [ 0 trackbacks ] | permalink | related link |




( 3 / 42 )I am writing a code-generation tool in PHP that builds CRUD classes (Create-Update-Retrieve-Delete) from a database. It uses PHP5 and each of the properties are private so that you need to use public SET and GET methods to manage them. This is good, as I detect the database column properties such as data type, whether it is nullable, if there is a default value etc and use these features to write validation routines inside the SET methods.
Now I am also using xajax to call these class methods and I wanted a way to automate the registration of each method with xajax.
To do this, I pass the xajax object to the class and use the constructor to register all the ajax methods like this:
function __construct($conn,$xajax) {
...
$this->xajax->registerFunction(array('myclass_insert', $this, 'insert_ajax'));
...
}
These ajax methods call the CRUD, GET and SET methods and build a response object for xajax. It works like this:
function insert_ajax($array){
if (isset($array['name'])){
$this->set_name($array['name']);
}
$objResponse = new xajaxResponse();
$this->id = $this->insert();
$objResponse->Script("myclass_new_id = ".$this->id.";");
$objResponse->Script("function set_myclass_id(){alert(myclass_new_id);}");
$objResponse->Script("set_myclass_id();");
return $objResponse;
}
Now, there is something really crucial going on here that no-one in the xajax forums seems to be able to explain clearly, and so it took me a lot of trial and error to work out. I will write about this in a seperate entry as it is so important, but in a nutshell it goes like this...
When you build a response object with script commands that set variables, the variables must be declared in the global scope (eg: in the HTML code, not in the xajax response object). Secondly, these scrips are not run until after the response object is returned. Hence, the values of these variables are not available from the calling function! In other words you cannot do this:
var my_var = null;
xajax_call_that_sets_my_var();
alert(my_var);
The value of my_var will be null until the next javascript function is called. So if you do this:
var my_var = null;
function doajax(){
xajax_call_that_sets_my_var();
alert(my_var);
}
doajax();
doajax();
The first alert will be null and the second alert will be the value set by the first xajax call! Fortunately, there is a way around this. You need to call a follow-up function as part of the request object's script. And that is where I will leave it until the next blog entry!
Now, getting back to the original problem, here is a simplified page that creates an object that registers its own ajax functions automatically:
<?php
$xajax = new xajax();
$city = new myclass($conn,$xajax);
$xajax->processRequest();
?>
<html>
<head>
<php $xajax->printJavascript("includes/xajax/"); ?>
<script type="text/javascript">
var new_id = null;
var myclass = null;
function new_myclass(){
myclass= new Array();
myclass['name'] = 'Sealab';
xajax_myclass_insert(myclass);
}
</script>
</head>
<body>
<button onclick="new_myclass();">Make It!</button>
</body>
</html>
Here I create a new myclass object in PHP and pass the database connection and xajax object to it (these are singletons - ie: we only want one of each at any point in time). The myclass class registers it's ajax functions in the constructor, so I can now call
xajax_myclass_insert(myclass)from JavaScript without having to call
$xajax->registerFunction()in the current PHP page.
Why is this good? Well, if I have 10 objects on the page, each with 10 public methods - that's 100 calls to
registerFunction()that need to be made just so that xajax can access them! Using the destructor method, I can also unregister the methods so xajax doesn't ever try to call methods from a dead object.
Maybe I'm crazy, but I think that this is cool :)
NB: This code is for the 0.5 beta version of xajax and won't work with 0.2!
| [ 0 trackbacks ] | permalink | related link |




( 2.9 / 32 )Back Next



Avatar



