Engineered Web
Performance Is Green
pa href="http://www.flickr.com/photos/bike/49226298/"img src="http://engineeredweb.com/sites/engineeredweb.com/files/images/49226298_da8ecc7ad6_m.jpg" width="240" height="228" alt="49226298_da8ecc7ad6_m.jpg" align="right" class="float-right" //aAre you writing and using environmentally friendly software? Have you ever thought of the impact on the environment for the software you've written? Working in front of a computer it can be easy to overlook the impact on the environment due to what were creating. It's not like drinking a beverage out of a styrofoam cup (they don't break down). But, there is an impact. As Internet usage grows in leaps and bounds we need to start taking a closer look at that impact and doing something about it./p
h2Why Performance Is Green/h2
pWhy did Facebook start using a href="http://github.com/facebook/hiphop-php"Hip-Hop/a? a href="http://developers.facebook.com/blog/post/358" title="HipHop for PHP: Move Fast"According to their blog/a,/p
blockquotepWith HipHop we've reduced the CPU usage on our Web servers on average by about fifty percent, depending on the page. Less CPU means fewer servers, which means less overhead./p/blockquote
pWhen we have less servers we use less power, we need less space in buildings, less servers need to be built for our tasks and our overall footprint is smaller./p
pThink about it like this. We buy energy efficient appliances, we talk about turning lights off when we aren't using them, we look at energy efficient cars, and we think about being environmentally conscious. So, why not extend this to what powers our websites.br /
!--break--/p
h2Open Source Has A Major Impact/h2
pOpen Source projects, especially the popular ones, can have a huge impact. Think of the number of sites running a href="http://drupal.org"Drupal/a and a href="http://wordpress.org"Wordpress/a. It isn't just one website or a small amount number of sites. We are talking about millions of sites running on tens of thousands of servers. When a performance enhancement goes into one of these products it can have a broad impact./p
h2The Danger of Premature Optimization/h2
pWhen we try to optimize prematurely we can run into problems. If we optimize for one environment we may not be optimal for another environment. For example, optimizing around a href="http://php.net"PHP/a using a href="http://pecl.php.net/package/APC"APC/a. Then you may not be optimized for all the shared hosting environments not running APC. When we try to do this we need to be careful to avoid premature optimization./p
h2Architecting For Performance/h2
pAt a href="http://cph2010.drupal.org/"Drupalcon Copenhagen/a, a href="http://en.wikipedia.org/wiki/Rasmus_Lerdorf"Rasmus Lerdorf/a gave a keynote where he he made the point that em"Real performance is architecture-driven"/em. Something architecture driven cannot be bolted on as an after thought. Something architecture driven is more than optimization of what's already there. Something architecture driven is in the base of the framework the software is built on./p
h2Energy Star For Open Source Projects?/h2
pa href="http://en.wikipedia.org/wiki/Energy_Star"Energy Star/a is an international standard for energy efficient consumer products. What if we had something like this for the software that powered websites?/p
pImagine if a href="http://www.phpbb.com/"phpBB/a had an energy star like label. Not only would you know it was energy efficient but you would know that it will cost you less to use it than an alternative not designed to perform./p
pAs the world uses the Internet more and more we need to start thinking about the impact of our websites. Software that performs better uses less resources and has a smaller impact. Its time we start to take that into account in mass./pimg src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/8miSUVPc0zE" height="1" width="1"/
Accessing Libraries, Whether In Drupal or Elsewhere
pOne of the assumptions regularly made is that libraries, like a href="http://getid3.sourceforge.net/"getid3/a or a href="http://framework.zend.com"Zend/a, live within the a href="http://drupal.org" title="Drupal - Content Management Platform"Drupal/a directory structure. The popular pattern is to put them in the libraries directory alongside the modules and themes directories. This is very limited both in workflow and accessibility to libraries. What if a developer wants to have a library in the PHP include path so multiple sites, not all of which are Drupal, can share it? What if someone wants to use Pear to manage that library? Let's take a look at a quick pattern for providing for a wide variety of possible locations for libraries.br /
!--break--/p
h2Getting The Path/h2
pIn order to work with the classes and functions provided by the library you need the path to include them. If the library was to be in the include path it would be as simple as:br /
div class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"span style="color: #b1b100;"include/span span style="color: #0000ff;"'path/to/lib/file.php'/spanspan style="color: #339933;";/span/pre/divbr /
But, when you're taking into account the possibility it could be in the include path, in the Drupal directory structure, or elsewhere you need the path to the library.br /
div class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"span style="color: #009933; font-style: italic;"/**
* Retrieve the expected path to the example library.
*
* @return
* The path where the example library is to be expected to be installed.
*
* Note: Replace the example library name with a specific one.
*//span
span style="color: #000000; font-weight: bold;"function/span example_get_pathspan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #666666; font-style: italic;"// A path can be configured to the location of the library./span
span style="color: #000088;"$path/span span style="color: #339933;"=/span variable_getspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'example_path'/spanspan style="color: #339933;",/span span style="color: #000000; font-weight: bold;"FALSE/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
nbsp;
span style="color: #b1b100;"if/span span style="color: #009900;"#40;/spanspan style="color: #339933;"!/spanspan style="color: #000088;"$path/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #666666; font-style: italic;"// Check if the libraries module is installed and if the example library is/span
span style="color: #666666; font-style: italic;"// being supplied through the libraries module./span
span style="color: #b1b100;"if/span span style="color: #009900;"#40;/spanmodule_existsspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'libraries'/spanspan style="color: #009900;"#41;/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #666666; font-style: italic;"// Check if the library is found. If no library is found libraries_get_path()/span
span style="color: #666666; font-style: italic;"// will still return sites/all/libraries as a path./span
span style="color: #000088;"$libraries/span span style="color: #339933;"=/span libraries_get_librariesspan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
span style="color: #b1b100;"if/span span style="color: #009900;"#40;/spana href="http://www.php.net/isset"span style="color: #990000;"isset/span/aspan style="color: #009900;"#40;/spanspan style="color: #000088;"$libraries/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'example'/spanspan style="color: #009900;"#93;/spanspan style="color: #009900;"#41;/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #000088;"$path/span span style="color: #339933;"=/span libraries_get_pathspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'example'/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
span style="color: #009900;"#125;/span
span style="color: #009900;"#125;/span
nbsp;
span style="color: #666666; font-style: italic;"// Check if the example library is in the include path./span
span style="color: #b1b100;"if/span span style="color: #009900;"#40;/spanspan style="color: #339933;"!/spanspan style="color: #000088;"$path/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #000088;"$include_paths/span span style="color: #339933;"=/span a href="http://www.php.net/explode"span style="color: #990000;"explode/span/aspan style="color: #009900;"#40;/spanPATH_SEPARATORspan style="color: #339933;",/span a href="http://www.php.net/get_include_path"span style="color: #990000;"get_include_path/span/aspan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
span style="color: #b1b100;"foreach/span span style="color: #009900;"#40;/spanspan style="color: #000088;"$include_paths/span span style="color: #b1b100;"as/span span style="color: #000088;"$include_path/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #b1b100;"if/span span style="color: #009900;"#40;/spana href="http://www.php.net/is_dir"span style="color: #990000;"is_dir/span/aspan style="color: #009900;"#40;/spanspan style="color: #000088;"$include_path/span span style="color: #339933;"./spanspan style="color: #0000ff;"'/example'/spanspan style="color: #009900;"#41;/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #000088;"$path/span span style="color: #339933;"=/span span style="color: #000088;"$include_path/span span style="color: #339933;"./spanspan style="color: #0000ff;"'/example'/spanspan style="color: #339933;";/span
span style="color: #b1b100;"continue/spanspan style="color: #339933;";/span
span style="color: #009900;"#125;/span
span style="color: #009900;"#125;/span
span style="color: #009900;"#125;/span
span style="color: #009900;"#125;/span
nbsp;
span style="color: #b1b100;"return/span span style="color: #000088;"$path/spanspan style="color: #339933;";/span
span style="color: #009900;"#125;/span/pre/divbr /
The example above checks for the library in 3 different places./p
ol
liA configured location in the variables./li
liIn a libraries folder alongside the modules and themes folders. The dependency on a href="http://drupal.org/project/libraries"Libraries API/a is not required but is checked if available./li
liThe PHP configured include path. This is where libraries can be manually placed or where Pear is typically configured to place them./li
/ol
h2Autoloading Classes and Interfaces/h2
pMany of the libraries include an autoloader to load the classes and interfaces automatically. This way you do not need to manually include each file. An example of doing that could look like:br /
div class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"span style="color: #009933; font-style: italic;"/**
* Implementation of hook_init().
*//span
span style="color: #000000; font-weight: bold;"function/span example_initspan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #666666; font-style: italic;"// Due to the dependency on the libraries module being included, we wait until/span
span style="color: #666666; font-style: italic;"// hook_init() to register the example library./span
span style="color: #b1b100;"if/span span style="color: #009900;"#40;/spanspan style="color: #000088;"$path/span span style="color: #339933;"=/span example_get_pathspan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #b1b100;"require_once/span span style="color: #000088;"$path/span span style="color: #339933;"./spanspan style="color: #0000ff;"'/autoloader.php'/spanspan style="color: #339933;";/span
Example_Autoloaderspan style="color: #339933;"::/spanspan style="color: #004000;"getInstance/spanspan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
span style="color: #009900;"#125;/span
span style="color: #009900;"#125;/span/pre/div/p
pNot all libraries include an autoloader but many still include classes and interfaces. If you would still like to use one checkout the a href="http://drupal.org/project/autoload" title="Autoload Drupal Module"autoload module/a./p
pIf you want the library to be available to all a href="http://api.drupal.org/api/function/hook_init/6"hook_init()/a functions it would be a good idea to set the weight of the library to be lower than all the other modules on the site. And, providing an implementation of a href="http://api.drupal.org/api/function/hook_requirements/6"hook_requirements()/a to check for the library being available and for a library version is useful. Examples of both of these can be found in the a href="http://drupalcode.org/viewvc/drupal/contributions/modules/zend/zend.install?view=markupamp;pathrev=DRUPAL-6--2"2.x branch of the Zend modules zend.install file/a./p
pemNote: The example code is based on the 2.x branch of the a href="http://drupal.org/project/zend" title="Zend Drupal Module"Zend module/a./em/pimg src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/ylFfZXyK5o8" height="1" width="1"/
Safari Reader: An Example Of An Accessibility Failure
pThe recent release of a href="http://www.apple.com/safari/"Safari 5/a brought with it the a href="http://www.apple.com/safari/whats-new.html#reader"reader/a, a new feature designed to simplify articles and posts for users to read. Many modern web pages are cluttered with other images, ads (that pay the bills), and elements that distract from the main piece of content. The reader jumps in to help us with that by simplifying the page and focusing us on the content./p
pThe idea of focusing us is not new. Many applications provide a full screen mode that blocks out the rest of the desktop. a href="http://en.wikipedia.org/wiki/WYSIWYG" title="Wikipedia: WYSIWYG"WYSIWYG/a editors, like a href="http://ckeditor.com/"CKEditor/a, include an option to take it full screen. The clears out the other clutter and lets you write without being distracted./p
pstrongThe problem is the new reader is not accessible because you can barely see the links./strongbr /
!--break--br /
img src="http://engineeredweb.com/sites/engineeredweb.com/files/images/screen-shots/Safari-Reader-AC-Links.png" width="598" height="493" alt="Safari-Reader-AC-Links.png" class="image-border" //p
pA great example of where this is a problem is with a href="http://wikipedia.org"Wikipedia/a. Articles on Wikipedia regularly link off to other articles. The goal is not to have all the content in one place. Instead you link off to other sources. When you cannot see the links to follow them elsewhere this becomes a problem./p
pThis problem may not seem like much of one for people with young eyes that see well. For those with aging eyes and color blindness issues this becomes a real problem. a href="http://en.wikipedia.org/wiki/Color_blindness" title="Wikipedia: Color Blindness"Color blindness/a affects a significant portion of the population. When it comes to web accessibility this is important to take into account./p
pOlder eyes from the growing population Internet users, also, have trouble seeing the subtle variations. Their eyes do not adjust as well and noticing the subtle links is a problem./p
pIn any case, the Safari 5 Reader provides a lesson of what not to do with accessibility./pimg src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/uDd_i0eD6CU" height="1" width="1"/
Installing and Using The Zend Framework Via Pear
pimg src="http://engineeredweb.com/sites/engineeredweb.com/files/images/logos/pear.png" width="250" height="125" alt="pear.png" class="image-border float-right"/When I use the same library or framework on many sites being able to manage and reuse the code for it across the different projects and tinkerings makes development that much faster and easier. Instead of dealing with the code management I can work with using the code. This is the case when I use the a href="http://framework.zend.com"Zend Framework/a. So, instead of downloading and installing it each time I use it I installed it one time and use it everywhere with a href="http://pear.php.net"Pear/a.br /
!--break--/p
h2What Is Pear?/h2
pPEAR is the PHP Extension and Application Repository. Put simply, it's a tool for managing packages of PHP code. A project can setup a Pear channel describing their projects. That channel be be subscribed to and with a few simple commands they can be installed and managed./p
pFor example, the a href="http://www.twig-project.org/" title="Twig - The flexible, fast, and secure template language for PHP"Twig Project/a is a templating layer for PHP. That project setup a Pear Channel. With two commands at the command line Twig can be downloaded, installed, and available to all the sites on the system./p
h2Installing Zend With Pear/h2
pTo install a project with Pear the first step is to discover the channel. This provides Pear with the knowledge about the channel and the packages it has information about. Since Pear is decentralized it needs to know about the Pear channels you want it to know about./p
pThe Zend Framework does not have an official Pear channel. But, one has been setup on Google Code. To subscribe to the channel type the following at the command line:br /
div class="geshifilter"pre class="bash geshifilter-bash" style="font-family:monospace;"$ pear channel-discover zend.googlecode.comspan style="color: #000000; font-weight: bold;"//spanspan style="color: #c20cb9; font-weight: bold;"svn/span/pre/div/p
pemNote: I am assuming Pear is properly installed and configured. Pear is included with PHP and is setup and configured in most cases./em/p
pAfter Pear has discovered the channel installing a package is really simple. To Install the latest Zend Framework simple type:br /
div class="geshifilter"pre class="bash geshifilter-bash" style="font-family:monospace;"$ pear span style="color: #c20cb9; font-weight: bold;"install/span zendspan style="color: #000000; font-weight: bold;"//spanzend/pre/div/p
pThe latest release of zend will be installed into the repository of pear files on the system. When configured properly this location is part of the a href="http://www.php.net/manual/en/ini.core.php#ini.include-path"include path/a within PHP and accessible everywhere./p
h2Using Zend From Shared Location/h2
pNow that the Zend Framework is installed we can put it to use. In a new file we can start with the following:br /
div class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"span style="color: #000000; font-weight: bold;"lt;?php/span
nbsp;
span style="color: #666666; font-style: italic;"// Load and initialize the Zend Autoloader./span
span style="color: #b1b100;"require_once/span span style="color: #0000ff;"'Zend/Loader/Autoloader.php'/spanspan style="color: #339933;";/span
Zend_Loader_Autoloaderspan style="color: #339933;"::/spanspan style="color: #004000;"getInstance/spanspan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
nbsp;
span style="color: #666666; font-style: italic;"// Test it out./span
span style="color: #000088;"$form/span span style="color: #339933;"=/span span style="color: #000000; font-weight: bold;"new/span Zend_Formspan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span/pre/div/p
pThe first thing we do is load the autoloader with:br /
div class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"span style="color: #b1b100;"require_once/span span style="color: #0000ff;"'Zend/Loader/Autoloader.php'/spanspan style="color: #339933;";/span/pre/div/p
pSince Zend is in the include path it knows where to look to load the file from. Following that we are able register the autoloader, use the Zend classes, and let the autoloader load the necessary files for us. Since they are all in the include path they are accessible to our application./pimg src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/thW_kuIVJg4" height="1" width="1"/
The Time To Embrace PHP 5.3 Is Here
pimg src="http://engineeredweb.com/sites/engineeredweb.com/files/images/logos/PHP-logo.png" width="200" height="106" alt="PHP-logo.png" class="float-right image-border" /I am amazed at the number of a href="http://drupal.org" title="Drupal - Content Management Platform"Drupal/a modules that do not work under PHP 5.3. Until recently it had been acceptable to write code that didn't work in PHP 5.3. There was a small market share and the initial release of 5.3 had some bugs that made it worthwhile to rely on PHP 5.2. But, with the upcoming release of Drupal 7, which requires at a minimum PHP 5.2, and with PHP 5.3 starting to ship on some of the popular linux versions it's time to make sure Drupal sites run under 5.3 without any problems.br /
!--break--/p
h2Drupal 7, A Clean Point In Time/h2
pNow that modules are being ported to Drupal 7, in anticipation of its upcoming release, we have a perfect opportunity to support PHP 5.3. By support I do not mean rely on PHP 5.3. While it has a fair market share it is still at a point where supporting both PHP 5.2 and 5.3 is beneficial./p
pThis should be easier than when we supported PHP 4.4 through PHP 5.2. The differences between 5.2 and 5.3 are much smaller and both versions are far better than any version of PHP 4./p
h2Differences Between 5.2 and 5.3/h2
pIn addition to the a href="http://us2.php.net/manual/en/migration53.incompatible.php" title="Backward Incompatible Changes"list of incompatibilities between 5.3 and previous versions/a there are two items I'd like to highlight./p
ul
listronga href="http://www.php.net/manual/en/language.references.pass.php"Call-time pass-by-reference no longer works./a/strong That is, when you want a variable passed by reference into a function the span class="geshifilter"code class="geshifilter-php"span style="color: #339933;"amp;/span/code/span symbol should only be on the variable in the function definition and not when the function is called./li
listrongDon't use the ereg family of functions./strong The posix regex functions are now officially deprecated. Instead a href="http://us2.php.net/manual/en/book.pcre.php"PCRE/a should be used for regular expressions./li
/ul
h2Multiple Environments On One System/h2
pI typically develop under PHP 5.2. I want the ability to develop and test under PHP 5.3 side by side with 5.2. It is possible to setup a second system with the alternate version of PHP but it is more practical, for me, to have it right within my regular development workflow. Luckily there is a lot written about doing just that. Here's a short list./p
ul
liUse a href="http://mamp.info"MAMP/a. MAMP 1.9 provides both PHP 5.2 and 5.3./li
liUse a href="http://www.wampserver.com"WAMP/a with a a href="http://www.wampserver.com/en/addons_php.php"PHP 5.2.x add-on/a./li
lia href="http://cuadradevelopment.com/blog/26/multiple-php-versions-with-apache-using-fastcgi-on-os-x/"FastCGI with Multiple PHP Versions./a/li
lia href="http://mark-story.com/posts/view/maintaining-two-versions-of-php-with-macports"MacPorts and Multiple PHP Versions./a/li
lia href="http://ireallylikesushi.com/blog/2009/12/21/installing-both-zend-server-ce-php-5-2-php-5-3-on-snow-leopard/"Zend Server with PHP 5.2 and 5.3./a/li
lia href="http://boztek.net/blog/2009/10/07/install-lamp-stack-source-mac-os-x-106-snow-leopard-using-homebrew" Multiple PHP versions using Homebrew to install them./a/li
/ul
pIf you noticed that this fairly OS X centric. Most of the ideas on this, like using FastCGI, will work on other environments (e.g., *nix systems) as well./pimg src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/pFiq0nkpucc" height="1" width="1"/
Debugging in Drupal 7
pI can't count the number of times I've seen span class="geshifilter"code class="geshifilter-php"a href="http://www.php.net/print_r"span style="color: #990000;"print_r/span/a /code/spanor span class="geshifilter"code class="geshifilter-php"a href="http://www.php.net/var_export"span style="color: #990000;"var_export/span/a/code/span used while debugging code within a href="http://drupal.org" title="Drupal - Content Management Platform"Drupal/a. For those who use the a href="http://drupal.org/project/devel" title="devel drupal module"devel/a module I see regular use of the span class="geshifilter"code class="geshifilter-php"dsm/code/span and span class="geshifilter"code class="geshifilter-php"dpm/code/span functions. In Drupal 7 this all changes for the better with the introduction of the a href="http://api.drupal.org/api/function/debug/7" title="debug drupal 7 function"debug/a function.br /
!--break--/p
h2The Basics/h2
pUsing the debug function is pretty straight forward, like using span class="geshifilter"code class="geshifilter-php"dsm/code/span or span class="geshifilter"code class="geshifilter-php"a href="http://www.php.net/print_r"span style="color: #990000;"print_r/span/a/code/span. For example,/p
pdiv class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"span style="color: #000088;"$node/span span style="color: #339933;"=/span node_loadspan style="color: #009900;"#40;/spanspan style="color: #cc66cc;"123/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
debugspan style="color: #009900;"#40;/spanspan style="color: #000088;"$node/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span/pre/div/p
pThis will display the value of span class="geshifilter"code class="geshifilter-php"span style="color: #000088;"$node/span/code/span where php errors, notices, and warnings are usually displayed. This could be in the page or in the logs depending on how php is configured./p
h2Why To Use Debug/h2
pThere are 4 very good reasons to use debug over previous methods./p
ul
liSince debug uses the built in php error handling the errors are displayed where php is configured to display them. If php is configured to only send them to the logs they will just show up there. This is really useful for debugging and getting the details of errors users are experiencing./li
liThe previous bullet can be used during development or in production, depending on how php is configured, to capture valuable information. This is worth directly pointing out.
liThe debug function is common. Being in core its usage can be used across many modules consistently./li
liQuite often I see the debug output displaying at the top of a page throwing off the layout and look of the page to pick out a piece of information. span class="geshifilter"code class="geshifilter-php"dpm/code/span and span class="geshifilter"code class="geshifilter-php"dsm/code/span in devel do a good job not throwing that off. This can be used that way as well./li
liWorks with Simpletest. emThanks for the info rfay/em/li
/ul
h2All The Options/h2
pThe debug function has 3 arguments. It is pretty easy to just use span class="geshifilter"code class="geshifilter-php"debugspan style="color: #009900;"#40;/spanspan style="color: #000088;"$data/spanspan style="color: #009900;"#41;/span/code/span but there are cases where you want to do more than that./p
pThe full options are:br /
div class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"debugspan style="color: #009900;"#40;/spanspan style="color: #000088;"$data/spanspan style="color: #339933;",/span span style="color: #000088;"$label/spanspan style="color: #339933;",/span span style="color: #000088;"$print_r/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span/pre/div/p
pThe span class="geshifilter"code class="geshifilter-php"span style="color: #000088;"$data/span/code/span is pretty self explanatory. It can be anything you could pass through span class="geshifilter"code class="geshifilter-php"a href="http://www.php.net/print_r"span style="color: #990000;"print_r/span/a/code/span or span class="geshifilter"code class="geshifilter-php"a href="http://www.php.net/var_export"span style="color: #990000;"var_export/span/a/code/span. The span class="geshifilter"code class="geshifilter-php"span style="color: #000088;"$label/span/code/span allows for a custom label to be added. This is ideal when you are sending the information to a log and you want a key to search the logs for. The 3rd argument is whether to use span class="geshifilter"code class="geshifilter-php"a href="http://www.php.net/print_r"span style="color: #990000;"print_r/span/a/code/span or span class="geshifilter"code class="geshifilter-php"a href="http://www.php.net/var_export"span style="color: #990000;"var_export/span/a/code/span. The default is span class="geshifilter"code class="geshifilter-php"a href="http://www.php.net/var_export"span style="color: #990000;"var_export/span/a/code/span. If you are interested between the two I'd suggest reading the manual pages./p
pI have to say I am quite happy with this addition to Drupal 7. It adds a bit more debugging power to Drupal./p
pema href="http://en.wikipedia.org/wiki/Hat_tip" title="Wikipedia: Hat tip"Hat tip/a to a href="http://drupal4hu.com/"chx/a for pointing out this function./em/pimg src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/fYQgO5gTn7I" height="1" width="1"/
3 Tips For Using External Libraries With Drupal
pThere are more and more cases to use external libraries with a href="http://drupal.org" title="Drupal: Content Management Platform"Drupal/a. They may be a href="http://jquery.com"jQuery/a plugins, CSS libraries, or PHP libraries already providing some form or function we want to use. But, so often we can't include then on drupal.org because of policy issues or there may be multiple modules wanting to use the same libraries which can cause collisions. Here are 3 tips for easily working with outside libraries.br /
!--break--/p
h2Use Libraries Module/h2
pThe a href="http://drupal.org/project/libraries" title="Libraries Drupal Module"libraries/a module provides a missing link in Drupal. Modules go in the modules folder. Themes go in the themes folder. With the libraries modules libraries go in the libraries folder alongside the modules and themes folders./p
pThat means there are several places you can place libraries and they will work. If you want to place a library in a profile it can be at:br /
div class="geshifilter"pre class="text geshifilter-text" style="font-family:monospace;"profiles/example_profile/libraries/example_library/pre/div/p
pOr, if you want a library available to all sites in a multi-site install you can place it in:br /
div class="geshifilter"pre class="text geshifilter-text" style="font-family:monospace;"sites/all/libraries/pre/div/p
pIf you want a specific version of a library for a specific site it can be placed in:br /
div class="geshifilter"pre class="text geshifilter-text" style="font-family:monospace;"sites/example_domain/libraries/pre/div/p
pThis works just like modules and themes./p
pTo get the path to the library the function to use is libraries_get_path.br /
div class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"span style="color: #000088;"$path/span span style="color: #339933;"=/span libraries_get_pathspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'library_name'/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span/pre/div/p
h2hook_requirements/h2
pa href="http://api.drupal.org/api/function/hook_requirements/6"hook_requirements/a can check to see if a library is available and even report the version./p
pThe example below is a simple example to see if a library is installed. It will check when a user visits the status page and when the module is being installed.br /
div class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"span style="color: #000000; font-weight: bold;"function/span example_requirementsspan style="color: #009900;"#40;/spanspan style="color: #000088;"$phase/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #000088;"$requirements/span span style="color: #339933;"=/span a href="http://www.php.net/array"span style="color: #990000;"array/span/aspan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
span style="color: #666666; font-style: italic;"// Ensure translations do not break at install time/span
span style="color: #000088;"$t/span span style="color: #339933;"=/span get_tspan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
nbsp;
span style="color: #000088;"$requirements/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'example'/spanspan style="color: #009900;"#93;/span span style="color: #339933;"=/span a href="http://www.php.net/array"span style="color: #990000;"array/span/aspan style="color: #009900;"#40;/span
span style="color: #0000ff;"'title'/span span style="color: #339933;"=gt;/span span style="color: #000088;"$t/spanspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'Example Library'/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;",/span
span style="color: #009900;"#41;/spanspan style="color: #339933;";/span
nbsp;
span style="color: #000088;"$libraries/span span style="color: #339933;"=/span libraries_get_librariesspan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
span style="color: #b1b100;"if/span span style="color: #009900;"#40;/spana href="http://www.php.net/isset"span style="color: #990000;"isset/span/aspan style="color: #009900;"#40;/spanspan style="color: #000088;"$libraries/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'example'/spanspan style="color: #009900;"#93;/spanspan style="color: #009900;"#41;/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #000088;"$requirements/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'example'/spanspan style="color: #009900;"#93;/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'value'/spanspan style="color: #009900;"#93;/span span style="color: #339933;"=/span span style="color: #000088;"$t/spanspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'Installed'/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
span style="color: #000088;"$requirements/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'example'/spanspan style="color: #009900;"#93;/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'severity'/spanspan style="color: #009900;"#93;/span span style="color: #339933;"=/span REQUIREMENT_OKspan style="color: #339933;";/span
span style="color: #009900;"#125;/span
span style="color: #b1b100;"else/span span style="color: #009900;"#123;/span
span style="color: #000088;"$requirements/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'example'/spanspan style="color: #009900;"#93;/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'value'/spanspan style="color: #009900;"#93;/span span style="color: #339933;"=/span span style="color: #000088;"$t/spanspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'Not Installed'/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
span style="color: #000088;"$requirements/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'example'/spanspan style="color: #009900;"#93;/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'severity'/spanspan style="color: #009900;"#93;/span span style="color: #339933;"=/span REQUIREMENT_ERRORspan style="color: #339933;";/span
span style="color: #000088;"$requirements/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'example'/spanspan style="color: #009900;"#93;/spanspan style="color: #009900;"#91;/spanspan style="color: #0000ff;"'description'/spanspan style="color: #009900;"#93;/span span style="color: #339933;"=/span span style="color: #000088;"$t/spanspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'Please install the example library %url.'/spanspan style="color: #339933;",/span a href="http://www.php.net/array"span style="color: #990000;"array/span/aspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'%url'/span span style="color: #339933;"=gt;/span span style="color: #0000ff;"'http://example.com'/spanspan style="color: #009900;"#41;/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
span style="color: #009900;"#125;/span
nbsp;
span style="color: #b1b100;"return/span span style="color: #000088;"$requirements/spanspan style="color: #339933;";/span
span style="color: #009900;"#125;/span/pre/div/p
pAn alternate example that reports the version and only checks at runtime can be see in the a href="http://drupalcode.org/viewvc/drupal/contributions/modules/zend/zend.module?revision=1.1.2.1.2.10amp;view=markupamp;pathrev=DRUPAL-6--1#l52"Zend module/a./p
pThere are several different ways to take advantage of this function. Using it can help the user make sure everything is present and the sate it is in./p
h2Autoload Classes/h2
pAutoloading classes and interfaces is common in PHP development. Most frameworks have something built in to aide with autoloading. When building Drupal modules it is a good idea to use autoloading as well. The simplest way is to take advantage of the a href="http://drupal.org/project/autoload" title="Autoload Drupal Module"autoload/a module./p
pThe autoload module provides span class="geshifilter"code class="geshifilter-php"hook_autoload_infospan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/span/code/span to tell Drupal where classes and interfaces are. This is a registry hook to collect information for the build in PHP spl_autoloader. An example, working with the libraries module could look something like:br /
div class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"span style="color: #000000; font-weight: bold;"function/span example_autoload_infospan style="color: #009900;"#40;/spanspan style="color: #009900;"#41;/span span style="color: #009900;"#123;/span
span style="color: #000088;"$path/span span style="color: #339933;"=/span libraries_get_pathspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'example'/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span
span style="color: #b1b100;"return/span a href="http://www.php.net/array"span style="color: #990000;"array/span/aspan style="color: #009900;"#40;/span
span style="color: #0000ff;"'exampleClass'/span span style="color: #339933;"=gt;/span a href="http://www.php.net/array"span style="color: #990000;"array/span/aspan style="color: #009900;"#40;/span
span style="color: #0000ff;"'file'/span span style="color: #339933;"=gt;/span span style="color: #0000ff;"'exampleClass.php'/spanspan style="color: #339933;",/span
span style="color: #0000ff;"'file path'/span span style="color: #339933;"=gt;/span span style="color: #000088;"$path/spanspan style="color: #339933;",/span
span style="color: #009900;"#41;/spanspan style="color: #339933;",/span
span style="color: #0000ff;"'exampleInterface'/span span style="color: #339933;"=gt;/span a href="http://www.php.net/array"span style="color: #990000;"array/span/aspan style="color: #009900;"#40;/span
span style="color: #0000ff;"'file'/span span style="color: #339933;"=gt;/span span style="color: #0000ff;"'exampleInterface.php'/spanspan style="color: #339933;",/span
span style="color: #0000ff;"'file path'/span span style="color: #339933;"=gt;/span span style="color: #000088;"$path/spanspan style="color: #339933;",/span
span style="color: #009900;"#41;/spanspan style="color: #339933;",/span
span style="color: #009900;"#41;/spanspan style="color: #339933;";/span
span style="color: #009900;"#125;/span/pre/div/p
pThe 'file path' property is optional. If it is not included the autoload module will assume the folder the module is in as the patch./pimg src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/De4GKepMQBY" height="1" width="1"/
The New Way To Generate Hashes In Drupal 7
pWhen we write a href="http://drupal.org" title="Drupal: Content Management Framework"Drupal/a modules generating hashes is a common task. They are usually generated as a md5 hash. Because of some new regulations for a large group of Drupal users it's time to migrate away from md5 to the a href="http://en.wikipedia.org/wiki/SHA-2" title="Wikipedia: SHA-2"SHA-2/a family of hashes. a href="http://drupal.org/node/723802" title="convert to sha-256 and hmac from md5 and sha1"Drupal 7 core has already migrated away from md5/a and it's time for contrib modules to follow.br /
!--break--/p
h2Why Change to SHA2/h2
pThe software powering United States government websites are going to be required to use SHA-2 according to FIPS 180-3 and FIPS 198-1. Now, these requirements don't mean that every hash has to be a SHA-2 hash. But, any case a hash is used that's not SHA-2 needs to be explained. And, this is most likely going to happen each time Drupal is used. Can you imagine being a vendor building a Drupal website for the US government and having to explain, in writing, each use of a hash that is not SHA-2? And, doing that each time you build a website for them? Yikes, that would be annoying./p
pSome will say they don't care about supporting the US Government or vendors who build sites for them. Yet, when sites are built for them, like the a href="http://www.whitehouse.gov/"White House/a, it is seen as a big deal and a win./p
pModules that are used on sites, like the White House, gain some popularity. Look at the a href="http://drupal.org/project/usage/context"usage on the context module/a after its usage was announced on the White House./p
pAll around it seems like a better idea to migrate to SHA-2 hashes and be done with it. As a practice building modules that can be used by a wide array of users is good and healthy./p
h2The 4 Ways To Generate Hashes/h2
pFollowing how Drupal 7 implements the SHA-2 hashes there are 4 ways we can implement hashes depending on what we need./p
ol
liThe simpliest is to use the built in PHP function to generate a SHA-2 hash. It would look something like:br /
div class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"hashspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'sha256'/spanspan style="color: #339933;",/span span style="color: #000088;"$data/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span/pre/div/li
liA standard SHA-2 hash is not url safe. Drupal 7 provides a href="http://api.drupal.org/api/function/drupal_hash_base64/7"drupal_hash_base64/a which generates a SHA-256 based hash that is url safe./li
liThere are occasions where a module may want to generate a a href="http://en.wikipedia.org/wiki/HMAC" title="Wikipedia: HMAC"HMAC/a. In those cases using the built in PHP hash_hmac will work. For example:br /
div class="geshifilter"pre class="php geshifilter-php" style="font-family:monospace;"hash_hmacspan style="color: #009900;"#40;/spanspan style="color: #0000ff;"'sha256'/spanspan style="color: #339933;",/span span style="color: #000088;"$data/spanspan style="color: #339933;",/span span style="color: #000088;"$key/spanspan style="color: #009900;"#41;/spanspan style="color: #339933;";/span/pre/div/li
liThe hash generated by hash_hmac for SHA-2 is not url safe. For those cases Drupal 7 provides a helper function in a href="http://api.drupal.org/api/function/drupal_hmac_base64/7"drupal_hmac_base64/a./li
/ol
pThese examples use SHA-256. Other varients, like SHA-512, are acceptable. SHA-256 ends up being faster. Some places in Drupal use stronger hashes. For example, Drupal 7 default password hashing uses SHA-512./pimg src="http://feeds.feedburner.com/~r/EngineeredWeb/~4/nW69hJiRsLE" height="1" width="1"/