<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
 <channel>
   <title>Flourish Blog</title>
  <link>http://flourishlib.com/blog</link>
  <description>The PHP Unframework</description>
  <language>en-us</language>
  <generator>Trac v0.10.4</generator>
   <image>
	<title>Flourish</title>
	<url>http://flourishlib.com/chrome/common/logo.png</url>
	<link>http://flourishlib.com/blog</link>
   </image>
   <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/flourishlib_blog" /><feedburner:info uri="flourishlib_blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
	<title>Cutting Down on Spam</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Wed, 15 Jun 2011 15:03:34 EDT</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/TFS0x3cTeZc/CuttingDownOnSpam</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/CuttingDownOnSpam</guid>
	<description>&lt;p&gt;
Last night I got fed up with the spam that was getting through on the forum and in tickets. While Akismet and the built-in spam filtering in Trac cut out 99.9% of spam, it is frustrating for site participants to get notification emails about spam posts.
&lt;/p&gt;
&lt;p&gt;
In order to cut down on the spam messages even more, I've changed the site to require a user account to post. After finding almost 9,000 spam accounts created on the site, I've also implemented reCaptcha on the registration form.
&lt;/p&gt;
&lt;p&gt;
I apologize for the inconvenience of registering and logging in to participate, but I hope these steps can help keep the site even more spam free and keep the notifications relevant and frustration-free.
&lt;/p&gt;
&lt;p&gt;
If you haven't already created an account, jump over to the &lt;a href="/register"&gt;registration page&lt;/a&gt; and sign up!
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/TFS0x3cTeZc" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/CuttingDownOnSpam</feedburner:origLink></item>
   <item>
	<title>Alter Table Improved, Especially for SQLite</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Tue, 24 May 2011 15:03:19 EDT</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/1yg_7h6Kl2M/AlterTableImproved</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/AlterTableImproved</guid>
	<description>&lt;p&gt;
A frequent complaint among developers dealing with relational database systems
is dealing with database migrations. Depending on the size of the data you are
working with, that may be the issue, however the syntax and features of
&lt;tt&gt;ALTER TABLE&lt;/tt&gt; statements vary greatly between database systems. I’ve recently
added some functionality to Flourish to make &lt;tt&gt;ALTER TABLE&lt;/tt&gt; statements not only
more pleasant to work with, but consistent across MySQL, PostgreSQL, SQLite,
Oracle, DB2 and Microsoft SQL Server.
&lt;/p&gt;
&lt;h2 id="Implementation"&gt;Implementation&lt;/h2&gt;
&lt;p&gt;
Flourish now supports a full complement of &lt;tt&gt;ALTER TABLE&lt;/tt&gt; statements that will
run on MySQL, PostgreSQL, SQLite, Oracle, DB2 and Microsoft SQL Server. You
can now write a single SQL migration script and run it on any supported
database. &lt;a class="auto_api api" href="/api/fDatabase#translatedQuery" title="fDatabase#translatedQuery"&gt;fDatabase::translatedQuery()&lt;/a&gt; and &lt;a class="auto_api api" href="/api/fDatabase#translatedExecute" title="fDatabase#translatedExecute"&gt;fDatabase::translatedExecute()&lt;/a&gt; will
utilize the new &lt;a class="wiki" href="/docs/fSQLSchemaTranslation"&gt;fSQLSchemaTranslation&lt;/a&gt; class when &lt;tt&gt;CREATE TABLE&lt;/tt&gt;, &lt;tt&gt;ALTER TABLE&lt;/tt&gt;,
&lt;tt&gt;DROP TABLE&lt;/tt&gt; and &lt;tt&gt;COMMENT ON COLUMN&lt;/tt&gt; statements are run.
&lt;/p&gt;
&lt;p&gt;
Rather than trying to abstract the SQL language into PHP method calls, I’ve
always opted with Flourish to translate SQL to the various dialects supported
by the database in question. The goal here isn’t to provide an abstraction
layer, but a translation layer. If you look at the guts of &lt;a class="wiki" href="/docs/fSQLSchemaTranslation"&gt;fSQLSchemaTranslation&lt;/a&gt;
you’ll see there is quite a bit of pattern matching, SQL statement manipulation
and schema catalog lookups.
&lt;/p&gt;
&lt;p&gt;
If you use PostgreSQL or Oracle you are probably used to fairly robust 
support for SQL DDL statements. Unfortunately some of the other supported
systems are a bit more painful to use. For MySQL, foreign key constraints must
be dropped before any operations can be performed on the column or table
they are associated with, and then once the operation is complete they must
be re-created. SQL Server requires similar requirements for dropping
and re-creating constraints, but even goes to the extreme of requiring it for
default value constraints. SQLite barely supports any &lt;tt&gt;ALTER TABLE&lt;/tt&gt; statements
in version 3 and nothing is supported in version 2. DB2 requires some
management of constraints, but also that you explicitly reorganize the table
index after specific statements.
&lt;/p&gt;
&lt;p&gt;
What it comes down to is that to support more than a single database system,
you end up having to handle all of these edge cases for each database system.
This significantly slows down the development process and can be a downright
frustrating experience. Flourish is here to help with that.
&lt;/p&gt;
&lt;h2 id="ShowMetheCode"&gt;Show Me the Code!&lt;/h2&gt;
&lt;p&gt;
Here is a basic example of how you can create a database table that work on
six different database systems. If you really want to dive right into the
supported syntax, please check out the &lt;a class="wiki" href="/docs/FlourishSql"&gt;FlourishSql&lt;/a&gt; page.
&lt;/p&gt;
&lt;p&gt;
As I mentioned above, all of this functionality I’ll be explaining works through
&lt;a class="wiki" href="/docs/fDatabase"&gt;fDatabase&lt;/a&gt;. You don’t actually need to worry about the &lt;a class="wiki" href="/docs/fSQLSchemaTranslation"&gt;fSQLSchemaTranslation&lt;/a&gt;
class at all. The class is separate from &lt;a class="wiki" href="/docs/fSQLTranslation"&gt;fSQLTranslation&lt;/a&gt; due to its sheer
size, over five thousand lines of code. Simply pass a &lt;a class="wiki" href="/docs/FlourishSql"&gt;FlourishSql&lt;/a&gt; statement
to &lt;a class="auto_api api" href="/api/fDatabase#translatedQuery" title="fDatabase#translatedQuery"&gt;fDatabase::translatedQuery()&lt;/a&gt; or &lt;a class="auto_api api" href="/api/fDatabase#translatedExecute" title="fDatabase#translatedExecute"&gt;fDatabase::translatedExecute()&lt;/a&gt; and you
are in business.
&lt;/p&gt;
&lt;div class="code php"&gt;&lt;pre&gt;&lt;span class="php-var"&gt;$db&lt;/span&gt;&lt;span class="php-code"&gt; = &lt;/span&gt;&lt;span class="php-reserved"&gt;new&lt;/span&gt; &lt;span class="php-identifier"&gt;fDatabase&lt;/span&gt;&lt;span class="php-brackets"&gt;(&lt;/span&gt;&lt;span class="php-quotes"&gt;'&lt;/span&gt;&lt;span class="php-string"&gt;sqlite&lt;/span&gt;&lt;span class="php-quotes"&gt;'&lt;/span&gt;&lt;span class="php-code"&gt;, &lt;/span&gt;&lt;span class="php-quotes"&gt;'&lt;/span&gt;&lt;span class="php-string"&gt;./path/to/db&lt;/span&gt;&lt;span class="php-quotes"&gt;'&lt;/span&gt;&lt;span class="php-brackets"&gt;)&lt;/span&gt;&lt;span class="php-code"&gt;;&lt;/span&gt;
 
&lt;span class="php-var"&gt;$db&lt;/span&gt;&lt;span class="php-code"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="php-identifier"&gt;translatedExecute&lt;/span&gt;&lt;span class="php-brackets"&gt;(&lt;/span&gt;&lt;span class="php-quotes"&gt;&amp;quot;&lt;/span&gt;&lt;span class="php-string"&gt;&lt;/span&gt;
&lt;span class="php-string"&gt;    CREATE TABLE users (&lt;/span&gt;
&lt;span class="php-string"&gt;        user_id INTEGER AUTOINCREMENT PRIMARY KEY,&lt;/span&gt;
&lt;span class="php-string"&gt;        name VARCHAR(200) NOT NULL,&lt;/span&gt;
&lt;span class="php-string"&gt;        email VARCHAR(200) NOT NULL UNIQUE&lt;/span&gt;
&lt;span class="php-string"&gt;    )&lt;/span&gt;
&lt;span class="php-string"&gt;&lt;/span&gt;&lt;span class="php-quotes"&gt;&amp;quot;&lt;/span&gt;&lt;span class="php-brackets"&gt;)&lt;/span&gt;&lt;span class="php-code"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;
Some of the nicest features of the translation layer in Flourish is that it
handles even the gnarly edge cases like auto-incrementing integer primary keys.
If you’ve ever worked with more than one database system I’m sure you are
aware that they all have completely different syntax for this. PostgreSQL uses
the &lt;tt&gt;SERIAL&lt;/tt&gt; data type that implicitly creates a sequence. MySQL has a special
keyword &lt;tt&gt;AUTO_INCREMENT&lt;/tt&gt;. SQL Server uses an &lt;tt&gt;IDENTITY&lt;/tt&gt; properly on the column.
Oracle is possibly the most painful, requiring an explicit sequence to be created
and then a trigger created to select values from the sequence and insert them
into new records.
&lt;/p&gt;
&lt;p&gt;
&lt;tt&gt;CREATE TABLE&lt;/tt&gt; support is all great and dandy and, in fact, Flourish has
supported that since early on. What you really need to maintain an app that
supports multiple databases is &lt;tt&gt;ALTER TABLE&lt;/tt&gt; support. Here are some example
statements:
&lt;/p&gt;
&lt;div class="code php"&gt;&lt;pre&gt;&lt;span class="php-var"&gt;$db&lt;/span&gt;&lt;span class="php-code"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="php-identifier"&gt;translatedExecute&lt;/span&gt;&lt;span class="php-brackets"&gt;(&lt;/span&gt;&lt;span class="php-quotes"&gt;&amp;quot;&lt;/span&gt;&lt;span class="php-string"&gt;&lt;/span&gt;
&lt;span class="php-string"&gt;    ALTER TABLE users ADD COLUMN password VARCHAR(80) NOT NULL DEFAULT '';&lt;/span&gt;
&lt;span class="php-string"&gt;    ALTER TABLE users ALTER COLUMN password DROP DEFAULT;&lt;/span&gt;
&lt;span class="php-string"&gt;    ALTER TABLE users RENAME COLUMN email TO email_address;&lt;/span&gt;
&lt;span class="php-string"&gt;    ALTER TABLE users ALTER COLUMN name TYPE VARCHAR(250);&lt;/span&gt;
&lt;span class="php-string"&gt;&lt;/span&gt;&lt;span class="php-quotes"&gt;&amp;quot;&lt;/span&gt;&lt;span class="php-brackets"&gt;)&lt;/span&gt;&lt;span class="php-code"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="UsefulShorthand"&gt;Useful Shorthand&lt;/h2&gt;
&lt;p&gt;
In addition to creating consistent syntax across all of the supported database
systems, Flourish provides simple shorthand syntax for dealing with constraints.
For many database systems it is necessary to use system-generated constraint
names when dropping constraints, and for some it is necessary to create explicit
constraint names upon creation.
&lt;/p&gt;
&lt;p&gt;
Here are examples of the shorthand available:
&lt;/p&gt;
&lt;div class="code sql"&gt;&lt;pre&gt;&lt;span class="sql-reserved"&gt;ALTER&lt;/span&gt; &lt;span class="sql-reserved"&gt;TABLE&lt;/span&gt; &lt;span class="sql-reserved"&gt;table&lt;/span&gt; &lt;span class="sql-reserved"&gt;ADD&lt;/span&gt; &lt;span class="sql-reserved"&gt;PRIMARY&lt;/span&gt; &lt;span class="sql-reserved"&gt;KEY&lt;/span&gt; &lt;span class="sql-brackets"&gt;(&lt;/span&gt;&lt;span class="sql-reserved"&gt;column&lt;/span&gt;&lt;span class="sql-brackets"&gt;)&lt;/span&gt; &lt;span class="sql-reserved"&gt;AUTOINCREMENT&lt;/span&gt;&lt;span class="sql-code"&gt;;
&lt;/span&gt;&lt;span class="sql-reserved"&gt;ALTER&lt;/span&gt; &lt;span class="sql-reserved"&gt;TABLE&lt;/span&gt; &lt;span class="sql-reserved"&gt;table&lt;/span&gt; &lt;span class="sql-reserved"&gt;ADD&lt;/span&gt; &lt;span class="sql-reserved"&gt;UNIQUE&lt;/span&gt; &lt;span class="sql-brackets"&gt;(&lt;/span&gt;&lt;span class="sql-identifier"&gt;column1&lt;/span&gt;&lt;span class="sql-code"&gt;, &lt;/span&gt;&lt;span class="sql-identifier"&gt;column2&lt;/span&gt;&lt;span class="sql-brackets"&gt;)&lt;/span&gt;&lt;span class="sql-code"&gt;;
&lt;/span&gt;&lt;span class="sql-reserved"&gt;ALTER&lt;/span&gt; &lt;span class="sql-reserved"&gt;TABLE&lt;/span&gt; &lt;span class="sql-reserved"&gt;table&lt;/span&gt; &lt;span class="sql-reserved"&gt;ADD&lt;/span&gt; &lt;span class="sql-reserved"&gt;FOREIGN&lt;/span&gt; &lt;span class="sql-reserved"&gt;KEY&lt;/span&gt; &lt;span class="sql-brackets"&gt;(&lt;/span&gt;&lt;span class="sql-reserved"&gt;column&lt;/span&gt;&lt;span class="sql-brackets"&gt;)&lt;/span&gt; &lt;span class="sql-reserved"&gt;REFERENCES&lt;/span&gt; &lt;span class="sql-identifier"&gt;other_table&lt;/span&gt;&lt;span class="sql-brackets"&gt;(&lt;/span&gt;&lt;span class="sql-reserved"&gt;column&lt;/span&gt;&lt;span class="sql-brackets"&gt;)&lt;/span&gt; &lt;span class="sql-reserved"&gt;ON&lt;/span&gt; &lt;span class="sql-reserved"&gt;DELETE&lt;/span&gt; &lt;span class="sql-reserved"&gt;CASCADE&lt;/span&gt;&lt;span class="sql-code"&gt;;
&lt;/span&gt;&lt;span class="sql-reserved"&gt;ALTER&lt;/span&gt; &lt;span class="sql-reserved"&gt;TABLE&lt;/span&gt; &lt;span class="sql-reserved"&gt;table&lt;/span&gt; &lt;span class="sql-reserved"&gt;ALTER&lt;/span&gt; &lt;span class="sql-reserved"&gt;COLUMN&lt;/span&gt; &lt;span class="sql-reserved"&gt;column&lt;/span&gt; &lt;span class="sql-reserved"&gt;SET&lt;/span&gt; &lt;span class="sql-reserved"&gt;CHECK&lt;/span&gt; &lt;span class="sql-reserved"&gt;IN&lt;/span&gt; &lt;span class="sql-brackets"&gt;(&lt;/span&gt;&lt;span class="sql-quotes"&gt;'&lt;/span&gt;&lt;span class="sql-string"&gt;Value 1&lt;/span&gt;&lt;span class="sql-quotes"&gt;'&lt;/span&gt;&lt;span class="sql-code"&gt;, &lt;/span&gt;&lt;span class="sql-quotes"&gt;'&lt;/span&gt;&lt;span class="sql-string"&gt;Value2&lt;/span&gt;&lt;span class="sql-quotes"&gt;'&lt;/span&gt;&lt;span class="sql-brackets"&gt;)&lt;/span&gt;&lt;span class="sql-code"&gt;;
 
&lt;/span&gt;&lt;span class="sql-reserved"&gt;ALTER&lt;/span&gt; &lt;span class="sql-reserved"&gt;TABLE&lt;/span&gt; &lt;span class="sql-reserved"&gt;table&lt;/span&gt; &lt;span class="sql-reserved"&gt;DROP&lt;/span&gt; &lt;span class="sql-reserved"&gt;PRIMARY&lt;/span&gt; &lt;span class="sql-reserved"&gt;KEY&lt;/span&gt;&lt;span class="sql-code"&gt;;
&lt;/span&gt;&lt;span class="sql-reserved"&gt;ALTER&lt;/span&gt; &lt;span class="sql-reserved"&gt;TABLE&lt;/span&gt; &lt;span class="sql-reserved"&gt;table&lt;/span&gt; &lt;span class="sql-reserved"&gt;DROP&lt;/span&gt; &lt;span class="sql-reserved"&gt;UNIQUE&lt;/span&gt; &lt;span class="sql-brackets"&gt;(&lt;/span&gt;&lt;span class="sql-identifier"&gt;column1&lt;/span&gt;&lt;span class="sql-code"&gt;, &lt;/span&gt;&lt;span class="sql-identifier"&gt;column2&lt;/span&gt;&lt;span class="sql-brackets"&gt;)&lt;/span&gt;&lt;span class="sql-code"&gt;;
&lt;/span&gt;&lt;span class="sql-reserved"&gt;ALTER&lt;/span&gt; &lt;span class="sql-reserved"&gt;TABLE&lt;/span&gt; &lt;span class="sql-reserved"&gt;table&lt;/span&gt; &lt;span class="sql-reserved"&gt;DROP&lt;/span&gt; &lt;span class="sql-reserved"&gt;FOREIGN&lt;/span&gt; &lt;span class="sql-reserved"&gt;KEY&lt;/span&gt; &lt;span class="sql-brackets"&gt;(&lt;/span&gt;&lt;span class="sql-reserved"&gt;column&lt;/span&gt;&lt;span class="sql-brackets"&gt;)&lt;/span&gt;&lt;span class="sql-code"&gt;;
&lt;/span&gt;&lt;span class="sql-reserved"&gt;ALTER&lt;/span&gt; &lt;span class="sql-reserved"&gt;TABLE&lt;/span&gt; &lt;span class="sql-reserved"&gt;table&lt;/span&gt; &lt;span class="sql-reserved"&gt;ALTER&lt;/span&gt; &lt;span class="sql-reserved"&gt;COLUMN&lt;/span&gt; &lt;span class="sql-reserved"&gt;column&lt;/span&gt; &lt;span class="sql-reserved"&gt;DROP&lt;/span&gt; &lt;span class="sql-reserved"&gt;CHECK&lt;/span&gt;&lt;span class="sql-code"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;
You can visit the &lt;a class="wiki" href="/docs/FlourishSql"&gt;FlourishSql&lt;/a&gt; page for a complete list of all of the supported
syntax.
&lt;/p&gt;
&lt;h2 id="Testing"&gt;Testing&lt;/h2&gt;
&lt;p&gt;
This sort of functionality wouldn’t really be possible without extensive
testing. The addition of &lt;a class="wiki" href="/docs/fSQLSchemaTranslation"&gt;fSQLSchemaTranslation&lt;/a&gt; was joined by over 1500 new
tests (when run on a server with all database extensions). Between the 12
different machines and configurations Flourish is tested on, the grand total
number of tests run on each commit increased by well over 10,000 tests.
&lt;/p&gt;
&lt;p&gt;
That said, the SQLite support is probably the least robust. While I’ve fairly
extensively tested that SQLite tables created from &lt;a class="wiki" href="/docs/FlourishSql"&gt;FlourishSql&lt;/a&gt; statements can
be altered, I would imagine there are some statements that may not work
properly on all databases. Luckily SQLite supports DDL statements within
transactions, meaning that your database will remain in a good state even if
something fails. If you do experience any issues with SQLite, please
&lt;a href="/newticket"&gt;open a ticket&lt;/a&gt; with your &lt;tt&gt;CREATE TABLE&lt;/tt&gt; statement and the
&lt;tt&gt;ALTER TABLE&lt;/tt&gt; statement you executed, and I’ll fix &lt;a class="wiki" href="/docs/fSQLSchemaTranslation"&gt;fSQLSchemaTranslation&lt;/a&gt; to
handle it.
&lt;/p&gt;
&lt;h2 id="AtomicNature"&gt;Atomic Nature&lt;/h2&gt;
&lt;p&gt;
One of the other things I set as a requirement for implementing &lt;tt&gt;ALTER TABLE&lt;/tt&gt;
support was to make individual statements atomic in nature. While it is
certainly possible that a SQL statement may fail, baring extenuating
circumstances with MySQL or DB2 such as a hard drive being full, Flourish can
ensure your database will either remain in its original state, or be
properly altered.
&lt;/p&gt;
&lt;p&gt;
To make sure that operations are performed completely, or not at all, there
are around 40 tests run per database system to test the atomic failure of
&lt;tt&gt;ALTER TABLE&lt;/tt&gt; statements. So like I said before, under normal operating
conditions, Flourish will keep your database in a good state.
&lt;/p&gt;
&lt;p&gt;
As I mentioned, there are some edge cases with MySQL and DB2. Unfortunately
MySQL does not support DDL statements within transactions, and
additionally, it requires removing foreign key constraints for many operations.
&lt;a class="wiki" href="/docs/fDatabase"&gt;fDatabase&lt;/a&gt; and &lt;a class="wiki" href="/docs/fSQLSchemaTranslation"&gt;fSQLSchemaTranslation&lt;/a&gt; are written in such a way that rollback
statements are created in case a statement fails. These rollback statements
undo any partially complete changes. It is theoretically possible that a
situation arises where MySQL will not permit the rollback statements to run
if a serious error occurs.
&lt;/p&gt;
&lt;p&gt;
In a similar vein, DB2 support transactions for DDL statements, but requires
table reorganization to occur after certain statements. This reorganization
implicitly commits any open transaction. The failure edge case for DB2 would
be if the primary statement succeeds and the reorganization succeeds, but
remaining statements that re-create constraints fail.
&lt;/p&gt;
&lt;h2 id="WhatsNext"&gt;What’s Next&lt;/h2&gt;
&lt;p&gt;
While this new functionality has undergone quite a bit of testing on my end,
I’m sure there are some edge-case bugs. It will certainly become more robust
over time as people like you take the time to &lt;a href="/newticket"&gt;open tickets&lt;/a&gt; and
report bugs.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/1yg_7h6Kl2M" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/AlterTableImproved</feedburner:origLink></item>
   <item>
	<title>PHP|Tek 2011</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Wed, 18 May 2011 13:01:16 EDT</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/oJzJALcso4U/PHPTek11</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/PHPTek11</guid>
	<description>&lt;p&gt;
One week from today, the annual PHP|Tek conference returns to Chicago for the 2011 edition. I'm excited that I'm able to attend this year, and I'd love to meet some Flourish users in person! So, whether you want to ask questions, suggest improvements, or grill me on the finer points of how to over-use regular expressions, I'm down. :-)
&lt;/p&gt;
&lt;p&gt;
The easiest way to get in contact will be through Twitter. I set up a separate twitter account, &lt;a class="ext-link" href="http://twitter.com/flourishlibconf"&gt;&lt;span class="icon"&gt;@flourishlibconf&lt;/span&gt;&lt;/a&gt;, for conferences so that I don't end up spamming normal followers. I'll also be available via my personal account, &lt;a class="ext-link" href="http://twitter.com/wbond"&gt;&lt;span class="icon"&gt;@wbond&lt;/span&gt;&lt;/a&gt;, but I'm going to try and keep that to replies. I look forward to meeting you there!
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/oJzJALcso4U" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/PHPTek11</feedburner:origLink></item>
   <item>
	<title>PHP Floating Point Bug</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Fri, 14 Jan 2011 14:02:02 EST</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/09Zd9WsiHcE/PHPFloatingPointBug</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/PHPFloatingPointBug</guid>
	<description>&lt;p&gt;
Just last week a rather serious denial of service (DoS) vulnerability was found in PHP, affecting versions 5.2.0 through 5.2.16 and 5.3.0 through 5.3.4. The bug, &lt;a class="ext-link" href="http://bugs.php.net/53632"&gt;&lt;span class="icon"&gt;#53632&lt;/span&gt;&lt;/a&gt;, causes PHP to enter an infinite loop when working with the value &lt;tt&gt;2.2250738585072011e-308&lt;/tt&gt; as a floating point number. The simple submission of this value to a site multiple times can easily cause the web server to become unresponsive to users.
&lt;/p&gt;
&lt;p&gt;
The good news is that if you are using &lt;a class="auto_api api" href="/api/fRequest#get" title="fRequest#get"&gt;fRequest::get()&lt;/a&gt; and passing &lt;tt&gt;float&lt;/tt&gt; to the &lt;tt&gt;$cast_to&lt;/tt&gt; parameter and Flourish &lt;a class="changeset" href="/changeset/950" title="Completed ticket #553 - fix fRequest to work with 3+ dimensional  ..."&gt;r950&lt;/a&gt; or newer, you will be automatically protected from this vulnerability. The value &lt;tt&gt;2.2250738585072011e-308&lt;/tt&gt; will be converted to &lt;tt&gt;2.2250738585072012e-308&lt;/tt&gt;, which resolves to the same floating point value, but does not cause the infinite loop.
&lt;/p&gt;
&lt;p&gt;
If you are using an older revision of Flourish, I strongly recommend you use the &lt;tt&gt;flourish.rev&lt;/tt&gt; file in your Flourish directory with the &lt;a href="/docs/BackwardsCompatibilityBreak"&gt;backwards compatibility breaks page&lt;/a&gt; to upgrade your code to the latest revision.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/09Zd9WsiHcE" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/PHPFloatingPointBug</feedburner:origLink></item>
   <item>
	<title>Testing Across 12 OSes, 10 Versions of PHP and 6 Databases</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Wed, 04 Aug 2010 14:02:30 EDT</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/GJ3S3Ag6uVM/60000Tests</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/60000Tests</guid>
	<description>&lt;p&gt;
Part of the goal of Flourish is to provide a solid library of code to build web apps and websites on top of. Since PHP runs on such a variety of operating systems and many users do not control the server they are installed on, operating system and PHP version compatibility is important. Thanks to recent donations by &lt;a class="ext-link" href="http://imarc.net"&gt;&lt;span class="icon"&gt;iMarc&lt;/span&gt;&lt;/a&gt; and Luke Foreman, the &lt;a class="wiki" href="/docs/Tests"&gt;testing setup&lt;/a&gt; has been expanded to include OS X 10.6 and Windows Server 2008.
&lt;/p&gt;
&lt;p&gt;
With these changes, &lt;a class="wiki" href="/docs/Tests"&gt;over 60,000 tests&lt;/a&gt; are run with every SVN commit, on a total of 10 different versions of PHP, running on 12 different server environments. All database-related tests are run on the six supported databases, and most are run using each of the 14 supported database extensions against eight different database versions. In situations where Flourish provides a pure-PHP fallback implementation of a non-standard PHP extension, the tests are run both with the non-standard extension loaded and not.
&lt;/p&gt;
&lt;div style="width: 600px;"&gt;
&lt;div class="stacked_first" style="width: 35%;"&gt;
	&lt;h3&gt;Operating Systems&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;CentOS 5.3&lt;/li&gt;
		&lt;li&gt;Debian 5.0&lt;/li&gt;
		&lt;li&gt;Fedora 12&lt;/li&gt;
		&lt;li&gt;FreeBSD 7.2&lt;/li&gt;
		&lt;li&gt;NetBSD 5.0.1&lt;/li&gt;
		&lt;li&gt;OpenBSD 4.5&lt;/li&gt;
		&lt;li&gt;OpenSolaris 2009.06&lt;/li&gt;
		&lt;li&gt;OpenSuSE 11.2&lt;/li&gt;
		&lt;li&gt;OS X 10.6&lt;/li&gt;
		&lt;li&gt;Ubuntu 8.04 LTS&lt;/li&gt;
		&lt;li&gt;Windows Server 2008&lt;/li&gt;
		&lt;li&gt;Windows XP&lt;/li&gt;
	&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="stacked" style="width: 25%;"&gt;
	&lt;h3&gt;PHP Versions&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;5.3.3&lt;/li&gt;
		&lt;li&gt;5.3.2&lt;/li&gt;
		&lt;li&gt;5.3.1&lt;/li&gt;
		&lt;li&gt;5.2.13&lt;/li&gt;
		&lt;li&gt;5.2.12&lt;/li&gt;
		&lt;li&gt;5.2.9&lt;/li&gt;
		&lt;li&gt;5.2.8&lt;/li&gt;
		&lt;li&gt;5.2.6&lt;/li&gt;
		&lt;li&gt;5.2.4&lt;/li&gt;
		&lt;li&gt;5.1.6&lt;/li&gt;
	&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="stacked"&gt;
	&lt;h3&gt;Databases&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;DB2 Express-C 9.7&lt;/li&gt;
		&lt;li&gt;MySQL 5.0&lt;/li&gt;
		&lt;li&gt;Oracle 10g XE&lt;/li&gt;
		&lt;li&gt;PostgreSQL 8.3&lt;/li&gt;
		&lt;li&gt;SQLite 2&lt;/li&gt;
		&lt;li&gt;SQLite 3&lt;/li&gt;
		&lt;li&gt;SQL Server 2005&lt;/li&gt;
		&lt;li&gt;SQL Server 2008&lt;/li&gt;
	&lt;/ul&gt;
&lt;/div&gt;
&lt;div style="clear: left;"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
At the end of the day, this helps to ensure that Flourish will work if you deploy it on a RHEL 4 server running PHP 5.1.6, a Windows Server 2008 machine running PHP 5.3.3 or a Solaris box with PHP 5.2.9.
&lt;/p&gt;
&lt;h2 id="TheSetup"&gt;The Setup&lt;/h2&gt;
&lt;p&gt;
Throwing around numbers is great and all, but I'd like to touch on the setup a little bit. Flourish uses &lt;a class="ext-link" href="http://phpunit.de"&gt;&lt;span class="icon"&gt;PHPUnit&lt;/span&gt;&lt;/a&gt; for unit and integration tests. And yes, many of the test aren't true unit tests. Since portability and compatibility are key, I want all of the code to actually run. If I were to have written pure unit tests, I would have mocked all sorts of dependencies and missed quite a number of bugs in PHP and bizarre edge cases.
&lt;/p&gt;
&lt;div style="text-align: center; float: left; margin-right: 1.5em; font-size: 0.8em; margin-top: 1.1em; margin-bottom: 1.5em;"&gt;
    &lt;a href="http://static.flourishlib.com/tests_example-large.png"&gt;&lt;img src="http://static.flourishlib.com/tests_example.png" alt="tests.php example output" style="border: 6px solid #b7b7b7;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;tt&gt;tests.php&lt;/tt&gt; example output
&lt;/div&gt;
&lt;p&gt;
PHPUnit contains an awesome amount of functionality, however when I started with it, it did not allow for running tests with different PHP configuration. I wouldn't be surprised if &lt;a class="ext-link" href="http://twitter.com/s_bergmann"&gt;&lt;span class="icon"&gt;Sebastian&lt;/span&gt;&lt;/a&gt; has added the functionality in 3.4 or 3.5, but I started this whole process back with 3.3 so I created my own solution. There is a PHP test runner &lt;tt&gt;tests.php&lt;/tt&gt; that parses class config files and runs the tests once for each different configuration. It has evolved over time, and isn't the prettiest thing I've ever written, but it gets the job done.
&lt;/p&gt;
&lt;p&gt;
&lt;tt&gt;tests.php&lt;/tt&gt; includes some other functionality, including a column-based, color-coded shell output for interactive testing and JSON output for automated testing. It allows for configuration values to be passed at run time (through a nasty PHP ini hack) so that passwords don't need to be hard coded in the tests and inadvertantly leaked through a source code repositories. In addition, you can included or exclude specific classes and filter the configurations to be run.
&lt;/p&gt;
&lt;div style="float: right; text-align: center; font-size: 0.8em; margin-left: 1.5em; margin-top: 1.1em; margin-bottom: 1.5em;"&gt;
    &lt;a href="http://static.flourishlib.com/remote_tests_example-large.png"&gt;&lt;img src="http://static.flourishlib.com/remote_tests_example.png" alt="remote_tests.sh example output" style="border: 6px solid #b7b7b7;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;tt&gt;remote_tests.sh&lt;/tt&gt; example output
&lt;/div&gt;
&lt;p&gt;
Once the local test runner once was written, I went to work setting up a bunch of virtual machines. There are a total of 12 VMs running on two different physical machines, an Intel i7 quad-core with 8GB of ram and a dual-core iMarc with 3GB ram. One of the virtual machines runs DB2, MySQL, Oracle and PostgreSQL, while another runs SQL Server 2005 and 2008. Every machine, including Windows, is running OpenSSH, allowing for key-based authentication and distribution of the tests. I leave the stock OS configuration alone as much as possible, but install PHP, various extensions, PHPUnit, some command line database programs and configure the various local sendmail implementations to route through an SMTP relay. Where possible I use the OS-supplied PHP packages in an effort to find bugs related to common environments.
&lt;/p&gt;
&lt;p&gt;
To run the rests on the virtual machines, I use a custom bash script &lt;tt&gt;remote_tests.sh&lt;/tt&gt; that &lt;tt&gt;scp&lt;/tt&gt;s a tarball to each machine and then invokes &lt;tt&gt;tests.php&lt;/tt&gt; over &lt;tt&gt;ssh&lt;/tt&gt;. &lt;tt&gt;remote_tests.sh&lt;/tt&gt; allows for parallel execution of the test scripts for the different database types, however I found that performance decreased due to disk thrashing. It also allows checking the remote server configuration to show the installed PHP version and the install status of both required and optional PHP extensions.
&lt;/p&gt;
&lt;p&gt;
I haven't spent much time abstracting or refining this setup for use by others, but I could see it being useful for library and framework maintainers. You can check out the code at &lt;a class="ext-link" href="http://github.com/wbond/flourish/tree/master/tests/"&gt;&lt;span class="icon"&gt;http://github.com/wbond/flourish/tree/master/tests/&lt;/span&gt;&lt;/a&gt;.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/GJ3S3Ag6uVM" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/60000Tests</feedburner:origLink></item>
   <item>
	<title>Offline Documentation</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Mon, 02 Aug 2010 15:03:47 EDT</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/Al5C0iMxX8Y/OfflineDocumentation</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/OfflineDocumentation</guid>
	<description>&lt;p&gt;
After a handful of requests, I finally took some time this weekend to create some offline documentation for Flourish. Starting with &lt;a class="changeset" href="/changeset/879" title="BackwardsCompatibilityBreak - removed support for ODBC from fDatabase,  ..."&gt;r879&lt;/a&gt;, every SVN commit and every time a class documentation page is updated, a single HTML page is created that contains all of the class documentation, API reference, and relevant general documentation.
&lt;/p&gt;
&lt;div style="text-align: center; margin: 2em 0;"&gt;&lt;a href="http://docs.flourishlib.com/single_page_docs/flourish_r880.html"&gt;&lt;img src="http://static.flourishlib.com/offline_docs.png" alt="Offline Documentation Preview" style="border: 6px solid #b7b7b7;" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;
The file uses the &lt;a class="ext-link" href="http://en.wikipedia.org/wiki/Data_URI_scheme"&gt;&lt;span class="icon"&gt;data URI scheme&lt;/span&gt;&lt;/a&gt; to allow for a single file containing all HTML, images, CSS and javascript. As long as you aren't using Internet Explorer, you'll even see the Flourish favicon.
&lt;/p&gt;
&lt;p&gt;
Unfortunately, IE6 and IE7 don't support the data URI scheme and thus may not show all images. You probably won't want to use IE anyway, since it can't handle the 4mb of HTML without slowing to a crawl. Chrome, Firefox, Opera and Safari all seem to perform just great.
&lt;/p&gt;
&lt;p&gt;
Head on over to the &lt;a href="/docs/Documentation"&gt;Documentation page&lt;/a&gt; to grab a copy while it's hot!
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/Al5C0iMxX8Y" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/OfflineDocumentation</feedburner:origLink></item>
   <item>
	<title>Do You Use ODBC?</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Tue, 22 Jun 2010 09:09:10 EDT</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/-BxAEhUXCsA/DoYouUseODBC</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/DoYouUseODBC</guid>
	<description>&lt;p&gt;
Recently I've been running into more issues with ODBC not properly handling &lt;a class="wiki" href="/docs/UTF-8"&gt;UTF-8&lt;/a&gt; and blob data across the various databases that Flourish supports. I'm very strongly considering dropping ODBC support due to the fact that:
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;None of the ODBC database drivers pass the tests on any OS but Windows
&lt;/li&gt;&lt;li&gt;There is no way to tell DB2 to use the &lt;a class="wiki" href="/docs/UTF-8"&gt;UTF-8&lt;/a&gt; encoding with ODBC
&lt;/li&gt;&lt;li&gt;Oracle via ODBC fails with &lt;a class="wiki" href="/docs/UTF-8"&gt;UTF-8&lt;/a&gt; so some characters must be escaped using &lt;tt&gt;CHR()&lt;/tt&gt;
&lt;/li&gt;&lt;li&gt;&lt;tt&gt;CURRENT_TIMESTAMP&lt;/tt&gt; isn't implemented for Oracle when using ODBC
&lt;/li&gt;&lt;li&gt;The &lt;tt&gt;pdo_odbc&lt;/tt&gt; driver in PHP 5.3 returns seemingly random data from an MSSQL blob column
&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;
Does anyone currently use an ODBC connection with &lt;a class="wiki" href="/docs/fDatabase"&gt;fDatabase&lt;/a&gt;?
&lt;/p&gt;
&lt;h2 id="Update"&gt;Update&lt;/h2&gt;
&lt;p&gt;
&lt;i&gt;7/31/10&lt;/i&gt; - As of &lt;a class="changeset" href="/changeset/879" title="BackwardsCompatibilityBreak - removed support for ODBC from fDatabase,  ..."&gt;revision 879&lt;/a&gt;, ODBC support is no longer provided in any of Flourish's database classes. ODBC support was removed since it was holding back perfect &lt;a class="wiki" href="/docs/UTF-8"&gt;UTF-8&lt;/a&gt; support, caused stability issues on some servers and did not appear to be used by anyone.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/-BxAEhUXCsA" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/DoYouUseODBC</feedburner:origLink></item>
   <item>
	<title>DB2 Support Added</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Wed, 14 Apr 2010 08:08:10 EDT</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/OXi_hZ59YEE/DB2SupportAdded</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/DB2SupportAdded</guid>
	<description>&lt;p&gt;
Last night I completed the final additions to the core database layer of Flourish by adding support for &lt;a class="ext-link" href="http://www.ibm.com/db2"&gt;&lt;span class="icon"&gt;IBM's DB2&lt;/span&gt;&lt;/a&gt;. Along with support in all of the core database classes, such as &lt;a class="wiki" href="/docs/fDatabase"&gt;fDatabase&lt;/a&gt; and &lt;a class="wiki" href="/docs/fResult"&gt;fResult&lt;/a&gt;, DB2 support was added to &lt;a class="wiki" href="/docs/fSchema"&gt;fSchema&lt;/a&gt; and &lt;a class="wiki" href="/docs/fSQLTranslation"&gt;fSQLTranslation&lt;/a&gt;, which means that DB2 is fully supported by the &lt;a class="wiki" href="/docs/ObjectRelationalMapping"&gt;ORM&lt;/a&gt;. The &lt;a class="wiki" href="/docs/FlourishSql"&gt;Flourish SQL&lt;/a&gt; page has been updated to show the non-translated compatibility of DB2 to the other supported databases.
&lt;/p&gt;
&lt;p&gt;
Currently only the &lt;a class="ext-link" href="http://php.net/ibm_db2"&gt;&lt;span class="icon"&gt;ibm_db2&lt;/span&gt;&lt;/a&gt; extension is supported for DB2 access due to issues with the others. The &lt;a class="ext-link" href="http://php.net/pdo_ibm"&gt;&lt;span class="icon"&gt;pdo_ibm&lt;/span&gt;&lt;/a&gt; extension currently has serious issues that cause PHP to segfault when trying to access CLOB or BLOB data. The &lt;a class="ext-link" href="http://php.net/odbc"&gt;&lt;span class="icon"&gt;odbc&lt;/span&gt;&lt;/a&gt; and &lt;a class="ext-link" href="http://php.net/pdo_odbc"&gt;&lt;span class="icon"&gt;pdo_odbc&lt;/span&gt;&lt;/a&gt; drivers are not currently supported because I have not found a way to get proper &lt;a class="wiki" href="/docs/UTF-8"&gt;UTF-8&lt;/a&gt; support on Windows machines. If you have any experience with DB2 on Windows, please &lt;a class="ext-link" href="http://www.ibm.com/developerworks/forums/thread.jspa?threadID=325160&amp;amp;tstart=0"&gt;&lt;span class="icon"&gt;check out my post&lt;/span&gt;&lt;/a&gt; on the IBM developerWorks forum.
&lt;/p&gt;
&lt;p&gt;
In the coming weeks I will be announcing SMTP support for &lt;a class="wiki" href="/docs/fEmail"&gt;fEmail&lt;/a&gt; and some more image manipulation functionality for &lt;a class="wiki" href="/docs/fImage"&gt;fImage&lt;/a&gt;. Feel free to &lt;a class="ext-link" href="http://twitter.com/flourishlib"&gt;&lt;span class="icon"&gt;follow Flourish on Twitter&lt;/span&gt;&lt;/a&gt;, or &lt;a class="ext-link" href="http://feeds2.feedburner.com/flourishlib_blog"&gt;&lt;span class="icon"&gt;subscribe to this blog&lt;/span&gt;&lt;/a&gt; to learn more when they are released. 
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/OXi_hZ59YEE" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/DB2SupportAdded</feedburner:origLink></item>
   <item>
	<title>Testing Enhancements</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Mon, 29 Mar 2010 23:11:50 EDT</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/mBamwPdpBQE/TestingEnhancements</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/TestingEnhancements</guid>
	<description>&lt;p&gt;
With the addition of &lt;a href="/blog/PreparedStatementSupportAdded"&gt;comprehensive prepared statement support&lt;/a&gt;, I felt it time to invest in an enhanced testing architecture to help ensure that Flourish is as portable as possible. The work described below was possible due to the generous support received through the &lt;a href="/docs/ServerFund"&gt;Server Fund&lt;/a&gt; last fall.
&lt;/p&gt;
&lt;p&gt;
The hardware purchased with the server fund included an Intel Core i7 860 processor and 8GB of ram. This hardware is used to run 11 different virtual machines:
&lt;/p&gt;
&lt;a href="/docs/Tests" style="float: right; margin-left: 2em; font-size: 0.85em; text-align: center; margin-bottom: 0.5em;"&gt;&lt;img src="http://static.flourishlib.com//tests.png" alt="Testing Output" style="display: block;" /&gt;Test History Graphs&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;A Debian database server running MySQL 5.0, PostgreSQL 8.3 and Oracle 10g XE
&lt;/li&gt;&lt;li&gt;A Windows XP machine used for running tests and running SQL Server 2005 and SQL Server 2008
&lt;/li&gt;&lt;li&gt;Machines for running tests, including the following operating systems:
&lt;ul&gt;&lt;li&gt;CentOS 5.3, PHP 5.1.6
&lt;/li&gt;&lt;li&gt;Debian 5.0, PHP 5.2.6
&lt;/li&gt;&lt;li&gt;Fedora 12, PHP 5.3.2
&lt;/li&gt;&lt;li&gt;FreeBSD 7.2, PHP 5.2.12
&lt;/li&gt;&lt;li&gt;NetBSD 5.0, PHP 5.2.13
&lt;/li&gt;&lt;li&gt;OpenBSD 4.5, PHP 5.2.8
&lt;/li&gt;&lt;li&gt;OpenSolaris 2009.06, PHP 5.2.9
&lt;/li&gt;&lt;li&gt;OpenSuSE 11.2, PHP 5.3.1
&lt;/li&gt;&lt;li&gt;Ubuntu 8.10 LTS, PHP 5.2.4
&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;
This extensive combination of operating systems and PHP versions ensure that Flourish is tested on most of the environments that may be encountered in the wild.
&lt;/p&gt;
&lt;p&gt;
To take advantage of this setup, an SVN post-commit hook is used to run the full test suite on all of the servers after each commit. As of the time of writing this article, 5989 tests have been written using &lt;a class="ext-link" href="http://www.phpunit.de/"&gt;&lt;span class="icon"&gt;PHPUnit&lt;/span&gt;&lt;/a&gt;. Each server reports the number of tests that passed, skipped, and failed. The &lt;a class="wiki" href="/docs/Tests"&gt;Tests page&lt;/a&gt; has graphs showing a history of the results for each server.
&lt;/p&gt;
&lt;p&gt;
Flourish has some extensive PHP and shell scripts that allow tests to be run on multiple different configurations per class and on remote servers with little effort. The different configurations allow running the tests with different PHP extensions loaded, or against different types of databases. When an extension or program is not available, or the test is not applicable to the current environment, it is skipped. It is by this functionality that all 16 supported database extensions can be tested.
&lt;/p&gt;
&lt;p&gt;
The current plans for improving this setup include obtaining a Mac Mini or notebook for OS X testing, and a copy of Microsoft Server 2008. If you, or someone you know, would be willing to donate either of these, please contact me at &lt;a class="ext-link" href="mailto:will@flourishlib.com"&gt;&lt;span class="icon"&gt;will@flourishlib.com&lt;/span&gt;&lt;/a&gt;.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/mBamwPdpBQE" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/TestingEnhancements</feedburner:origLink></item>
   <item>
	<title>Prepared Statement Support Added</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Thu, 04 Mar 2010 16:04:08 EST</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/6FwnEqiCyqg/PreparedStatementSupportAdded</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/PreparedStatementSupportAdded</guid>
	<description>&lt;p&gt;
Since back in December there has been kind of a lull in activity on Flourish due to some major work adding prepared statement support to &lt;a class="wiki" href="/docs/fDatabase"&gt;fDatabase&lt;/a&gt; and re-architecting the tests. The result of this work was a new class added to Flourish, &lt;a class="wiki" href="/docs/fStatement"&gt;fStatement&lt;/a&gt;, that works in combination with &lt;a class="wiki" href="/docs/fDatabase"&gt;fDatabase&lt;/a&gt; to provide prepared statement support across all database extensions. You can read more about it in the &lt;a class="wiki" href="/docs/fDatabase#PreparedStatements"&gt;fDatabase section about Prepared Statements&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
A good amount of time was spent adapting the various PHP extension APIs to work with the existing &lt;a class="auto_api api" href="/api/fDatabase#query" title="fDatabase#query"&gt;fDatabase::query()&lt;/a&gt; style of using data-type-specific placeholders. As you can see below, using prepared statements with Flourish will feel very natural if you have used the other query methods.
&lt;/p&gt;
&lt;div class="code php"&gt;&lt;pre&gt;&lt;span class="php-comment"&gt;//&lt;/span&gt;&lt;span class="php-comment"&gt; Prepare a statement&lt;/span&gt;
&lt;span class="php-var"&gt;$statement&lt;/span&gt;&lt;span class="php-code"&gt; = &lt;/span&gt;&lt;span class="php-var"&gt;$db&lt;/span&gt;&lt;span class="php-code"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="php-identifier"&gt;prepare&lt;/span&gt;&lt;span class="php-brackets"&gt;(&lt;/span&gt;&lt;span class="php-quotes"&gt;&amp;quot;&lt;/span&gt;&lt;span class="php-string"&gt;SELECT * FROM users WHERE user_id = %i&lt;/span&gt;&lt;span class="php-quotes"&gt;&amp;quot;&lt;/span&gt;&lt;span class="php-brackets"&gt;)&lt;/span&gt;&lt;span class="php-code"&gt;;&lt;/span&gt;
 
&lt;span class="php-comment"&gt;//&lt;/span&gt;&lt;span class="php-comment"&gt; Execute it any number of times&lt;/span&gt;
&lt;span class="php-var"&gt;$user_1&lt;/span&gt;&lt;span class="php-code"&gt; = &lt;/span&gt;&lt;span class="php-var"&gt;$db&lt;/span&gt;&lt;span class="php-code"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="php-identifier"&gt;query&lt;/span&gt;&lt;span class="php-brackets"&gt;(&lt;/span&gt;&lt;span class="php-var"&gt;$statement&lt;/span&gt;&lt;span class="php-code"&gt;, &lt;/span&gt;&lt;span class="php-number"&gt;1&lt;/span&gt;&lt;span class="php-brackets"&gt;)&lt;/span&gt;&lt;span class="php-code"&gt;;&lt;/span&gt;
&lt;span class="php-var"&gt;$user_2&lt;/span&gt;&lt;span class="php-code"&gt; = &lt;/span&gt;&lt;span class="php-var"&gt;$db&lt;/span&gt;&lt;span class="php-code"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="php-identifier"&gt;query&lt;/span&gt;&lt;span class="php-brackets"&gt;(&lt;/span&gt;&lt;span class="php-var"&gt;$statement&lt;/span&gt;&lt;span class="php-code"&gt;, &lt;/span&gt;&lt;span class="php-number"&gt;2&lt;/span&gt;&lt;span class="php-brackets"&gt;)&lt;/span&gt;&lt;span class="php-code"&gt;;&lt;/span&gt;
&lt;span class="php-comment"&gt;//&lt;/span&gt;&lt;span class="php-comment"&gt; …&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;
The &lt;a class="auto_api api" href="/api/fDatabase#prepare" title="fDatabase#prepare"&gt;fDatabase::prepare()&lt;/a&gt; method will create an &lt;a class="wiki" href="/docs/fStatement"&gt;fStatement&lt;/a&gt; object out of database-specific SQL string, while &lt;a class="auto_api api" href="/api/fDatabase#translatedPrepare" title="fDatabase#translatedPrepare"&gt;fDatabase::translatedPrepare()&lt;/a&gt; will translate the SQL throught &lt;a class="wiki" href="/docs/fSQLTranslation"&gt;fSQLTranslation&lt;/a&gt; before creating the object. The object can then be passed in place of a SQL string to &lt;a class="auto_api api" href="/api/fDatabase#query" title="fDatabase#query"&gt;fDatabase::query()&lt;/a&gt; or &lt;a class="auto_api api" href="/api/fDatabase#unbufferedQuery" title="fDatabase#unbufferedQuery"&gt;fDatabase::unbufferedQuery()&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
There are a couple of other methods that were added including &lt;a class="auto_api api" href="/api/fDatabase#execute" title="fDatabase#execute"&gt;fDatabase::execute()&lt;/a&gt; and &lt;a class="auto_api api" href="/api/fDatabate#translatedExecute" title="fDatabate#translatedExecute"&gt;fDatabate::translatedExecute()&lt;/a&gt;. These function the same as &lt;a class="auto_api api" href="/api/fDatabase#query" title="fDatabase#query"&gt;fDatabase::query()&lt;/a&gt; and &lt;a class="auto_api api" href="/api/fDatabase#translatedQuery" title="fDatabase#translatedQuery"&gt;fDatabase::translatedQuery()&lt;/a&gt;, respectively, except for the fact that they don't return anything. They will be useful for situations where the result of a SQL statement is not required, such as an &lt;tt&gt;UPDATE&lt;/tt&gt; statement. As you would expect, an &lt;a class="wiki" href="/docs/fStatement"&gt;fStatement&lt;/a&gt; object can be passed as the first parameter to &lt;a class="auto_api api" href="/api/fDatabase#execute" title="fDatabase#execute"&gt;fDatabase::execute()&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
I'll be posting another blog in the near future with some details of the new testing architecture, which was made possible by the &lt;a class="wiki" href="/docs/ServerFund"&gt;server fundraiser&lt;/a&gt; that was run last fall. A quick glance at the &lt;a class="wiki" href="/docs/Tests"&gt;Tests&lt;/a&gt; page will show that the tests run on each commit have gone up from around 2500 to over 42,000!
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/6FwnEqiCyqg" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/PreparedStatementSupportAdded</feedburner:origLink></item>
   <item>
	<title>Contributing</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Mon, 16 Nov 2009 14:02:12 EST</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/tiHxiXx95ao/Contributing</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/Contributing</guid>
	<description>&lt;p&gt;
Recently there has been some increased interest in contributing to Flourish. If you are interested in helping out with the project, I’m sure that everyone who uses it would be very grateful. The way that things of have been going recently, I’m going to start focusing more on approaching a stable release. Over the past year the beta has helped to improve the available functionality, increase its robustness and work out &lt;a href="/report/4"&gt;quite a number of bugs&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
As the code moves to a stable release, I foresee more of a focus on improving &lt;a href="/docs"&gt;documentation&lt;/a&gt; and writing &lt;a href="/docs/Tests"&gt;tests&lt;/a&gt;. There are also currently a number of &lt;a href="/report/1"&gt;tickets for enhancements&lt;/a&gt;, plus there are some items on the &lt;a class="wiki" href="/docs/Roadmap"&gt;original roadmap&lt;/a&gt; still to tackle.
&lt;/p&gt;
&lt;p&gt;
So, if you do have interest in contributing to the project, please consider how you may be able to help out with:
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Writing patches for &lt;a href="/report/1"&gt;tickets&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;Reading the &lt;a href="/docs"&gt;documentation&lt;/a&gt; and providing &lt;a href="/newticket"&gt;edits or improvements&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;Writing &lt;a href="/docs/Tests"&gt;tests&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;Answering questions in the &lt;a href="/discussion"&gt;forums&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;
I’m currently not looking to add much more to Flourish. Right now it serves as a fairly general-purpose library for website and application development, without being tied into third party services and without getting too much into markup generation. It has fairly good support across different environments and databases, and provides a more stream-lined API for a lot that is already possible with PHP.
&lt;/p&gt;
&lt;p&gt;
Third party services — things like twitter, flickr, payment gateways, etc — all require keeping up with changes to the APIs. I feel that individual libraries will be better able to keep up with changes to the services and providing product-specific features. In regards to the generation of HTML, since there are so many different approaches and styles, I think staying out of that arena as much as possible will help me to stay focused on what Flourish already does.
&lt;/p&gt;
&lt;p&gt;
If you are interested in writing code or editing documentation, please note that you will need to sign a &lt;a href="/docs/ContributorLicenseAgreements"&gt;contributor license agreement&lt;/a&gt; (CLA) to help protect users of Flourish and myself from legal issues.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/tiHxiXx95ao" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/Contributing</feedburner:origLink></item>
   <item>
	<title>New Oracle Support and More Tests</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Thu, 28 May 2009 13:01:00 EDT</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/bkjlvubIoTA/NewOracleSupportandMoreTests</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/NewOracleSupportandMoreTests</guid>
	<description>&lt;p&gt;
After some prodding from a few interested parties, I took it upon myself to add Oracle support to Flourish. There now exists full support for Oracle in the &lt;a class="wiki" href="/docs/fDatabase"&gt;fDatabase&lt;/a&gt;, &lt;a class="wiki" href="/docs/fResult"&gt;fResult&lt;/a&gt;, &lt;a class="wiki" href="/docs/fUnbufferedResult"&gt;fUnbufferedResult&lt;/a&gt;, &lt;a class="wiki" href="/docs/fSchema"&gt;fSchema&lt;/a&gt; and &lt;a class="wiki" href="/docs/fSQLTranslation"&gt;fSQLTranslation&lt;/a&gt; classes. I've targeted Oracle 10g since I have free access to that via Oracle Database 10g Express Edition, however I believe almost all of the functionality should work on older versions.
&lt;/p&gt;
&lt;p&gt;
In addition to adding support for Oracle, I took the past couple of months to add over &lt;a class="wiki" href="/docs/Tests"&gt;1800 new tests&lt;/a&gt; that exercise all 16 supported database extensions and cover most of the functionality of the &lt;a class="wiki" href="/docs/fDatabase"&gt;fDatabase&lt;/a&gt;, &lt;a class="wiki" href="/docs/fResult"&gt;fResult&lt;/a&gt;, &lt;a class="wiki" href="/docs/fUnbufferedResult"&gt;fUnbufferedResult&lt;/a&gt;, &lt;a class="wiki" href="/docs/fSchema"&gt;fSchema&lt;/a&gt; and &lt;a class="wiki" href="/docs/fSQLTranslation"&gt;fSQLTranslation&lt;/a&gt; classes.
&lt;/p&gt;
&lt;p&gt;
Like other supported databases, the Oracle support in &lt;a class="wiki" href="/docs/fDatabase"&gt;fDatabase&lt;/a&gt; will work with any of the available database extensions for Oracle. This includes OCI8, PDO_OCI, ODBC and PDO_ODBC. From my testing, the ODBC extensions only work on Windows because some of the &lt;tt&gt;ALTER SESSION&lt;/tt&gt; commands executed by &lt;a class="wiki" href="/docs/fDatabase"&gt;fDatabase&lt;/a&gt; are not supported by the UnixODBC driver. If you have any details on a better way to configure ODBC on Linux/BSD, please let me know.
&lt;/p&gt;
&lt;p&gt;
In closing I'd like to say thanks to Chris Jones from Oracle and Aurélien Chivot for their assistance during this process!
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/bkjlvubIoTA" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/NewOracleSupportandMoreTests</feedburner:origLink></item>
   <item>
	<title>Discussions and Comments</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Wed, 14 Jan 2009 13:01:26 EST</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/npliuPXpFOs/DiscussionsandComments</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/DiscussionsandComments</guid>
	<description>&lt;p&gt;
Just a few days ago I posted links to Flourish on both &lt;a class="ext-link" href="http://news.ycombinator.com"&gt;&lt;span class="icon"&gt;Hacker News&lt;/span&gt;&lt;/a&gt; and the &lt;a class="ext-link" href="http://reddit.com/r/PHP"&gt;&lt;span class="icon"&gt;PHP Reddit&lt;/span&gt;&lt;/a&gt;. There has been some great conversation about Flourish on those sites and on a thread over on the &lt;a class="ext-link" href="http://codeigniter.com/forums/"&gt;&lt;span class="icon"&gt;CodeIgnitor forums&lt;/span&gt;&lt;/a&gt;.
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a class="ext-link" href="http://news.ycombinator.com/item?id=431062"&gt;&lt;span class="icon"&gt;Flourish on Hacker News&lt;/span&gt;&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a class="ext-link" href="http://www.reddit.com/r/PHP/comments/7p7no/flourish_a_developerfriendly_php_library/"&gt;&lt;span class="icon"&gt;Flourish on Reddit&lt;/span&gt;&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a class="ext-link" href="http://codeigniter.com/forums/viewthread/102299/"&gt;&lt;span class="icon"&gt;CodeIgnitor Forums: Is the reign of frameworks over?&lt;/span&gt;&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;
If you run across any other conversations, I'd love to hear about them. And as always, please feel free to comment on this post or &lt;a href="/discussion"&gt;start a thread&lt;/a&gt; with any suggestions or questions you may have.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/npliuPXpFOs" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/DiscussionsandComments</feedburner:origLink></item>
   <item>
	<title>Flourish Demo Site</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Mon, 05 Jan 2009 13:01:35 EST</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/-NuUiNPcyQ4/FlourishDemoSite</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/FlourishDemoSite</guid>
	<description>&lt;p&gt;
If you've never worked with Flourish before, getting started building a site may seem a little daunting. Included below is the description and source code for a production site written with Flourish and SQLite.
&lt;/p&gt;
&lt;p&gt;
The &lt;a class="ext-link" href="http://northshorewebgeeks.com"&gt;&lt;span class="icon"&gt;northshorewebgeeks.com&lt;/span&gt;&lt;/a&gt; site provides a simple list of upcoming and past meetups for the North Shore Web Geeks meetup. Rather than hand-editing the HTML and RSS feeds, Flourish was set up to provide a simple CMS to easily update the information.
&lt;/p&gt;
&lt;h2 id="SourceCode"&gt;Source Code&lt;/h2&gt;
&lt;p&gt;
The source code for the demo can be found in the &lt;a class="ext-link" href="https://github.com/wbond/flourish-demo-site"&gt;&lt;span class="icon"&gt;flourish-demo-site repository&lt;/span&gt;&lt;/a&gt; on Github. Github has a nice little code browser, so you can view the code without downloading or cloning.
&lt;/p&gt;
&lt;h2 id="Routing"&gt;Routing&lt;/h2&gt;
&lt;p&gt;
The site is fairly simple, so I set up Apache with &lt;a class="ext-link" href="http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html"&gt;&lt;span class="icon"&gt;mod_rewrite&lt;/span&gt;&lt;/a&gt; to create some nice, clean URLs:
&lt;/p&gt;
&lt;pre class="wiki"&gt;/                     # -&amp;gt; index.php  : Home/main page
/rss                  # -&amp;gt; index.php  : RSS feed
/manage               # -&amp;gt; manage.php : Lists all meetups
/manage/add           # -&amp;gt; manage.php : Allows adding a meetup
/manage/{date}/edit   # -&amp;gt; manage.php : Allows editing a meetup
/manage/{date}/delete # -&amp;gt; manage.php : Allows deleting a meetup
/log_in               # -&amp;gt; login.php  : Allows a user to log in
/log_out              # -&amp;gt; login.php  : Lets the user log out
/sup/*                # -&amp;gt; sup/*      : Static files including CSS and images
&lt;/pre&gt;&lt;p&gt;
Anything other than those URLs will cause the page at &lt;tt&gt;views/404.php&lt;/tt&gt; to be shown.
&lt;/p&gt;
&lt;h2 id="DirectoryStructure"&gt;Directory Structure&lt;/h2&gt;
&lt;p&gt;
The files on the filesystem are organized in the following structure:
&lt;/p&gt;
&lt;pre class="wiki"&gt;/                     # The three php scripts that handle requests
/inc/                 # The bootstrap script init.php and config file
/inc/classes/         # The ORM classes
/inc/flourish/        # Flourish classes
/storage/db/          # The SQLite database the source .sql file
/storage/session/     # The PHP session files
/sup/css/             # The CSS files
/sup/img/             # The images
/views/               # The HTML templates for the site
&lt;/pre&gt;&lt;h2 id="RequestHandling"&gt;Request Handling&lt;/h2&gt;
&lt;p&gt;
As requests are received, they are routed the appropriate PHP page by &lt;tt&gt;mod_rewrite&lt;/tt&gt;, however each of these pages first runs the bootstrapping code in &lt;tt&gt;inc/&lt;/tt&gt;. Here is an example of the execution order:
&lt;/p&gt;
&lt;pre class="wiki"&gt;config.php -&amp;gt; init.php -&amp;gt; manage.php
&lt;/pre&gt;&lt;h2 id="LiveInstance"&gt;Live Instance&lt;/h2&gt;
&lt;p&gt;
The site is currently running live on &lt;a class="ext-link" href="http://demo.flourishlib.com"&gt;&lt;span class="icon"&gt;http://demo.flourishlib.com&lt;/span&gt;&lt;/a&gt;. You can log in with the following information:
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Login:&lt;/strong&gt; admin
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Password:&lt;/strong&gt; password
&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;
Right now the site will allow you to edit anything, however I may need to disabled saving changes if the site is spammed or inappropriate content is added.
&lt;/p&gt;
&lt;h2 id="Installation"&gt;Installation&lt;/h2&gt;
&lt;p&gt;
If you wish to run the demo site on your own server, you’ll need to download the source from github and recursively &lt;tt&gt;chmod&lt;/tt&gt; the &lt;tt&gt;storage&lt;/tt&gt; directory to &lt;tt&gt;777&lt;/tt&gt;. This allows the web server to write to the SQLite database and session directory.
&lt;/p&gt;
&lt;pre class="wiki"&gt;chmod -R 777 /path/to/flourish_demo_site/storage
&lt;/pre&gt;&lt;p&gt;
All files included with the demo site, except for graphics and CSS files, are licensed under the MIT license. Graphics and CSS files are only provided for demo purposes. Please see the &lt;tt&gt;license.txt&lt;/tt&gt; file for more details.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/-NuUiNPcyQ4" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/FlourishDemoSite</feedburner:origLink></item>
   <item>
	<title>SQLite 3.2.8 Binary</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Sat, 03 Jan 2009 23:11:43 EST</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/yrMZLGhdNqE/Sqlite3.2.8Binary</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/Sqlite3.2.8Binary</guid>
	<description>&lt;p&gt;
If you are working with a server running PHP 5.1.x (such as a VPS with CentOS 4) you may have run into an issue with using SQLite as a database. The version of the &lt;tt&gt;sqlite3&lt;/tt&gt; command line program is 3.3.6, however the version of the SQLite library used for the PDO SQLite driver is 3.2.8. To complicate matters further, between versions 3.2.8 and 3.3.0 the database file format was changed in a way that databases created by 3.3.0 and newer are not readable by 3.2.8 and before.
&lt;/p&gt;
&lt;p&gt;
&lt;i&gt;In practical terms, this means you can't use the &lt;tt&gt;sqlite3&lt;/tt&gt; binary provided by the OS to create a database to use with PHP.&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
Unfortunately the SQLite website has removed all source and binary files for everything before 3.6.x. While I was unable to find a 3.2.8 binary for linux, I was able to find a copy of the source tarball from an old Ubuntu repository, and I have mirrored it here along with a statically linked binary that I compiled.
&lt;/p&gt;
&lt;h2 id="Downloads"&gt;Downloads&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a class="ext-link" href="http://static.flourishlib.com/sqlite_3.2.8/sqlite3"&gt;&lt;span class="icon"&gt;SQLite 3.2.8 Linux Binary&lt;/span&gt;&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a class="ext-link" href="http://static.flourishlib.com/sqlite_3.2.8/sqlite3_3.2.8.tar.gz"&gt;&lt;span class="icon"&gt;SQLite 3.2.8 Tarball&lt;/span&gt;&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="SimpleQuickInstructions"&gt;Simple/Quick Instructions&lt;/h2&gt;
&lt;p&gt;
The following directions will allow you to create a new SQLite 3.2.8 database on any linux server where you have SSH access:
&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Log onto the server
&lt;/li&gt;&lt;li&gt;Execute: &lt;tt&gt;wget http://static.flourishlib.com/sqlite_3.2.8/sqlite3&lt;/tt&gt;
&lt;/li&gt;&lt;li&gt;Execute: &lt;tt&gt;chmod 755 sqlite3&lt;/tt&gt;
&lt;/li&gt;&lt;li&gt;Create a database: &lt;tt&gt;./sqlite3 my_new_db&lt;/tt&gt;
&lt;/li&gt;&lt;/ol&gt;&lt;h2 id="Compiling"&gt;Compiling&lt;/h2&gt;
&lt;p&gt;
If the pre-compiled binary I provided above does not work on your system, you should be able to fairly easily compile your own binary. You'll need standard compilation tools such as gcc, make, etc installed on your system.
&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;tt&gt;tar xvfz sqlite3_3.2.8.tar.gz&lt;/tt&gt;
&lt;/li&gt;&lt;li&gt;&lt;tt&gt;cd sqlite-3.2.8&lt;/tt&gt;
&lt;/li&gt;&lt;li&gt;&lt;tt&gt;./configure --disable-tcl --disable-shared&lt;/tt&gt;
&lt;/li&gt;&lt;li&gt;&lt;tt&gt;make&lt;/tt&gt;
&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;
Once those four steps are complete, there will be an executable named &lt;tt&gt;sqlite3&lt;/tt&gt; in the current directory. You can use that to create databases that will be compatible with the PDO SQLite driver in PHP 5.1.x.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/yrMZLGhdNqE" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/Sqlite3.2.8Binary</feedburner:origLink></item>
   <item>
	<title>Announcing the Flourish Beta</title>
	 <author>will@flourishlib.com</author>
	<pubDate>Wed, 19 Nov 2008 13:01:00 EST</pubDate>
	<link>http://feedproxy.google.com/~r/flourishlib_blog/~3/m5RX5UNIfO0/AnnouncingtheFlourishBeta</link>
	<guid isPermaLink="false">http://flourishlib.com/blog/AnnouncingtheFlourishBeta</guid>
	<description>&lt;p&gt;
After about a year and a half of development and approximately 150k lines of code changes, Flourish is now officially in beta.
&lt;/p&gt;
&lt;p&gt;
Flourish is a general PHP library that is focused on being robust, yet easy to use, secure, portable and well documented. It is specifically &lt;i&gt;not&lt;/i&gt; referred to as a framework because it is quite different from most of the PHP MVC frameworks currently available.
&lt;/p&gt;
&lt;h2 id="ProjectOverview"&gt;Project Overview&lt;/h2&gt;
&lt;p&gt;
Here is a brief overview of the library:
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;It is &lt;a href="/license"&gt;licensed under the MIT license&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;It works with PHP 5.1+
&lt;/li&gt;&lt;li&gt;It loves Linux/BSD, Solaris and Windows environments
&lt;/li&gt;&lt;li&gt;It includes &lt;a href="/docs"&gt;extensive documentation&lt;/a&gt; covering &lt;a class="missing wiki" href="/docs/ClassDocs" rel="nofollow"&gt;all code?&lt;/a&gt;, plus the &lt;a class="missing wiki" href="/docs/ApiDocs" rel="nofollow"&gt;API?&lt;/a&gt; and other &lt;a class="missing wiki" href="/docs/GeneralDocs" rel="nofollow"&gt;general PHP topics?&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;It includes &lt;a class="wiki" href="/docs/Security"&gt;features and guidance to make sites more secure&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;No shell access is required, simply &lt;a class="wiki" href="/docs/GettingStarted"&gt;drop the classes in and go&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;It uses &lt;a class="wiki" href="/docs/UTF-8"&gt;UTF-8&lt;/a&gt; everywhere and provides &lt;a class="wiki" href="/docs/fUTF8"&gt;UTF-8 functions&lt;/a&gt; even without the &lt;a class="ext-link" href="http://php.net/mbstring"&gt;&lt;span class="icon"&gt;mbstring&lt;/span&gt;&lt;/a&gt; extension
&lt;/li&gt;&lt;li&gt;It supports &lt;a class="wiki" href="/docs/fDatabase"&gt;MySQL, PostgreSQL, SQLite and Microsoft SQL Server&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;It includes support for &lt;a class="wiki" href="/docs/FlourishSql"&gt;one dialect of SQL&lt;/a&gt; across all database types
&lt;/li&gt;&lt;li&gt;It supports almost &lt;a class="api" href="/api/fDatabase" title="fDatabase"&gt;all extensions for the supported databases&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;It includes powerful, but intuitive &lt;a class="wiki" href="/docs/ObjectRelationalMapping"&gt;object-relational mapping&lt;/a&gt; features
&lt;ul&gt;&lt;li&gt;Full support and auto-exploration of &lt;a class="wiki" href="/docs/fActiveRecord#RelatedRecordsOperations"&gt;foreign key relationships&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;Simple, shorthand notation for &lt;a class="wiki" href="/docs/fRecordSet"&gt;querying sets of records&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a class="wiki" href="/docs/fActiveRecord#CreatingandLoadingRecords"&gt;Multi-column primary key support&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a class="wiki" href="/docs/fORM#ExtendingtheORM"&gt;A simple plugin system&lt;/a&gt; using hooks and callbacks
&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;It can &lt;a class="wiki" href="/docs/fImage"&gt;manipulate images&lt;/a&gt; and automatically detects if GD or ImageMagick is installed
&lt;/li&gt;&lt;li&gt;It provides &lt;a class="wiki" href="/docs/fNumber"&gt;precise number support&lt;/a&gt; even without the &lt;a class="ext-link" href="http://php.net/bc"&gt;&lt;span class="icon"&gt;bcmath&lt;/span&gt;&lt;/a&gt; extension
&lt;/li&gt;&lt;li&gt;It backports some PHP 5.2+ functionality to PHP 5.1 such as &lt;a class="wiki" href="/docs/fCookie"&gt;Httponly cookies&lt;/a&gt; and &lt;a class="wiki" href="/docs/fJSON"&gt;JSON&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;It includes &lt;a class="wiki" href="/docs/fCore"&gt;error/exception handling and debugging features&lt;/a&gt; that make bug fixing much simpler 
&lt;/li&gt;&lt;li&gt;It is &lt;a class="wiki" href="/docs/InternationalizationLocalization"&gt;built with internationalization and localization in mind&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="GeneralThemes"&gt;General Themes&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Almost every single one of the &lt;a class="source" href="/browser/"&gt;59 classes&lt;/a&gt; provides functionality useful to end-developers and the class APIs have been tweaked to be easy to use and understand
&lt;/li&gt;&lt;li&gt;There is no desire for the project to provide an MVC architecture/framework, instead the focus is on providing a usable and modular set of classes to help solve common web development issues 
&lt;/li&gt;&lt;li&gt;Instead of having monolithic and infrequent releases, each class is versioned separately and the library as a whole is versioned by the subversion revision number for easy updates and bug fixes
&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="FurtherReading"&gt;Further Reading&lt;/h2&gt;
&lt;p&gt;
If you are interested in some more information, please check out:
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a class="wiki" href="/docs/Download"&gt;Download&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a class="wiki" href="/docs/GettingStarted"&gt;Getting Started&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a class="wiki" href="/docs/HowDoI"&gt;How Do I … ?&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="/docs"&gt;Documentation&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="Thanks"&gt;Thanks&lt;/h2&gt;
&lt;p&gt;
As a final note, I’d like to say thanks to the following people for their encouragement and assistance in the development and testing of Flourish: &lt;a class="ext-link" href="http://adaptivehatch.com"&gt;&lt;span class="icon"&gt;Craig Ruksznis&lt;/span&gt;&lt;/a&gt;, &lt;a class="ext-link" href="http://buoyantship.com"&gt;&lt;span class="icon"&gt;Patrick McPhail&lt;/span&gt;&lt;/a&gt;, &lt;a class="ext-link" href="http://davetufts.com"&gt;&lt;span class="icon"&gt;Dave Tufts&lt;/span&gt;&lt;/a&gt; and &lt;a class="ext-link" href="http://imarc.net/bill"&gt;&lt;span class="icon"&gt;Bill Bushee&lt;/span&gt;&lt;/a&gt;.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/flourishlib_blog/~4/m5RX5UNIfO0" height="1" width="1"/&gt;</description>
   <feedburner:origLink>http://flourishlib.com/blog/AnnouncingtheFlourishBeta</feedburner:origLink></item>
 </channel>
</rss>

