LogoPhly, boy, phly
the weblog and site of Matthew Weier O'Phinney

Sunday, May 20. 2007

Globals, continued

Update: Sara has pointed out a flaw in my last case. The file 'loadFileWithGlobals.php' was incorrectly loading the wrong file -- it should be loading 'withGlobals2.php' (updated now). When it does, access to 'baz2' works as it should.

As I note to in my comment, however, I stand by my original rant: relying on globals for your applications is a bad practice, as it makes them difficult to integrate with other applications later. Developers using your application should not need to hunt down exactly when a global is first declared and explicitly push it into the global scope in order to get that application to integrate with others. Use other means, such as singletons or registries, to persist configuration within your applications.


In my last entry, I evidently greatly simplified the issue to the point that my example actually didn't display the behaviour I had observed. I'm going to show a more detailed example that shows exactly the behaviour that was causing issues for me.

First off, this has specifically to do with including files from within functions or class methods that then call on other files that define values in the global scope. In the original example, I show an action controller method that includes the serendipity bootstrap file, which in turn loads a configuration file that sets a multi-dimensional array variable in the global scope. Without first defining the variable in the global scope, this method of running serendipity fails.

Now, for the examples.


Continue reading "Globals, continued"

Posted by Matthew Weier O'Phinney in PHP at 12:23 | Comments (4) | Trackback (1)

Saturday, May 19. 2007

PHP globals for the OOP developer

Update: I evidently simplified the issue too much, and have had several people rightly comment on the bogosity of the issue. However, there are still situations where $GLOBALS does not act as expected, and I outline these in my next entry.


In my previous entry, I ranted about the use of globals in popular PHP applications, and how they make embedding said applications difficult. I develop using object-oriented practices, and can honestly say I can't recall ever having slung a global variable around in my own code. Globals seem hackish to me, and as a result, trying to get applications that use them to behave correctly has been a challenge.

One of the applications I had in mind was Serendipity, the software that powers this blog. I was attempting to create a Zend Framework action controller that wraps my s9y instance so that I can do things such as apply ACLs from my website to selected entries, as well as pull the sitewide skeleton out from s9y so that I only have to maintain one version of it (I had one version for s9y, and another for my own content featured on the site (resume, contact form, etc.).

I tried importing the various config files into my action method prior to invoking the actual s9y bootstrap, but no dice. I also tried modifying the s9y config files to use the notation $GLOBALS['serendipity'] around the serendipity configuration variables (s9y uses a single multi-dimensional array for all configuration options). This didn't work, either; s9y functions that called global $serendipity were still getting a null value.

So, I did a little closer reading in the manual section on predefined variables, I discovered something interesting in the description of $GLOBALS (emphasis mine):

Contains a reference to every variable which is currently available within the global scope of the script.

Interestingly, the section on variable scope didn't make this distinction at all. Basically, if the variable you reference via $GLOBALS does not already exist, assigning it does nothing. It doesn't even raise a notice. It just silently goes ahead, leaving you thinking you set a new global variable, but in fact, you cannot assign new globals via $GLOBALS; you can only modify existing variables in the global scope.

So, I got around the issue by putting this in my front controller bootstrap:


$serendipity = null;
 

After that, I was able to create a wrapper action controller for s9y very easily:


/** Zend_Controller_Action */
require_once 'Zend/Controller/Action.php';

/**
 * Serendipity integration
 *
 * @uses       Zend_Controller_Action
  */

class S9y_IndexController extends Zend_Controller_Action
{
    public function init()
    {
        // New ViewRenderer helper in ZF incubator; telling it not
        // to autorender a view script when done
        $this->_helper->viewRenderer->initView(null, null, array('noRender' => true));
    }

    public function indexAction()
    {
        global $serendipity;
        chdir($_SERVER['DOCUMENT_ROOT'] . '/path/to/s9y');
        include './index.php';
        chdir($_SERVER['DOCUMENT_ROOT']);
    }
}
 

Note that I don't do any output buffering; this is because the ZF dispatcher takes care of that for me. All I need to do is execute the s9y bootstrap.

So, the lesson to learn from all this: if you need to wrap an application that uses globals, find out what all of them are, and declare them in the global namespace -- just setting them to null is enough -- in your application bootstrap.

Posted by Matthew Weier O'Phinney in PHP at 09:42 | Comments (9) | Trackback (1)

Monday, May 7. 2007

Start Writing Embeddable Applications

Clay Loveless wrote last year an article entitled Stop Writing Loner Applications in which he ranted about all the monolithic applications that act like they're the only kid on the block when it comes to user authentication. Basically, if you want to create a site that utilizes several third-party, off-the-shelf PHP apps (say, a forum, a blog, and a wiki), getting a shared authentication to work between them can be more than a little painful.

I've hit a similar problem repeatedly the past couple months: most of these apps simply are not embeddable, at least not without modifying the source.

"Why embed?" you ask. Simple: if I'm creating a site that has one or two of these applications, but also my (or my company's) own custom functionality, I may want to ensure that certain elements are present on all pages, or that I can control some of the content in all pages: a unified header and footer, ability to inject statistic tracking javascript, etc.

The predominant attitudes are either, "Don't embed our app, embed your app in ours," or "Just modify the templates." Neither of these solutions is acceptable.


Continue reading "Start Writing Embeddable Applications"

Posted by Matthew Weier O'Phinney in PHP at 00:00 | Comments (9) | Trackback (1)
Defined tags for this entry: best practices, php
(Page 1 of 1, totaling 3 entries)
  • Home
  • Resume
  • Blog
  • Phly PEAR Channel
  • Contact Me
  • About this site

ZCE

Zend Education Advisory Board Member

Add to Technorati Favorites

Calendar

Back May '07 Forward
Mon Tue Wed Thu Fri Sat Sun
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

Quicksearch

Links

  • PHLY - PHp LibrarY
  • Paul M. Jones
  • Mike Naberezny
  • Shahar Evron
  • Planet PHP
  • Zend Where I now work
  • Garden.org Where I once worked

Archives

March 2010
February 2010
January 2010
Recent...
Older...

Categories

XML Linux
XML Personal
XML Aikido
XML Family
XML Programming
XML Dojo
XML Perl
XML PHP

All categories

Syndicate This Blog

XML RSS 0.91 feed
XML RSS 1.0 feed
XML RSS 2.0 feed
ATOM/XML ATOM 0.3 feed
ATOM/XML ATOM 1.0 feed
XML RSS 2.0 Comments

Show tagged entries

xml best practices
xml books
xml conferences
xml cw09
xml decorators
xml dojo
xml dpc08
xml file_fortune
xml git
xml linux
xml mvc
xml oop
xml pear
xml perl
xml personal
xml php
xml phpworks08
xml programming
xml rest
xml ubuntu
xml vim
xml webinar
xml zendcon
xml zendcon08
xml zendcon09
xml zend framework
© 2004 - present, Matthew Weier O'Phinney
matthew-web <at> weierophinney.net