… as recommended by readers of Planet PHP :)

Most Recommendations

There were six Firefox extensions that folks repeatedly recommended …

  1. ColorZilla – advanced eyedropper, color picker, page zoomer and other colorful goodies.
  2. FireBug – live DOM & CSS inspector. The single greatest web developer add-on for Firefox.
  3. Live HTTP Headers – view HTTP headers of a page and whilst browsing.
  4. Web Developer Toolbar – adds a menu and a toolbar with various web developer tools.
  5. YSlow – Yahoo’s tool for analysing web pages and telling you why they are slow. Requires Firebug.
  6. Zend Studio Toolbar – debugging assistance for Zend Studio 5.5 and earlier. Isn’t mentioned on the Zend Studio 6 pages, so does that mean it is now obsolete?

… and after that, there was a lot of variety amongst the other extensions that were recommended.

Also Recommended

  1. Cache Status – easy cache status & management from the status bar.
  2. ChatZilla – IRC client for Firefox.
  3. Duplicate Tab – clone a tab along with its history.
  4. Edit Cookies – edit your cookies right in Firefox.
  5. Fasterfox – performance and network tweaks for Firefox.
  6. Firefox Accessibility Extension – test your web pages for functional accessibility features based on the iCITA HTML Best Practices.
  7. FirePHP – print to your Firebug console using a simple PHP function call.
  8. FireShot – take screenshots of web pages, and a whole lot more.
  9. Google Toolbar – Google’s famous in-browser search toolbar.
  10. GreaseMonkey – customise the way a web page displays using your own Javascript add-ons. See also Lifehacker’s Top 10 Greasemonkey User Scripts, and their Better GMail and Better Flickr add-ons to get an idea of just what can be done with Greasemonkey as a Firefox extension tool.
  11. HTML Validator – add HTML validation to your browser.
  12. IE Tab (Windows only) – open Firefox tabs using IE’s rendering engine. See also the popular IE View alternative.
  13. LocationBar2 – adds additional features to Firefox’s address bar.
  14. Lorem Ipsum content generator – Generate “Lorem Ipsum” dummy text, for when you need to fill a page with content for testing purposes.
  15. MeasureIt – draw out a ruler to get the pixel width and height of any element on the web page.
  16. NagiosChecker – see the status of your services and servers in Firefox’s status bar. You do monitor your servers, right? 😉
  17. PrefBar – power user toolbar for Firefox.
  18. Regular Expressions Tester – testing tool for regular expressions with colour highlighting.
  19. RefSpoof – easy spoofing of the HTTP referrer header.
  20. ReloadEvery – reloads a web page every so many seconds.
  21. Save Session – save your current browser windows & tabs for the next time you open Firefox.
  22. Scrapbook – save web pages locally and easily manage collections. (Like OS X web archives, as supported by Together, DevonThink, and so on, but cross-platform).
  23. Selenium IDE – record, edit and debug tests for Selenium, the automated UI testing tool for web developers. See also PHPUnit’s support for Selenium. You do have reproducible testing for you web apps, right? 😉
  24. Stylish – fix ugly sites, customise the look of your browser or mail client by using your own CSS files. Stylish is to CSS what Greasemonkey is to Javascript.
  25. Tab Mix Plus – tab management on steroids.
  26. Tamper Data – view and modify HTTP/HTTPS headers and POST parameters.
  27. TimestampDecode – treats the selected number as a timestamp and displays a decoded date/time.
  28. TitlebarTweaks – tweak Firefox’s titlebar text.
  29. User Agent Switcher – Adds a menu and a toolbar button to switch the user agent of the browser.
  30. Venkman – Javascript debugger for Firefox.

Stu’s Recommends

To round off the list, here are a few extensions that I find useful, but which weren’t recommended. If you haven’t heard of these before, give them a try.

  1. Flagfox – display a country flag in the status bar for the location of the current website’s server.
  2. Server Switcher – easily switch between development and production servers.
  3. Show MyIP – display your current external IP address.
  4. SQLite Manager – Manage any SQLIte database on your computer.

Are you a web developer? Got a favourite Firefox extension that isn’t on this list? Let us know in the comments below.

Be the first to leave a comment »

The folks from Packt Publishing recently sent me another of their books to review. If you’re not familiar with Packt, they’re a relatively new book publisher who are steadily building up quite a range of technology books on open source software, normally written by people involved or close to the software being written about. They’re like a modern day equivalent to the old O’Reilly of the 90’s, only (imho) with higher quality :)

A Bit About Packt

Mastering phpMyAdmin 2.11 for Effective MySQL Management by Marc Delisle is the third edition of this book, and it follows the usual pattern of Packt Publishing books. The book has clearly defined objectives on the cover, and it follows a clear progression of its chosen subject from start to end. It is well presented, with a clear layout and clean page design that makes it easy to read. The book also includes a sizeable index, something no decent technical book can be without.

I’m really pleased to see that Packt are now providing example code online for download, as well as online errata for the book. Many of their earlier books reviewed here on Planet PHP have been criticised for not doing so; it’s great to see Packt improving in this area.

No matter which Packt book you pick up, don’t let the use of language be the reason you put it back on the shelf. Most Packt books are written and reviewed by folks who don’t speak English as their first language. Once you get used to it, it’s never really a problem, but it’s worth pointing it out because if you browse their books at your local bookstore, it might put you off at first.

Introducing phpMyAdmin

If you’ve never heard of it, phpMyAdmin is (imho) one of the most important open source projects for the LAMP stack. phpMyAdmin provides a web-based admin interface for MySQL, making it extremely easy for folks new to the LAMP stack to start working with databases, and a very convenient way to avoid firing up the MySQL command-line if you need to check something or make changes to your databases.

It feels like phpMyAdmin has been around forever.

Unfortunately, it looks that way too at times. In the post Google Maps world of AJAX enabled slick and efficient user interfaces, phpMyAdmin’s usefulness can be hampered by its Web 1.0 UI, and by its continued reliance of manual configuration instead of a WordPress-like admin panel. Don’t get me wrong, phpMyAdmin is a good tool without equal atm, but it’s a workmanlike and functional tool that younger folks used to the Facebook world find a bit long in the tooth.

About The Book

Marc’s book is aimed both at folks new to MySQL and phpMyAdmin as well as experienced developers such as myself who aren’t aware of the advanced features that have been added over the years. The full chapter list is:

  1. Introducing phpMyAdmin
  2. Installing phpMyAdmin
  3. Interface Overview
  4. First Steps
  5. Changing Data
  6. Changing Table Structures
  7. Exporting Structure and Data
  8. Importing Structure and Data
  9. Searching Data
  10. Table and Database Operations
  11. The Relational System
  12. Entering SQL Commands
  13. The Multi-Table Query Generator
  14. Bookmarks
  15. System Documentation
  16. MIME-Based Transformations
  17. Character Sets and Collations
  18. MySQL 5.0 Features
  19. MySQL Server Administration
  20. Troubleshooting and Support

The first ten chapters cover the basics of using phpMyAdmin. If you’re new to phpMyAdmin, these chapters will be very helpful to you, and if you’ve been using phpMyAdmin for years, there’s still little bits in here that you might not have been aware of before now. I particularly like the way that these chapters often refer back to the configuration settings in phpMyAdmin’s config file. However, towards the end of this section, the material starts to feel a bit rushed, as if the author himself can’t wait to get onto the clever features of phpMyAdmin that have yet to come. If you’re completely new to MySQL, you might find the end of this section to be a little light on detail. I hope the next edition of this book beefs these chapters up a bit.

Like most people I know, my use of phpMyAdmin over the years has tended to stick with the basics: creating and browsing tables. I confess, it’s partly because I’ve found the phpMyAdmin UI to be more and more clunky as time has gone by, a throwback to the days before Google showed us just what could be done with Javascript and AJAX. So the second half of the book, which looks at the more advanced features of phpMyAdmin, were ones I found very educational. I had no idea, for example, that phpMyAdmin now includes an AJAX-based Designer tool, or that I can use phpMyAdmin to generate PDF documentation of my databases. I found these chapters to be very detailed and informative, although again towards the end of the second half of the book, the chapters began to feel a little rushed in places to me.

Conclusion

I have several new starters joining my team in June, and it’ll be interesting to see whether or not they find the book useful as they find their feet in their first job doing PHP web development. One thing’s for sure: I’ll have no hesitation in leaving this book out for them to read.

4 comments »

I’m still working on the next article in my series looking at PHP on servers, so in the mean time, check out this simple way to emulate Ruby’s nice way of handling separate getter, setter and state query methods in PHP:

[code lang="php"]
class Example
{
	private $canCache = false;
	private $cacheXml = null;

	function canCache($newState = null)
	{
		// check if we are querying or changing state
                if ($newState === null)
 		{
 			// we are querying
 			return $this->canCache;
 		}

  	 	// if we get here, we are a traditional getter/setter method
 		if ($newState)
 		{
 			$this->canCache = true;
 			$this->cacheXml = $this->_toXml();
 			return true;
 		}
 		else
 		{
 			$this->canCache = false;
 			unset($this->cacheXml);
 			return false;
 		}
 	}
}

$exObj = new Example();
$exObj->canCache(true);
if ($exObj->canCache())
{
 	// ... do something here
}
[/code]

It isn’t as elegant as Ruby, but it does the job, and it means that your classes don’t have to be full of seperate canDoSomething() and isSomethingAllowed() type methods. I think it makes the code that uses the object a little easier to read, and a little more intuitive. YMMV.

13 comments »

I’ve recently switched my blog from b2evolution back to WordPress. The good news is both “no more spam :)” and “the admin panel works in Safari”, but on the downside I missed the multiblog feature that attracted me to b2evolution in the first place. There is WordPress MU, I suppose, but after coming across a few plugins that warned they didn’t work with WordPress MU, that option didn’t look very appealing.

Ah ha – thinks I – I can fake the multiblog by putting several different blogs on the site, and generating a homepage from the RSS feeds of the individual blogs. Should be simple enough, and it sounds like the perfect nail to hit with the SimpleXML hammer of PHP 5 :) Funnily enough, in work last week we were wondering whether you could use SimpleXML with XML namespaces (alas, we still use PHP 4 at work atm), so armed with the perfect excuse, I set to work.

Getting an RSS 2 feed into SimpleXML is trivial:

[code lang=”php”]
$feedUrl = ‘http://blog.stuartherbert.com/php/?feed=rss2′;
$rawFeed = file_get_contents($feedUrl);
$xml = new SimpleXmlElement($rawFeed);
[/code]

Extracting the information from the RSS ‘channel’ is equally trivial:

[code lang=”php”]
$channel[‘title’] = $xml->channel->title;
$channel[‘link’] = $xml->channel->link;
[/code]

… and so on. Getting at the individual articles starts off just as easy:

[code lang=”php”]
foreach ($xml->channel->item as $item)
{
$article = array();
$article[‘title’] = $item->title;
$article[‘link’] = $item->link;
}
[/code]

… but, if you’re relying on the very thin SimpleXML documentation on php.net, like me you’ll soon run into two problems.

Some of the elements in an item sit inside different XML namespaces. The only way to get at them is to use the children() method on a SimpleXMLElement:

[code lang=”php”]
$dc = $item->children(‘http://purl.org/dc/elements/1.1/’);
$article[‘creator’] = $dc->creator;
foreach ($dc->subject as $subject)
$article[‘subject’][] = $dc->subject;
[/code]

That’s a bit of a mouthful. It’s a bit of a shame that I can’t do this:

[code lang=”php”]
// The following does NOT work!
$article[‘creator’] = $article->dc->creator;
[/code]

… or some variation on that, but the design of XML namespaces makes that impractical. (The XML namespace is actually the URI; the ‘dc’ prefix in a tag like <dc:creator> is shorthand defined in the opening tag at the top of the XML document. Although it would look a bit odd, there’s nothing at all to stop someone defining the ‘dc’ component as ‘dublinCore’ instead if they wanted to).

Having to pass the full URI for a namespace into children() is not my idea of fun! It’d be much better if we could pass in a shorter string instead. The only way to safely do this is to define an array of shortcuts yourself:

[code lang=”php”]
// define the namespaces that we are interested in
$ns = array
(
‘content’ => ‘http://purl.org/rss/1.0/modules/content/’,
‘wfw’ => ‘http://wellformedweb.org/CommentAPI/’,
‘dc’ => ‘http://purl.org/dc/elements/1.1/’
);

// now we can get dublin core content with a lot less typing!
// we also only have to update the code in one place if the namespace URI changes
$dc = $item->children($ns[‘dc’]);
$article[‘creator’] = $dc->creator;
[/code]

You can get a list of the namespaces like this:

[code lang=”php”]
$ns = $xml->getNamespaces(true);
$dc = $item->children($ns[‘dc’]);
[/code]

… but that only works if the XML document defines the prefix ‘dc’ for the namespace ‘http://purl.org/dc/elements/1.1/’. You’ll have to decide for yourself whether it’s a risk worth taking or not.

That’s namespaces tamed, but we’re not quite home yet. The actual ‘content’ part of the article sits inside a CDATA section inside a ‘content’ namespace, and how to deal with CDATA is conspicuous by its absence in the SimpleXML docs (probably because older versions of SimpleXML simply threw CDATA sections away without asking you).

If you have a look at the source code for SimpleXML, test 004 shows how basic CDATA access works.

[code lang=”php”]
$content = $item->children($ns[‘content’]);
$article[‘content’] = (string) trim($content->encoded);
[/code]

With that, the final code to read a RSS 2 feed looks like this:

[code lang=”php”]
// define the namespaces that we are interested in
$ns = array
(
‘content’ => ‘http://purl.org/rss/1.0/modules/content/’,
‘wfw’ => ‘http://wellformedweb.org/CommentAPI/’,
‘dc’ => ‘http://purl.org/dc/elements/1.1/’
);

// obtain the articles in the feeds, and construct an array of articles

$articles = array();

// step 1: get the feed
$blog_url = ‘http://blog.stuartherbert.com/php/?feed=rss2′;

$rawFeed = file_get_contents($blog_url);
$xml = new SimpleXmlElement($rawFeed);

// step 2: extract the channel metadata

$channel = array();
$channel[‘title’] = $xml->channel->title;
$channel[‘link’] = $xml->channel->link;
$channel[‘description’] = $xml->channel->description;
$channel[‘pubDate’] = $xml->pubDate;
$channel[‘timestamp’] = strtotime($xml->pubDate);
$channel[‘generator’] = $xml->generator;
$channel[‘language’] = $xml->language;

// step 3: extract the articles

foreach ($xml->channel->item as $item)
{
$article = array();
$article[‘channel’] = $blog;
$article[‘title’] = $item->title;
$article[‘link’] = $item->link;
$article[‘comments’] = $item->comments;
$article[‘pubDate’] = $item->pubDate;
$article[‘timestamp’] = strtotime($item->pubDate);
$article[‘description’] = (string) trim($item->description);
$article[‘isPermaLink’] = $item->guid[‘isPermaLink’];

// get data held in namespaces
$content = $item->children($ns[‘content’]);
$dc = $item->children($ns[‘dc’]);
$wfw = $item->children($ns[‘wfw’]);

$article[‘creator’] = (string) $dc->creator;
foreach ($dc->subject as $subject)
$article[‘subject’][] = (string)$subject;

$article[‘content’] = (string)trim($content->encoded);
$article[‘commentRss’] = $wfw->commentRss;

// add this article to the list
$articles[$article[‘timestamp’]] = $article;
}

// at this point, $channel contains all the metadata about the RSS feed,
// and $articles contains an array of articles for us to repurpose
[/code]

Don’t forget to add error handling :)

I hope this example helps anyone else who needs to work with RSS 2 feeds, or who needs to know how to work with namespaces and CDATA with SimpleXML.

71 comments »
Page 3 of 3123

This Month

September 2015
M T W T F S S
« Aug    
 123456
78910111213
14151617181920
21222324252627
282930