I was writing about new features in the upcoming PHP version (5.4, 6.0?) before. Today's topic reads like this in the NEWS file:
- Added array dereferencing support. (Felipe)
Now you might wonder what this typical short entry means. when doing OO-style PHP you might make use of a sntax feature which one might call "object dereferencing" which looks like this:
<?php class Foo { public function bar() { } } function func() { return new Foo(); } func()->bar(); ?>So one can chain method calls or property access. Now for a long time people requested the same thing for array offset access. This was often rejected due to uncertainties about memory issues, as we don't like memory leaks. But after proper evaluation Felipe committed the patch which allows you to do things like
<?php function foo() { return array(1, 2, 3); } echo foo()[2]; // prints 3 ?>Of course this also works with closures:
<?php $func = function() { return array('a', 'b', 'c'); }; echo $func()[0]; // prints a ?>And even though the following example is stupid I might accept this feature might make one of the few places where it is ok to use references in PHP:
<?php $data = array('me', 'myself', 'you'); function &get_data() { return $GLOBALS['data']; } get_data()[2] = 'I'; // $data will now contain 'me', 'myself' and 'I' ?>Wonderful, isn't it? If you want to test it please take a look at the recent snapshots for PHP trunk and send us your feedback! Please mind that all features in PHP trunk may or may not appear in the next major PHP release.
On NETTUTS.com today there's a new detailed tutorial on how to use the access control list functionality that comes with the CakePHP framework.
If you're building a CMS, you'll probably need different user roles'"superusers, admins, users - with different permission levels. Too complicated to code? Enter CakePHP's ACL (Access Control Lists). With the right setup, you'll be checking user permissions with just one line.They talk about what "access control lists" are but shows you an example of one including the database tables and the full scripts for the Users controller, a model to hook into the database and the view for output to the user. They include methods for denying access, checking permissions, and modifying a user's permissions.
On Developer.com today there's a new post listing ten experimental projects that are "pushing the envelope" in the PHP languages:
As the saying goes, "Just because you can do something doesn't mean you should." But in the world of programming, stretching boundaries is just part of the fun. The PHP community has never been one to shy away from bending their favorite language more ways than a shopping mall pretzel, and as the ten wild projects introduced in this article indicate, the fervor for experimentation is as strong as ever!Here's their list of the ten projects they see as trying to stretch the language to its limits:
On the Ask About PHP blog today there's a new tutorial about integrating the OpenFlashCharts tool into a CodeIgniter application to display data.
I recently upgraded some of my Codeigniter applications that used OpenFlashCharts to using FusionCharts Free, and at the same time incorporated some javascript to allow me to change the graphs dynamically at the client-side. This has greatly improved the usability of my charts and graphs that I pump out. As such, I thought I would share how I did this and hopefully someone will find it useful as well.He walks you through the steps needed to install - putting all of the files in the right places, creating a controller to use the scripts and a view to output the finished chart. A demo of the end result is also included.
In the latest post to his blog Chris Hartjes talks about how he got python and PHP working together as a part of his testing with Hudson.
These days, it's becoming increasingly harder to find web applications that are homogenous in terms of the tools they use to Get Things Done. [...] Loosely coupled components, passing messages to each other, is great architecture to try and build if you have both the skills and patience to make it work.His technique combines the testing of PHPUnit for PHP with the Py.test functionality for Python with the continuous integration tool Hudson to run them both as a part of the same build process.
Have a flair for translation and want to help out an open source project in need? Consider helping the Symfony Project with their translation efforts for their manual.
The Symfony2 documentation is written in English and many people are involved in the translation process. First, become familiar with the markup language used by the documentation. Then, subscribe to the Symfony docs mailing-list, as collaboration happens there. Finally, find the master repository for the language you want to contribute for.Full details on what they need help on and where/how to get involved are on the documentation page of the new Symfony 2 website.
On PHPBuilder.com there's a recent article detailing some of the updates in the latest version of the ExpressionEngine product (CMS) from EllisLab.
This popular Web development solution recently took another major step forward with the July 12 release of ExpressionEngine 2.1, the product's first major upgrade in several years. Version 2 sports a number of new features and significant improvements over its predecessor, many of which I'll highlight in this article.He touches on a few of the updates in this latest revision:
You can find out more about ExpressionEngine on its site.
I finally sat down and started work on a sandboxed DOM API. Originally I was just going to develop a new framework because the DOM is messy but instead I decided it would be cool to have a safe simulated DOM instead and build a framework on top of that.
It isn’t complete yet and there’s still a lot of work to do but it’s working pretty good. I still need to run some tests on it and try to break it but I don’t have time at the moment as I need to do other stuff.
One of the problems making a DOM API is that IE doesn’t have setter support even in IE8 it doesn’t allow you to define setters on normal objects. Because I spend most of my time hacking stuff it was a fun challenge to make IE support setters on DOM objects and keep my sandboxed whitelists.
It’s quite complicated and quite ugly in parts but it works and I think it’s the only way to support legacy browsers like IE7.
How it worksI have to test for the various setter support including defineSetter, Object.defineProperty and revert to the legacy onpropertychange. Object.defineProperty works fine in IE8 when using a DOM object but I encountered problems when I needed to assign to a sandboxed normal object. Here it gets ugly, I had to create a DOM object for any styles used by a node, this way both Object.defineProperty and onpropertychange allow me to monitor any assignments to the fake style object.
var styles = document.createElement('span'); node.$style$ = styles; Object.defineProperty(node.$style$, '$'+cssProp+'$', {}); document.getElementById('styleObjs').appendChild(styles); node.$style$ = styles; node.$style$.onpropertychange = function(){}As you can see with the code sample above I have to append the fake style DOM object for onpropertychange otherwise it won’t be called on assignments.
You can see this working by using the following test code:-
document.getElementById('x').style.color='#ccc';So I proxy off all these functions and make the root node any html object, I use CSSReg and htmlReg to sandbox each modification to a property. Finally where it got complicated was supporting events, currently I only support “onclick” as I’m still testing but what happens is because the code is already sandboxed I don’t need to perform a rewrite so I pass this to JSReg as it’s already been converted, I supply the “this” object as the html element this allows the triggered event to call “this” as the current element.
That’s it! I’ve donated the code to OWASP and it will be free to use in your projects, any help testing or suggestions are most welcome, enjoy the demo!
We are currently working on an app that uses a number of technologies, including PHP, Python, and MongoDB. Recently, a need arose to use sequential identifiers for users, similar to an auto_increment column in MySQL.
If you've used MongoDB, you might be familiar with the default behavior of using a UUID as the primary key. This is convenient, especially if you partition your database across servers, because you don't have to coordinate the primary key in any way. If you use sequential identifiers (as I demonstrate in this post), you can use multiple servers and interleave identifiers by advancing each server's sequence by the total number of servers. (For example, with two servers, advance each sequence by two, so one server generates even identifiers, and the other generates odd.)
I'd rather not discuss the advantages and disadvantages of either approach, because it's exactly this debate that makes it very difficult to find any useful information on using sequential identifiers with MongoDB. Instead, I'm just going to explain how I did it, and hope this is helpful to someone. :-)
First, create a sequence collection that you can use to determine the next identifier in the sequence. The following creates a collection called seq that has a single sequence in it (for users), but you can add as many as you need:
db.seq.insert({"_id":"users", "seq":new NumberLong(1)});If you assign seq to 1 instead of new NumberLong(1), it will be interpreted as a float due to a JavaScript quirk.
Before adding a new user, you need to increment the sequence by one and fetch the next identifier. Fortunately, the findandmodify() command provides an atomic way to do this. Using the MongoDB shell, the command would look something like this:
db.seq.findAndModify({ query: {"_id":"users"}, update: {$inc: {"seq":1}}, new: true });Because I'm using Lithium, I added a method for fetching the next identifier to my User model:
<?php namespace app\models; class User extends \lithium\data\Model { static public function seq() { $seq = static::_connection()->connection->command( array('findandmodify' => 'seq', 'query' => array('_id' => 'users'), 'update' => array('$inc' => array('seq' => 1)), 'new' => TRUE ) ); return $seqTruncated by Planet PHP, read more at the original (another 2980 bytes)
In a new post to his blog today Sean Coates talks about some of his work with Iterators in PHP and how, despite a bad example in the manual, he solved his issue (and updated the PHP manual too).
In the back end, we have models that connect to CouchDB. These models implement the Iterator pattern to allow easy traversal of a record's keys. [...] Little did I realize that this implementation is very broken. [...] Over the past few years, I've implemented many iterators in this way, using PHP's implicit array manipulation functions (reset(), current(), key(), next()). He points out some issues with how PHP handles array index tracking and how, in the previous PHP manual example, it incorrectly checked for "false" against the current array value. His updated version doesn't have this issue. You can see it here.On DevShed.com today there's a new tutorial about implementing the Asirra CAPTCHA system (from Microsoft) into your application for spam prevention.
Unlike other types of captcha that utilize difficult text obfuscation techniques (such as Google reCaptcha), this system utilizes images of dogs and cats, such as those shown in this screenshot.They describe some of the reasons to use the system (hard to break, doesn't use sessions, easy to integrate) and how it works. They show how to implement the system on both the server and client side.
Earlier this week, I spent most of a day tracing through code in search of the source of a bug that was causing part of our application to fail in strange ways.
In the back end, we have models that connect to CouchDB. These models implement the Iterator pattern to allow easy traversal of a record’s keys.
When I wrote the code to implement Iterator several months ago, I dutifully checked the PHP Manual and adapted the reference example that I found there:
<?php class Record implements Iterator { // (partial class, showing the iterator implementation only) public $_data = array(); public function rewind() { reset($this->_data); } public function current() { return current($this->_data); } public function key() { return key($this->_data); } public function next() { return next($this->_data); } public function valid() { return (current($this->_data) !== false); } }Little did I realize that this implementation is very broken. I’ll explain why, below.
Over the past few years, I’ve implemented many iterators in this way, using PHP’s implicit array manipulation functions (reset(), current(), key(), next()). These functions are very convenient because PHP arrays are so powerful — arrays in PHP work like ordered hash tables in other languages.
PHP’s implicit management of an array’s iteration index (the value that is incremented by next() and referenced by key()) is indeed convenient, but the convenience can sometimes be offset by its very implicitness — the value is hidden from you, the PHP programmer.
In PHP, generic array iteration (without the implicit iterator) isn’t actually as simple as it sounds. Remember that arrays aren’t arrays in the traditional sense, but ordered hash tables. Consider this:
$data = array('zero','one','two','three'); for ($i=0; $i<count($data); $i++) { // yeah, don't calculate count() on every iteration echo "{$data[$i]}\n"; }Output:
zero one two threeThis first example is easy to iterate — the array contains sequential, numeric, zero-based keys. It gets more complicated when using non-sequential, and non-numeric keys:
$data = array( 'apple', 'cow' => 'moo', 'pig' => 'oink', 'orange' ); for ($i=0; $i<count($data); $i++) { echo "{$data[$i]}\n"; }Output:
apple orange Notice: Undefined offset: 2 in - on line 10 Notice: Undefined offset: 3 in - on line 10I could use foreach, but because a numeric loop illustrates the point more clearly, here’s how I might implement the above code so that it works:
$data = array( 'apple', 'cow' => 'moo', 'pig' => 'oink', 'orange' ); $k = array_keys($data); for ($i=0; $i<count($data); $i++) { echo "{$data[$k[$i]]}\n"; }Output:
apple moo oink orangeThis brings us back to the Iterator implementation. Why isn’t the code above correct? Take a closer look at this:
public function valid() { return (current($this->_data) !== false); }A value of false in the array is indistinguishable from a false value returned by current(). Using the above implementation with the following array would cause it to bail after orange (and subsequently might cause you to waste a day tracking down the cause):
array( 'apple', 'orange', false, 'banana', );On Tuesday night, I updated the manual to use an improved Iterator implementation. It’s probably a bit slower (so you can use the internal-indexing implementation if you’re sure your arrays will never contain false), but my implementation is more robust.
<?php /** * A mixed-key iterator implementation * * Note: these array_keys() calls are slow. The array keys could be cached * as long as the cache value is invalidated when $_data is changed. */ class It implements Iterator { public $_data = array(); protected $_index = 0; public function rewind() { $this->_index = 0; } public function current() { $k = array_keys($thisTruncated by Planet PHP, read more at the original (another 765 bytes)
Jani Hartikainen has a suggestion for all PHP developers out there - stop using die() for handling errors!
What's the most common pattern for error handling you see in beginner's PHP code? - That's right, do_X() or die('do_X failed);. That's nice and all, as at least you have some sort of error handling, but I think this way of handling errors must go. There is no place for it in modern PHP code - it's the worst way to handle errors, not much better than not handling them at all.He talks about why die() is so bad and some alternatives to it - trigger_error (with a custom error handler) and exceptions. When used correctly, these two can help your script correctly catch and handle errors without the mess of a die().
On his blog today Giorgio Sironi has a response to this post from the I Am Learning PHP blog asking if web scripting languages really need OOP functionality.
Yesterday I came across a question: Do Web-Scripting Languages Really Need OOP? Here's my answer: only if you want to do more than an Hello World script (which is paradoxically how old school programmers measure the utility of a language.) I'll express some of my thoughts without compromises, which will be up to you.He opposes the claims of the other post, noting that there's a reason most PHP frameworks are object-oriented and his concern with some of the comments on the post. He also responds to two of the comments on the post - one about the private scope and the other about namespaces.