Monday, May 22. 2006
After some discussion with Paul
and Mike, I was convinced that
'Struct' was a bad name for Phly_Struct; structs are rarely if ever
iterable, and one key feature of Phly_Struct is its iterable nature.
The question is: what to name it? Associative arrays go by a variety of
names in different languages. In Perl, they're 'hashes'; Ruby and
Javascript, 'collections'; Python, 'dictionaries'. I ruled out
'Phly_Dictionary' immediately, as (a) I don't want it to be confused with
online dictionaries, and (b), it's too long. The term 'Collection' also
feels too long (although I write things like
'Cgiapp2_ErrorException_Observer_Interface', so I don't know why length
should be such an issue), as well as unfamiliar to many PHP developers. Hash
can imply cryptographic algorithms, but, overall, is short and used often
enough in PHP circles that it makes sense to me.
So, I've renamed Phly_Struct to Phly_Hash,
and updated Phly_Config to use the new package as its dependency. In
addition, I've had it implement Countable, so you can do things like:
$idxCount = count($struct);
Go to the channel page for
instructions on adding Phly to your PEAR channels list, and grab the new
package with pear install -a phly/Phly_Hash, or pear upgrade -a
phly/Phly_Config.
Friday, May 19. 2006
I often find myself needing a configuration module of some sort -- for
storing application parameters, bootstrapping, template variables, what have
you. I typically will either:
- Create a PHP file that creates and returns an array, and suck that in
via include, or
- Create an INI file and suck it in via
parse_ini_file, or
- Create an XML file and suck it in via
SimpleXML.
The first method gives great flexibility of structure and types, but isn't
portable to other languages (well, not easily; you could turn it into JSON,
or serialize it, etc). The second method (INI files) is handy because the
syntax is so concise, and can translate to other projects in other languages
easily if necessary; however, you can only easily go two levels deep (using
[sections] in the file). The third method is very portable, and allows
nested structures -- but doesn't allow usage of many specific PHP types.
I find, however, that each has their place. The problem, however, is: once I
bring them into my project, how can I access them? Better yet, would there
be a way to bring in configurations of many types and still access them all
in the same way?
Not happy with solutions out there, I did the only logical thing: I
reinvented the wheel, and added some new tread of my own.
Continue reading "Introducing Phly_Struct and Phly_Config"
Tuesday, May 16. 2006
I've been working with SimpleXML a fair amount lately, and have run into an
issue a number of times with character encodings. Basically, if a string
has a mixture of UTF-8 and non-UTF-8 characters, SimpleXML barfs, claiming
the "String could not be parsed as XML."
I tried a number of solutions, hoping actually to automate it via mbstring
INI settings; these schemes all failed. iconv didn't work properly.
The only thing that did work was to convert the encoding to latin1 -- but
this wreaked havoc with actual UTF-8 characters.
Then, through a series of trial-and-error, all-or-nothing shots, I stumbled
on a simple solution. Basically, I needed to take two steps:
- Detect the current encoding of the string
- Convert that encoding to UTF-8
which is accomplished with:
The conversion is performed even if the detected encoding is UTF-8; the
conversion ensures that all characters in the string are properly
encoded when done.
It's a non-intuitive solution, but it works! QED.
I've been working on Cgiapp in
the past few months, in particular to introduce one possibility for a Front
Controller class. To test out ideas, I've decided to port areas of my
personal site to Cgiapp2 using the Front Controller. Being the
programmer I am, I quickly ran into some areas where I needed some reusable
code -- principally for authentication and input handling.
I've been exposed to a ton of good code via PEAR,
Solar,
eZ components, and
Zend Framework. However, I have
several criteria I need met:
- I want PHP5 code. I'm coding in PHP5, I should be able to use PHP5
libraries, not PHP4 libraries that work in PHP5 but don't take advantage of
any of its features.
- I prefer few dependencies, particularly lock-in with existing
frameworks. If I want to swap out a storage container from one library and
use one from another, I should be free to do so without having to write
wrappers so they'll fit with the framework I've chosen. Flexibility is
key.
- Stable API. I don't want to have to change my code every few weeks or
months until the code is stable.
- I should be able to understand the internals quickly.
So what did I choose? To reinvent the wheel, of course!
To that end, I've opened a new PEAR channel that I'm calling
PHLY, the PHp LibrarY, named
after my blog. The name implies soaring, freedom, and perhaps a little
silliness.
It is designed with the following intentions:
- Loosely coupled; dependencies should be few, and no base class should be necessary.
- Extendible; all classes should be easily extendible. This may be via observers, interfaces, adapters, etc.. The base class should solve 80% of usage, and allow extensions to the class to fill in the remainder.
- Designed for PHP5 and up; all classes should make use of PHP5's features.
- Documented; all classes should minimally have excellent API-level documentation, with use cases in the class docblock.
- Tested; all classes should have unit tests accompanying them.
- Open source and commercial friendly; all classes should use a commercial-friendly open source license. The BSD license is one such example.
Please feel free to use this code however you will. Comments, feedback, and
submissions are always welcome.
Tuesday, May 2. 2006
I released Cgiapp 1.9.0 into the wild last night. The main difference
between 1.8.0 and 1.9.0 is that I completely removed the plugin system. I
hadn't had any users reporting that they were using it, and, in point of
fact, the overloading mechanism I was using was causing some obscure issues,
particularly in the behaviour of cgiapp_postrun().
As usual, you can find more information and links to downloads
at the Cgiapp site.
|
|