Archive for category PHP

Lightweight JSONP javascript library

This can now be found at github: https://github.com/IntoMethod/Lightweight-JSONP

Are you one of those that include jQuery or any other library only to be able to use some JSONP in your website? In that case this might be the code for you to read and try to understand. I won’t post any detailed explainations right now but feel free to comment if you wonder anything. I’ve also included a minified version in the bottom.

Update (2012-04-10) Fixed issues/suggestions found by Zach, Gabriel and Pamela (see comments). These updates and fixes can be found on github

Update (2011-06-08) Fixed delete/setting to null as pointed out by Bryan Smith (see comment)

Update (2011-04-29) Added encodeURIComponent as suggested by yched (see comment)

Update: Fixed scoping problem as found by Damon Oehlman (see comment)

Feel free to use this script for anything that you like, commercial or non-commercial, but please keep the comment and link to this site.

Oh and by the way, the script has been tested successfully in the following browsers:
Chrome 4,5,6
Firefox 3.x
Internet Explorer 6,7,8
Opera 9.6+10
Androids webkit-based browser
Symbian S60 browser

First an example of how to use it, to show the simplicity, then the actual code.

JSONP.get( 'someUrl.php', {param1:'123', param2:'456'}, function(data){
        //do something with data, which is the JSON object you output from someUrl.php
        //into the callback javascript method specified by the "callback" value in the querystring
});

A simple example of the someUrl.php (please observe this example does not include any security checks what so ever, just to show the principle):

$myData = fetchSomeData();
 
echo $_GET['callback'];
echo "(";
echo json_encode($myData);
echo ")";

See github link above for current code and examples, the code below is old

The actual code for the Lightweight JSONP functionality.
Around 1.1kb without gzip.

//Lightweight JSONP fetcher - www.nonobtrusive.com
var JSONP = (function(){
	var counter = 0, head, query, key, window = this;
	function load(url) {
		var script = document.createElement('script'),
			done = false;
		script.src = url;
		script.async = true;
 
		script.onload = script.onreadystatechange = function() {
			if ( !done && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete") ) {
				done = true;
				script.onload = script.onreadystatechange = null;
				if ( script && script.parentNode ) {
					script.parentNode.removeChild( script );
				}
			}
		};
		if ( !head ) {
			head = document.getElementsByTagName('head')[0];
		}
		head.appendChild( script );
	}
	function jsonp(url, params, callback) {
		query = "?";
		params = params || {};
		for ( key in params ) {
			if ( params.hasOwnProperty(key) ) {
				query += encodeURIComponent(key) + "=" + encodeURIComponent(params[key]) + "&";
			}
		}
		var jsonp = "json" + (++counter);
		window[ jsonp ] = function(data){
			callback(data);
			try {
				delete window[ jsonp ];
			} catch (e) {}
			window[ jsonp ] = null;
		};
 
		load(url + query + "callback=" + jsonp);
		return jsonp;
	}
	return {
		get:jsonp
	};
}());

, ,

46 Comments

How to prevent setting dynamic fields in your PHP classes

One problem that could arise when multiple coders are working on the same project is that everyone might not work with the same editors, and therefore everyone might not have intellisense / autocompletion. What could this cause? Alot of things 🙂 But we’ll talk about one of them below.

Well all PHP classes are by nature dynamic, which means that it’s possible to set variables that havn’t been declared. One would believe that setting the class to “final” would automatically fix this, but this is not the case.

Simple example:

class SimpleStructure 
{
	public $name;
	public function __construct( $name ) {
		$this->name = $name;
	}
}
 
$simple = new SimpleStructure("nonobtrusive");
$simple->myName = "dynamic_value";	//allowed
 
echo $simple->name, " - ", $simple->myName;

The above code will output:

nonobtrusive - dynamic_value

So, how can we prevent this if it’s an unwanted behaviour ?
The answer is simple, use the magic method __set.

class SimpleStructure 
{
	public $name;
 
	public function __construct( $name ) {
		$this->name = $name;
	}
 
	public function __set( $key, $value ) {
		throw new Exception( "Not allowed to assign undefined variable : " . $key );
	}
}
 
$simple = new SimpleStructure("nonobtrusive");
$simple->myName = "dynamic_value";	//allowed
 
echo $simple->name, " - ", $simple->myName;

The above code would throw the error:

Fatal error: Uncaught exception 'Exception' with message 'Not allowed to assign undefined variable : myName'

To wrap this up we could also create our own UndefinedFieldException class and throw an instance of it to easier catch that specific error.

class UndefinedFieldException extends Exception
{
	public function __construct( $key ) {
		$this->message = "Not allowed to assign undefined field : " . $key;
	}
}
 
//then we can throw the exception like this instead
throw new UndefinedFieldException( $key );
 
//which in the above example would show as
Fatal error: Uncaught exception 'UndefinedFieldException' with message 'Not allowed to assign undefined field : myName'

, , , , ,

1 Comment

Strict standards could break admin css in wordpress

The following method in class.wp-scripts.php could break your css if you have strict standards enabled on your server.

	function set_group( $handle, $recursion, $group = false ) {
		$grp = isset($this->registered[$handle]->extra['group']) ? (int) $this->registered[$handle]->extra['group'] : 0;
		if ( false !== $group && $grp > $group )
			$grp = $group;
 
		return parent::set_group( $handle, $recursion, $grp );
	}

This is because the WP_Scripts inheritance from WP_Dependencies does not follow the signature of the method. WP_Dependencies have the set_group function declared without any default parameters while the subclass have defaulted $group to false.

Easy fix! Just remove the default value on the group parameter so it looks like this:

	function set_group( $handle, $recursion, $group ) {
		$grp = isset($this->registered[$handle]->extra['group']) ? (int) $this->registered[$handle]->extra['group'] : 0;
		if ( false !== $group && $grp > $group )
			$grp = $group;
 
		return parent::set_group( $handle, $recursion, $grp );
	}

The only place I can find this possible being called from send in a value anyway so there’s no need for having the default value as of right now.

5 Comments