<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BIT Consultants &#187; PHP</title>
	<atom:link href="http://www.bitconsultants.net/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bitconsultants.net</link>
	<description></description>
	<lastBuildDate>Sun, 25 Jul 2010 21:54:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Validating Data with Enhanced Declarative Data Integrity Rules</title>
		<link>http://www.bitconsultants.net/2010/validating-data-using-tuples-stored-in-column-comments/</link>
		<comments>http://www.bitconsultants.net/2010/validating-data-using-tuples-stored-in-column-comments/#comments</comments>
		<pubDate>Sat, 08 May 2010 05:48:09 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://www.bitconsultants.net/?p=255</guid>
		<description><![CDATA[Visit us at our new Google Code project page: http://code.google.com/p/metadata-validator/ Problem Definition Data validation and integrity assurance are complex subjects that have strong opinions tied to the way they are implemented. Some strongly feel that the database can handle validation using the column&#8217;s attributes (size,...]]></description>
			<content:encoded><![CDATA[<p><strong>Visit us at our new Google Code project page: <a href="http://code.google.com/p/metadata-validator/">http://code.google.com/p/metadata-validator/</a></strong></p>
<h2>Problem Definition</h2>
<p>Data validation and integrity assurance are complex subjects that have strong opinions tied to the way they are implemented. Some strongly feel that the database can handle validation using the column&#8217;s attributes (size, data type, etc) and TRIGGERS/STORED PROCEDURES can provide means to enforce complex business rules. This is true, but there are many caveats and arguments against this approach. Should a data source be performing logic? According to <a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28318/triggers.htm#g22503">Oracle&#8217;s website</a>:</p>
<p style="padding-left: 30px;">&#8220;<em>Although triggers are useful for customizing a database, use them only when necessary. Excessive use of triggers can result in complex interdependencies, which can be difficult to maintain in a large application</em>&#8220;</p>
<p>Those in opposition to this approach feel that it is not the job of the database to perform logic, only to store data. So, who is right?<br />
How should data validation be handled? Triggers or code? Honestly, both is usually the practice. The current implementations of Declarative Data Integrity Rules in the database marketplace give us simple rules to validate against (again: size, data type, nullable, etc) and if we don&#8217;t validate data in our code prior to insertion the database errors out. Though mindless and tedious, it is a straightforward task to code validation prior to executing SQL in your programming language.</p>
<p>I think that both opinions are correct, but both approaches are inadequate. Logic <strong><em>should </em></strong>be separated from data. However, rules about data stored in your database are really metadata. Why should programmers have to tweak code every time the table changes? Why should DBAs have to worry that programmers validation is insufficient and not have any control over the data integrity? I believe the database should dictate to us, in specific terms, what it is expecting. In addition, programmers and DBAs should be able to work together to formulate the data validation and that is should be in only one place.</p>
<h2>Current Practice</h2>
<p>Most of the time, a DBA will create a table with data type, length, unique and referential constraints. These rules are enforced by the database, programmers are handed back an error message which has to be parsed into a friendly error. In some shops, STORED PROCEDURES and TRIGGERS are used to validate data prior to insertion. As we pointed out above, this is not an encouraged practice and makes a data source a logic engine.</p>
<p>Let&#8217;s say we have a table defined as such:</p>
<pre class="brush: sql;">

id INT(8) NOT NULL,
name VARCHAR(40),
zip_code VARCHAR(10)
</pre>
<p>Programmers take the constraints defined above (i.e. &#8220;INT&#8221;, &#8220;NOT NULL&#8221;, 40, etc) and write up code validation for each of those columns. If DBAs alter the number of columns or the metadata of any one of the columns, the code needs to be updated accordingly. Conversely, if the programmers don&#8217;t properly validate the raw data in code, we could easily end up with &#8220;NOTAZIP&#8221; in our zip_code field. In this way, the technologies are seemingly blind of each other except for a tin-can phone that can pass simple messages back and forth. This is not a knock against the technology, they were made to be platform independent (in terms of interfacing) and not necessarily to know everything about each other.  This is the price we have to pay for an exceedingly friendly means of storing and retrieving data.</p>
<h2>Proposed Solution</h2>
<p>Utilizing dynamic functions, JSON and metadata stored in column comments of my database I was able to validate data against any table with only one validation class (that isn&#8217;t very long!). I have yet to see a column or table comment be anything slightly useful (if anything at all). Up until two days ago, every time I saw the field to insert a comment in phpmyadmin  I would think &#8220;I guess that&#8217;s a nice feature&#8230;&#8221;, and then move on. Then I realized that using (in MySQL) SHOW FULL COLUMN FROM {TABLE}, I can get that comment&#8217;s value back. And using my programming language (PHP), I could do the following:</p>
<pre class="brush: php;">

$data = json_decode($comment);
</pre>
<p>I now am holding an object created from metadata to do what I will with.</p>
<p>The initial data I inserted into a column COMMENT was a minified representation of this:</p>
<pre class="brush: jscript;">
'{	&quot;insert_helpers&quot;: {
		&quot;functions&quot;: {
			&quot;func1&quot;:{
				&quot;name&quot;:&quot;strtotime&quot;,
				&quot;params&quot;:{
					&quot;param1&quot;:&quot;+20 years&quot;
				}
			},
			&quot;func2&quot;:{
				&quot;name&quot;:&quot;str_replace&quot;,
				&quot;params&quot;:{
					&quot;param1&quot;:&quot;!!&quot;,
					&quot;param2&quot;:&quot;!&quot;,
					&quot;param3&quot;:&quot;@this&quot;,
				}
			}
		}
	},
	&quot;validators&quot;: {
		&quot;maxlength&quot;:&quot;10&quot;,
		&quot;minlength&quot;:&quot;2&quot;,
		&quot;patterns&quot;:{
			&quot;pattern1&quot;:{
				&quot;pattern&quot;:&quot;[^0-9]&quot;,
				&quot;example&quot;:&quot;This is data without numbers&quot;
			}
		}
	}
}'
</pre>
<p>This was then validated with code very similar to this:</p>
<pre class="brush: php;">
/**
*
* NOTE: I have not tested this code
* I typed directly it into notepad++ for your reading,
* not for executing, if it works, great!
*
*/
$json 				= json_decode($comment);
$helper_functions 	        = $json-&gt;{'insert_helpers'};
$validators			= $json-&gt;{'validators'};
$errors				= array();

//$row_value = $result['field'];
foreach($helper_functions as $function)
{
	$params = array();
	foreach($function-&gt;{'params'} as $param)
	{
		//insert row value
		if($param == '@this')
		{
			$param = str_replace(&quot;@this&quot;, $row_value, $param);
		}
		array_push($params, $param);
	}
	if(is_callable($function-&gt;{'name'})
	{
		$row_value = call_user_func_array($function-&gt;{'name'}, $params);
	}
}

if(is_object($validators))
{
	if(is_object($validators-&gt;{'minlength'})
	{
		if(sizeof($row_value) &lt; $validators-&gt;{'minlength'})
		{
			array_push($errors, &quot;$row_value is not long enough&quot;);
		}
	}
	if(is_object($validators-&gt;{'maxlength'})
	{
		if(sizeof($row_value) &gt; $validators-&gt;{'maxlength'})
		{
			array_push($errors, &quot;$row_value is too long&quot;);
		}
	}
	if(is_object($validators-&gt;{'patterns'})
	{
		foreach($validators-&gt;{'patterns'} as $pattern)
		{
			if(preg_match(&quot;/$pattern-&gt;{'pattern'}/&quot;, $row_value))
			{
				array_push($errors, &quot;$row_value is not in correct format [example: $pattern-&gt;{'example'}&quot;);
			}
		}
	}
}
</pre>
<p>If you didn&#8217;t pick it up by reading through the code, these functions couldn&#8217;t care less what table you are dealing with and the same set of code works against any and all columns. In addition, the validation rules (JSON) can be handed to the client side code to perform validation prior to reaching the server. All major databases have a comment column and most modern programming languages allow behavior like the example I posted.</p>
<p>I will post my php class that facilitates this process soon.</p>
<p>Anxious to hear people&#8217;s thoughts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitconsultants.net/2010/validating-data-using-tuples-stored-in-column-comments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Geocoding with Google Maps and the Zend Framework</title>
		<link>http://www.bitconsultants.net/2010/geocoding-with-google-maps-and-the-zend-framework/</link>
		<comments>http://www.bitconsultants.net/2010/geocoding-with-google-maps-and-the-zend-framework/#comments</comments>
		<pubDate>Sat, 24 Apr 2010 17:51:40 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Geocoding]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[Maps]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.bitconsultants.net/?p=231</guid>
		<description><![CDATA[Maps are a great way to engage your users and visualize data, but it can be a little tricky to setup. Here I will walk you through the steps needed to get a map up and running. // Sign Up Apply for a Google Maps...]]></description>
			<content:encoded><![CDATA[<p>Maps are a great way to engage your users and visualize data, but it can be a little tricky to setup. Here I will walk you through the steps needed to get a map up and running.<br />
<script type="text/javascript">// <![CDATA[
 google_ad_client = "pub-4761320180230999"; /* 468x15, created 5/5/10 */ google_ad_slot = "9379654790"; google_ad_width = 468; google_ad_height = 15;
// ]]&gt;</script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
</script></p>
<h3>Sign Up</h3>
<p>Apply for a Google Maps API Key (free) here using your domain without a subdomain or www (this will allow you to use key with or without www and on subdomains): http://code.google.com/apis/maps/signup.html</p>
<h3>Configuration</h3>
<p>Put the API key in your configuration file (application.ini, config.ini, etc.) like this:</p>
<pre class="brush: php;">
[google]
google_map_key =  YOUR_KEY
</pre>
<h3>Bootstrapping</h3>
<p>In your index.php file, add the following code:</p>
<pre class="brush: php;">
//update CONFIG_PATH to point to your configuration file
defined(CONFIG_PATH)
or define('CONFIG_PATH', APPLICATION_PATH . '/configs/application.ini');
Zend_Registry::set('google',    new Zend_Config_Ini(CONFIG_PATH, 'google'));
</pre>
<p>This will add your api key to the registry so that it can be accessed throughout your application.</p>
<h3>Model</h3>
<p>In your models directory, create a new class called &#8216;Geocoder.php&#8217;. This will be the file that contains the application logic for retreiving coordinates on a given location.</p>
<p><strong>models/Geocoder.php</strong></p>
<pre class="brush: php;">

/**
* Geocoder
*
* @author Robert McVey
*/
class Geocoder {
	protected $key = &amp;quot;&amp;quot;;
	public function __construct($apiKey)
	{
		$this-&gt;key = $apiKey;
	}
	private function _getGeocodedLatitudeAndLongitude($address)
	{
		$client = new Zend_Http_Client();
		$client-&gt;setUri($this-&gt;getGeocodingUri());
		$client-&gt;setParameterGet('q', urlencode($address))
			-&gt;setParameterGet('output', 'json')
			-&gt;setParameterGet('sensor', 'false')
			-&gt;setParameterGet('key', $this-&gt;key);
		$result = $client-&gt;request('GET');
		$response = Zend_Json_Decoder::decode(
			$result-&gt;getBody(),
			Zend_Json::TYPE_OBJECT
		);
		return $response;
	}
	public function getCoordinates($address)
	{
		$response = $this-&gt;_getGeocodedLatitudeAndLongitude($address);
		$return = array();
		if(isset($result-&gt;Placemark[0]-&gt;Point-&gt;coordinates[1])){
			$return(
			'lat' =&gt; $result-&gt;Placemark[0]-&gt;Point-&gt;coordinates[1];
			'lon' =&gt; $result-&gt;Placemark[0]-&gt;Point-&gt;coordinates[0];
			);
		}else{
			$return = null;
		}
		return $return;
	}
	private function getGeocodingUri()
	{
		return 'http://maps.google.com/maps/geo';
	}
}
?&gt;
</pre>
<h3>Usage</h3>
<p>Alright, that was pretty easy. Now we just have to implement this in our controller. Here is a sample model that uses the Geocoder class to return geotagged User objects.<br />
<strong>models/User.php</strong></p>
<pre class="brush: php;">
class User extends Zend_Db_Table_Abstract{
	protected $_name = 'users';
	protected $key;
	protected $geocoder;

	public function init()
	{
		$this-&gt;key = Zend_Registry::get('google')-&gt;google_map_key;
		$this-&gt;geocoder = new Geocoder($this-&gt;key);

	}
	public function getUsersAndGeocode()
	{
		$result = $this-&gt;fetchAll();

		$users    = $result-&gt;_toArray();
		foreach($users as $user)
		{
			$address = &quot;{$user['address']} {$user['city']} {$user['state']} {$user['zip']}&quot;;

			$latlon = $this-&gt;geocoder-&gt;getCoordinates($address);
			if($latlon)
			{
				$user['lat'] = $latlon['lat'];

				$user['lon'] = $latlon['lon'];
			}
		}
		return $users;
	}

}
?&gt;
</pre>
<p>The controller part is a little too easy. We will setup a reference to our user table and create a map action. Within the map action we get all of users and geocode them. We pass that collection to our view. This file should be located here:<br />
<strong>controllers/UserController.php</strong></p>
<pre class="brush: php;">
class UserController extends Zend_Controller_Action{
	protected $user_table;
	public function init()
	{
		//database connectivity stuff is up to you

		$this-&gt;user_table = new User();
	}
	public function mapAction()
	{

		$users = $this-&gt;user_table-&gt;getUsersAndGeocode();
		$this-&gt;view-&gt;users = $users;
	}
}
?&gt;
</pre>
<p>And finally, the view. Here we will create our map div, load the Google Maps API (don’t forget to sub out your key in the script src). We are using a custom marker here (personIcon); you can add your own image here by changing the path to your image. I recommend the image be pretty small with a transparent background. Given our current setup, this file would be located at this path:<br />
<strong>views/scripts/user/map.phtml</strong></p>
<pre class="brush: php;">
&lt;div id=&quot;map&quot;&gt;

&lt;noscript&gt;
&lt;center&gt;
&lt;strong&gt;To view the map feature, you need to have Javascript enabled. If you are unsure about how to turn Javascript support on, please&lt;/p&gt;
&lt;p&gt;read Google's instructions found here: &lt;a href=&quot;https://www.google.com/support/adsense/bin/answer.py?hl=en&amp;amp;answer=12654&quot; target=&quot;_blank&quot;&gt;LINK&lt;/a&gt;&lt;/strong&gt;

&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;&lt;/noscript&gt;
&lt;/div&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js&quot;&gt;&lt;/script&gt;

&lt;!--
&lt;script type=&quot;text/javascript&quot; src=&quot;http://maps.google.com/maps?file=api&amp;amp;amp;v=2&amp;amp;amp;sensor=false&amp;amp;amp;key=your_key&quot;&gt;&lt;/script&gt;
--&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
 //Sorry, I love jquery! If you don't use window.onload = function(){initialize();}
    $(document).ready(function(){
        initialize();

    });
var map;
var personIcon;
function initialize() {
    if(GBrowserIsCompatible){

        map = new google.maps.Map2(document.getElementById(&quot;thurtene_map&quot;));
        map.setUIToDefault();
        map.setCenter(new google.maps.LatLng('48.858001709', '2.29460000992'), 4);
        &lt;? endif; ?&gt;

        personIcon            = new GIcon();
  /**
  * Change this marker to be a small transparent custom image
  *
  */

        personIcon.image      = '/img/common/custom_marker.png';
        personIcon.shadow     = &quot;http://www.google.com/mapfiles/shadow50.png&quot;;
        personIcon.iconSize   = new GSize(32,32);
        personIcon.shadowSize = new GSize(37,34);

        personIcon.iconAnchor = new GPoint(9,34);
        personIcon.infoWindowAnchor = new GPoint(9,2);
    }
    addOverlays(map);
}

function personMarker(point, index, dto){
 //set our marker to be the custom icon we created
    markerOptions = {icon:personIcon};
    var marker = new GMarker(point, markerOptions);

/**
 * This is the content in the info bubble
 */
    GEvent.addListener(marker, 'click', function(){
       marker.openInfoWindowHtml(
            '&lt;h3&gt;&lt;a href=&quot;/profile/view/'+dto.user_id+'&quot;&gt;'+dto.user_first+' '+ dto.user_last+'&lt;/a&gt;&lt;/h3&gt;
'
            +dto.user_address+'

'
            +dto.user_city+'
'
            +dto.user_state+' '+dto.user_zip
        );

    });
    return marker;
}
/*
* Here is where we loop through our users and create new markers for each

*/
function addOverlays(map){
    &lt;?php
  $geo = $this-&gt;users-&gt;_toArray();
        $size = sizeof($geo);

 ?&gt;
    &lt;? for($i = 0; $i &lt; $size; $i++): ?&gt;
                var latLon = new GLatLng(&lt;?php echo $geo[$i]['lat'];?&gt;, &lt;?php echo $geo[$i]['lon'];?&gt;);

                map.addOverlay(personMarker(latLon, &lt;?=$i?&gt;, &lt;?=Zend_Json::encode($geo[$i])?&gt;));
    &lt;?php endfor; ?&gt;
}
&lt;/script&gt;
</pre>
<p>Post a comment if you have any questions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bitconsultants.net/2010/geocoding-with-google-maps-and-the-zend-framework/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Alternating Table Rows with PHP</title>
		<link>http://www.bitconsultants.net/2008/alternating-table-rows-with-php/</link>
		<comments>http://www.bitconsultants.net/2008/alternating-table-rows-with-php/#comments</comments>
		<pubDate>Tue, 09 Sep 2008 05:44:22 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.bitconsultants.net/?p=140</guid>
		<description><![CDATA[Using PHP and CSS, it&#8217;s very easy to create a report-style table with alternating colors on each row. This setup assumes a connection to a MySQL database (though any supported DBMS will work), and that you have already queried your database and are ready to...]]></description>
			<content:encoded><![CDATA[<p>Using <strong>PHP </strong>and <strong>CSS</strong>, it&#8217;s very easy to create a report-style table with alternating colors on each row. This setup assumes a connection to a MySQL database (though any supported DBMS will work), and that you have already queried your database and are ready to work with the results in your php code.</p>
<p>CSS</p>
<pre class="brush: css;">
.norm{
color:#fff;
background-color:#000;
}

.alt{
color:#000;
background-color:#fff;
}
</pre>
<p>PHP Code:</p>
<pre class="brush: php;">

&lt;?php

$style = 0;//switch to know which row we are on
echo '&lt;table&gt;';
while($row = mysql_fetch_array($query))
{
$name = $row['name'];//for each corresponding column name you wish to show
$add   =  $row['address'];
$email = $row['email'];

if($style == 0)
{
echo '&lt;tr class=&quot;norm&quot;&gt;';
echo '&lt;td&gt;'.$name.'&lt;/td&gt;';
echo '&lt;td&gt;'.$add.'&lt;/td&gt;';
echo '&lt;td&gt;'.$email.'&lt;/td&gt;';
echo '&lt;/tr&gt;';
$style++;
}else{
echo '&lt;tr class=&quot;alt&quot;&gt;';
echo '&lt;td&gt;'.$name.'&lt;/td&gt;';
echo '&lt;td&gt;'.$add.'&lt;/td&gt;';
echo '&lt;td&gt;'.$email.'&lt;/td&gt;';
echo '&lt;/tr&gt;';
$style--;
}
}
echo '&lt;/table&gt;';

?&gt;
</pre>
<p>That&#8217;s all, not much to it really.</p>
<p>Edit: It should be stated that this could be accomplished in a much more simple manner using the ternary operator to conditionally set the class, here is what that would look like:</p>
<pre class="brush: php;">

&lt;?php

$style = 'norm';//switch to know which row we are on
echo '&lt;table&gt;';
while($row = mysql_fetch_array($query))
{
$name = $row['name'];//for each corresponding column name you wish to show
$add   =  $row['address'];
$email = $row['email'];
echo '&lt;tr class=&quot;'.$style.'&quot;&gt; ';
echo '&lt;td&gt;'.$name.'&lt;/td&gt;';
echo '&lt;td&gt;'.$add.'&lt;/td&gt;';
echo '&lt;td&gt;'.$email.'&lt;/td&gt;';
echo '&lt;/tr&gt;';
$style = ($style == 'norm') ? 'alt' : 'norm';
}
echo '&lt;/table&gt;';

?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bitconsultants.net/2008/alternating-table-rows-with-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework on Apache 1.3.x</title>
		<link>http://www.bitconsultants.net/2000/zend-framework-on-apache-1-3-x/</link>
		<comments>http://www.bitconsultants.net/2000/zend-framework-on-apache-1-3-x/#comments</comments>
		<pubDate>Mon, 19 Jun 2000 18:34:06 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.bitconsultants.net/?p=279</guid>
		<description><![CDATA[If you are having problems with the .htaccess file for Zend Framework and getting 500 errors, and are running apache 1.3.x (like at GoDaddy), add a slash before index.php in the rewrite rule. Here is one of my htaccess files for reference &#60;IfModule mod_expires.c&#62; ExpiresActive...]]></description>
			<content:encoded><![CDATA[<p>If you are having problems with the .htaccess file for Zend Framework and getting 500 errors, and are running apache 1.3.x (like at GoDaddy), add a slash before index.php in the rewrite rule.</p>
<p>Here is one of my htaccess files for reference</p>
<pre class="brush: plain;">

&lt;IfModule mod_expires.c&gt;
 ExpiresActive On
 ExpiresByType text/html &quot;access plus 1 seconds&quot;
 ExpiresByType image/gif &quot;access plus 2 years&quot;
 ExpiresByType image/jpeg &quot;access plus 2 years&quot;
 ExpiresByType image/png &quot;access plus 2 years&quot;
 ExpiresByType text/css &quot;access plus 2 years&quot;
 ExpiresByType text/javascript &quot;access plus 30 minutes&quot;
 ExpiresByType application/x-javascript &quot;access plus 30 minutes&quot;
&lt;/IfModule&gt;

&lt;ifModule mod_gzip.c&gt;
 mod_gzip_on Yes
 mod_gzip_dechunk Yes
 mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$
 mod_gzip_item_include file clientside/css
 mod_gzip_item_include file clientside/javascript
 mod_gzip_item_include handler ^cgi-script$
 mod_gzip_item_include mime ^text/.*
 mod_gzip_item_include mime ^application/x-javascript.*
 mod_gzip_item_exclude mime ^image/.*
 mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
&lt;/ifModule&gt;

&lt;IfModule mod_deflate.so&gt;
 SetOutputFilter DEFLATE
 AddOutputFilterByType DEFLATE text/html text/css text/plain application/x-javascript text/javascript
 BrowserMatchSetOutputFilter DEFLATE ^Mozilla/4 gzip-only-text/html
 BrowserMatch ^Mozilla/4\.0[678] no-gzip
 BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
&lt;/IfModule&gt;

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bitconsultants.net/2000/zend-framework-on-apache-1-3-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
