<?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>Albert Fama &#187; PHP</title>
	<atom:link href="http://albertfama.com/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://albertfama.com</link>
	<description>Freelance Web Programmer - specializing in PHP &#38; MySQL</description>
	<lastBuildDate>Fri, 20 Nov 2009 16:06:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Display Errors</title>
		<link>http://albertfama.com/php/display-errors/</link>
		<comments>http://albertfama.com/php/display-errors/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 16:06:31 +0000</pubDate>
		<dc:creator>Albert Fama</dc:creator>
				<category><![CDATA[Content]]></category>
		<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://albertfama.com/?p=975</guid>
		<description><![CDATA[The display_errors directive in the PHP ini file &#8216;tells&#8217; PHP if errors should be added to the output stream (normally printed to the screen) or if they should not be displayed in the browser.
&#160;
&#60;IMPORTANT&#62;
It should be noted that this setting DOES NOT suppress the error. Even if the directive is set to &#8216;Off&#8217; (do not [...]]]></description>
			<content:encoded><![CDATA[<p>The display_errors directive in the PHP ini file &#8216;tells&#8217; PHP if errors should be added to the output stream (normally printed to the screen) or if they should not be displayed in the browser.<br />
<br />&nbsp;<br />
<strong>&lt;IMPORTANT&gt;</strong></p>
<p>It should be noted that this setting <strong>DOES NOT</strong> suppress the error. Even if the directive is set to &#8216;Off&#8217; (do not display errors) errors which occur in a script are still triggered and will be processed by the error handler.</p>
<p><strong>&lt;/IMPORTANT&gt;</strong><br />
<br />&nbsp;<br />
PHP does not offer a special display_errors function, but by using the <a href="http://us.php.net/manual/en/function.ini-set.php"  title="PHP Manual: ini_set()">ini_set()</a> function we can control the setting of this directive within our script. The function signature looks like this:</p>
<p>string ini_set  ( string $varname  , string $newvalue  )</p>
<p>blah, blah</p>

                            <div id="aspdf">
                                <a href="http://albertfama.com/wp-content/plugins/as-pdf/generate.php?post=975">
                                    <span>&nbsp;</span>
                                </a>
                            </div>
                        ]]></content:encoded>
			<wfw:commentRss>http://albertfama.com/php/display-errors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Error Reporting</title>
		<link>http://albertfama.com/php/error-reporting/</link>
		<comments>http://albertfama.com/php/error-reporting/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 20:30:44 +0000</pubDate>
		<dc:creator>Albert Fama</dc:creator>
				<category><![CDATA[Content]]></category>
		<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://albertfama.com/?p=924</guid>
		<description><![CDATA[PHP provides numerous error configuration options in the php.ini file. Since many people do not have the option of editing their ini file I would like to concentrate this series of posts on the ones which can be set within scripts (at run-time), more specifically ones you should consider using when creating a strategy for [...]]]></description>
			<content:encoded><![CDATA[<p>PHP provides numerous error configuration options in the php.ini file. Since many people do not have the option of editing their ini file I would like to concentrate this series of posts on the ones which can be set within scripts (at run-time), more specifically ones you should consider using when creating a strategy for handling errors. If you would like a complete list of the configuration options within PHP, the manual provides a very nice <a href="http://www.php.net/manual/en/errorfunc.configuration.php" title="PHP Manual: Errors and Logging Configuration Options" >chart</a>.</p>
<p>The configuration option I would like to address in this article is, of course, error_reporting.</p>
<p>Let&#8217;s start digging.</p>
<h4>error_reporting</h4>
<p>The error_reporting directive (within the PHP ini file) allows you to set the level of errors reported by PHP. By default this is set to &#8216;E_ALL &amp; ~E_NOTICE&#8217;. This <em>&#8216;tells&#8217;</em> PHP to report all errors, <em><strong>except</strong></em> Notices.</p>
<p>PHP provides a built-in function for getting and setting the error_reporting level: <a href="http://www.php.net/manual/en/function.error-reporting.php" title="PHP Manual: error_reporting()" >error_reporting()</a>. The function signature looks like this:</p>
<p><code>int error_reporting  ([ int $level  ] )</code></p>
<p>The function accepts one optional argument, a new error reporting level, and returns the old error reporting level. Although the signiture shows that the function accepts an integer, the new level sent can be represented by a <a href="http://www.php.net/manual/en/errorfunc.constants.php"  title="PHP Manual: Predefined Constants">predefined constant</a>. In fact it is recommended that you use the predefined constants to ensure future compatibility.</p>
<p>The available constants can be used in combination to build up a <a rel="nofollow" href="http://en.wikipedia.org/wiki/Bitmask"  title="Wikipedia: Bitmask">bitmask</a>; the bitmask <em>tells</em> PHP which errors to report and which to suppress. Since these constants are actually bitmasks, you will need to use <a href="http://www.php.net/manual/en/language.operators.bitwise.php"  title="PHP Manual: Bitwise Operators">bitwise operators</a> when combining them.</p>
<p>An example of the error reporting setting I use in development is:</p>
<pre name="code" class="php">
$old_setting = error_reporting(E_ALL | E_STRICT);
</pre>
<p>From the predefined constants chart the setting E_ALL equates to the integer 30719 and means:</p>
<blockquote><p>All errors and warnings, as supported, except of level E_STRICT in PHP < 6. </p></blockquote>
<p>From the predefined constants chart the setting E_STRICT equates to the integer 2048 and means:</p>
<blockquote><p>Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code. </p></blockquote>
<p>So basically, this tell PHP to report all errors, notices, and messages generated at the E_STRICT level.</p>
<p>Back to the code&#8230;</p>
<p>The variable $old_setting will now be set to: 6135, the default setting for error reporting (using the predefined constants again that would be: E_ALL &amp; ~E_NOTICE). </p>
<p>A small code example:</p>
<pre name="code" class="php">
&lt;?php
//get the current error reporting setting
$current_setting = error_reporting();

//check if error reporting is set to E_ALL | E_STRICT
if (8191 != $current_setting) {
    //not set to E_ALL | E_STRICT make it so
    error_reporting(E_ALL | E_STRICT);
}

//display new error reporting setting

echo error_reporting(); //displays 8191
?>
</pre>
<p>A more useful example would be to change the error_reporting setting based on the environment the script is being run in. </p>
<p>Let&#8217;s say you have a configuration file which defines the constant &#8216;ENV&#8217;, this can be set to &#8216;production&#8217; (live site) or &#8216;development&#8217;. If the script is run in production then we want to use &#8216;E_ALL &amp; ~E_NOTICE&#8217; (default), but when running in development we want to use E_ALL | E_STRICT.</p>
<p>config.php:</p>
<pre name="code" class="php">
&lt;?php

//define enviroment
define('ENV', 'development');
</pre>
<p>Script File:</p>
<pre name="code" class="php">
&lt;?php

//load configuration file
require_once('config.php');

//check ENV constant to see if running in development
if ('development' == ENV) {
    //running in development so change default setting
    error_reporting(E_ALL | E_STRICT);
    //now all errors, notices, and suggestions will be reported
}
</pre>
<p>That&#8217;s it! I&#8217;m sure you can see how useful this function can be.</p>
<blockquote><p><strong>Side Note:</strong> If you are unsure what a bitmask is or are unfamiliar with bitwise operators, you may want to checkout this <a href="http://www.joestump.net/2004/06/a-quick-bitmask-howto-for-programmers.html"  title="joestump.net: A Quick Bitmask HOWTO for Programmers">post</a> from <a href="http://www.joestump.net/"  title="joestump.net">joestump.net</a>.</p></blockquote>
</blockquote>

                            <div id="aspdf">
                                <a href="http://albertfama.com/wp-content/plugins/as-pdf/generate.php?post=924">
                                    <span>&nbsp;</span>
                                </a>
                            </div>
                        ]]></content:encoded>
			<wfw:commentRss>http://albertfama.com/php/error-reporting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A New Start: Error Reporting</title>
		<link>http://albertfama.com/php/new-start-error-reporting/</link>
		<comments>http://albertfama.com/php/new-start-error-reporting/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 17:35:12 +0000</pubDate>
		<dc:creator>Albert Fama</dc:creator>
				<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://obnexus.net/?p=34</guid>
		<description><![CDATA[A few years back I had written a post about deciphering error messages, which still remains popular today. Because of the continued interest I have decided to update the original post and create a series on error reporting and handling in PHP.
When I first started learning about errors and error handling I found numerous tutorials [...]]]></description>
			<content:encoded><![CDATA[<p>A few years back I had written a post about deciphering error messages, which still remains popular today. Because of the continued interest I have decided to update the original post and create a series on error reporting and handling in PHP.</p>
<p>When I first started learning about errors and error handling I found numerous tutorials on the topic, but none that provided a complete resource on the subject. This is understandable; since the topic is so broad one tutorial would not only be extremely long, it might also seem overwhelming to someone who just started learning about the topic. This is also the reason it would make a great topic to cover on a blog, where a series of posts can be created, each building on the information presented in the previous post ending with a comprehensive  resource. (OK, comprehensive maybe a little strong but hopefully it will be close.)</p>
<p>The intended outline for the series is:</p>
<h5>Resource Information</h5>
<ul>
<li><a title="Errors and Error Messages Deciphered " href="/php/errors-and-error-messages-deciphered/">Error Messages Deciphered (Revised)</a></li>
<li><a title="Error Reporting" href="/php/error-reporting/">Error Reporting</a></li>
<li>Displaying Errors</li>
<li>Error Logging</li>
<li>Backtrace Functions</li>
<li>Triggering Errors
  </li>
<li>Understanding Exceptions</li>
</ul>
<h5>Implementation</h5>
<ul>
<li>Creating A Custom Error Handler</li>
<li>Utilizing Exceptions</li>
<li>Creating an Exception Hierarchy</li>
</ul>
<h5>Putting it all together</h5>
<ul>
<li>Error Handling Strategies</li>
</ul>

                            <div id="aspdf">
                                <a href="http://albertfama.com/wp-content/plugins/as-pdf/generate.php?post=34">
                                    <span>&nbsp;</span>
                                </a>
                            </div>
                        ]]></content:encoded>
			<wfw:commentRss>http://albertfama.com/php/new-start-error-reporting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter API Fun</title>
		<link>http://albertfama.com/php/twitter-api-fun/</link>
		<comments>http://albertfama.com/php/twitter-api-fun/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 16:27:49 +0000</pubDate>
		<dc:creator>Albert Fama</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://albertfama.com/?p=787</guid>
		<description><![CDATA[The other day I was looking through the twitter API docs trying to get inspiration for a side project. I was thinking about creating my own twitter library for PHP, but I wanted to do something quick and dirty, just to get my feet wet, and to see how others have implemented the API in [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I was looking through the <a href="http://apiwiki.twitter.com/"  title="twitter API documentation">twitter API docs</a> trying to get inspiration for a side project. I was thinking about creating my own twitter library for PHP, but I wanted to do something <a rel="nofollow" href="http://idioms.thefreedictionary.com/quick+and+dirty"  title="Idiom: quick and dirty">quick and dirty</a>, just to <a rel="nofollow" href="http://idioms.thefreedictionary.com/get+feet+wet"  title="Idiom: get ones feet wet">get my feet wet</a>, and to see how others have implemented the API in PHP.</p>
<p>If your using <a href="http://twitter.com/"  title="Twitter">twitter</a> and are reading this blog I&#8217;m sure you are aware of <a href="http://twitter.com/hashphp"  title="PHP feed on twitter">hashphp</a>. If not, it is a twitter account which grabs most of the <a rel="nofollow" href="http://webtrends.about.com/od/glossary/g/what-is-a-tweet.htm"  title="about.com: What is a tweet">tweets</a> with the <a href="http://www.searchenginejournal.com/twitter-hashtags/9419/"  title="searchenginejournal.com:Ultimate Guide to Twitter Hashtags">hashtag</a> &#8216;#php&#8217;  and <a rel="nofollow" href="http://www.squidoo.com/retweeting"  title="squidoo: Retweeting explained">re-tweets</a> the messages. Since this seemed like a fairly simple thing to do I decided to create my own twitter feeder. Again, I was just hacking together a script, so if you use the code presented you will want to make some enhancements before letting it into the wild. (Please see <a href="#enhancements">end</a> of post.)</p>
<p>First, I decided to pick a hastag which was used in the range of 3 &#8211; 5 times every 15 minutes; &#8216;#mysql&#8217; seemed to fit the bill. </p>
<p>Now I needed a twitter account to re-tweet the messages, and a bit.ly account to create short URLs to link back to the original account that posted the message. I created a &#8216;poundmysql&#8217; account (The number sign &#8216;#&#8217; is sometimes referred to as the &#8216;pound&#8217; sign in the US), then I went to bit.ly and signed up for an account.</p>
<p>Continuing to gather the pieces of the puzzle, I looked through the published <a href="http://apiwiki.twitter.com/Libraries#PHP"  title="twitter API documentation: pre-written PHP libraries">PHP libraries</a> on twitter and found one which did exactly what I needed. There were other more robust scripts, but I only needed to update an account status so grabbed the package <a href="http://www.phpclasses.org/browse/package/4216.html"  title="phpclasses.org: Twitter">Twitter</a> by <a href="http://www.phpclasses.org/browse/author/385729.html"  title="phpclasses.org: Felix Oghina profile page">Felix Oghina</a>. The next piece came in the way of the <a rel="nofollow" href="http://code.google.com/p/bitly/" >Bitly</a> class, written by <a href="http://ruslanas.com"  title="Ruslanas Balciunas personal site">Ruslanas Balciunas</a>. (I apologize to Ruslanas Balciunas but my current character set in MySQL will not allow for a proper spelling of the last name.)</p>
<p>Next, I needed to be able to retrieve all the tweets which contained the string #mysql. Twitter offers a <a href="http://apiwiki.twitter.com/Twitter-API-Documentation"  title="twitter.com: API documentation">Search API</a> which would do the job, but for my purposes <a href="http://search.twitter.com/"  title="search twitter">search.twitter</a> was the faster option. They offer an XML  feed to any search so I only needed to search #mysql and grab the URL of the feed, which is:</p>
<p>http://search.twitter.com/search.atom?q=%23mysql</p>
<p>As you can see the search term is contained in the query string of the URL (URL encoded), which is useful since I could then setup the script to accept any search term.</p>
<p>OK, now with all the pieces of the puzzle at hand I only needed to write the code to fit the pieces together creating my own twitter feeder.</p>
<p>First I grabbed a function which I used in a long ago project [probably also swiped from the internet:)]. The function sends a HTTP request to a server and returns the response.</p>
<pre name="code" class="php">
function url_get($domain, $uri, $referer='')
{
    $header = array();
    $header[] = 'GET '.$uri.' HTTP/1.1';
    $header[] = 'Host: '.$domain;
    $header[] = 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US;rv:1.8) Gecko/20051111 Firefox/1.5';
    $header[] = 'Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
    $header[] = 'Accept-Language: en-us,en;q=0.5';
    $header[] = 'Accept-Encoding: gzip,deflate';
    $header[] = 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7';

    $header[] = 'Keep-Alive: 300';
    $header[] = 'Connection: keep-alive';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $domain.$uri);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_ENCODING, "");
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_REFERER, $referer);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

    $result['exec'] = curl_exec ($ch);
    $result['info'] = curl_getinfo($ch);

    curl_close ($ch);

    return $result['exec'];
}
</pre>
<p>As you can see the function accepts three parameters, the domain to connect to ($domain), the path to the requested page ($uri) and the referrer ($referer). This function uses the cURL extension, if your PHP configuration has allow_url_fopen turned on you don&#8217;t even need this function (more on that in a minute).</p>
<p>Next I setup the $domain, $uri and $search_term variables, and made the call to the function to get the XML from search.twitter.</p>
<pre name="code" class="php">

//ideally you would put this in a configuration file
$search_term = '#mysql';

//create variables to be sent to the function
$domain = 'search.twitter.com';
$uri    = '/search.atom?q='.urlencode($search_term);

//retrieve the xml response string from search.twitter
$feed = url_get($domain, $uri);
&nbsp;
</pre>
<p>Now that the script has the information needed from twitter as an xml string, I can then create a <a href="http://www.php.net/manual/en/book.simplexml.php"  title="PHP Manual: SimpleXML extension">SimpleXML</a> object using the following:</p>
<pre name="code" class="php">

$xml = new SimpleXMLElement($feed);
</pre>
<p>If allow_url_fopen is set to &#8216;on&#8217; you could skip directly to creating the SimpleXML object by using the URL as the first parameter and setting the third parameter to TRUE:</p>
<pre name="code" class="php">

$feed = 'http://search.twitter.com/search.atom?q='.urlencode($search_term);

$xml = new SimpleXMLElement($feed, NULL, TRUE);
</pre>
<p>The tweets in the feed are ordered by the time they were originally posted using the UTC timezone, since this is the case I needed PHP to use UTC when calling date time functions. To do this I used the <a href="http://us3.php.net/manual/en/function.date-default-timezone-set.php"  title="date_default_timezone_set">date_default_timezone_set</a> function.</p>
<pre name="code" class="php">

date_default_timezone_set('UTC');
</pre>
<p>Next I included the Twitter class and the Bitly class into the script and created new instances of each:</p>
<pre name="code" class="php">

//require the two files which define the classes used
require_once('Twitter.class.php');
require_once('bitly.class.php');

//setup log in information for twitter and bit.ly
//again these should really be kept in a separate config file
//outside the document root
$twit_uname = 'twitter_username';
$twit_pword = 'twitter_password';

$bit_uname = 'bit.ly_username';
$bit_api   = 'bit.ly_api_key';

//instantiate new objects
$twitter = new Twitter($twit_uname, $twit_pword);
$bitly   = new Bitly($bit_uname, $bit_api);
</pre>
<p>The idea is to loop through the messages received from the search and update the twitter account with any message that was posted within the last 15 minutes. I setup the last run time of the script outside the loop so that it only needs to be calculated once.</p>
<pre name="code" class="php">
//define the number of minutes between each script run
//again this is a setting which should be in the config file
$time_interval = 15;

//get the number of seconds since the UNIX epoch
//and the last script run
$last_run_time = mktime()-($time_interval*60);
</pre>
<p>The messages can be found in $xml->entry. Within the loop the first check I needed to make was to determine if the twitter feeder account (poundmysql) had posted the message and if so, skip that message.</p>
<pre name="code" class="php">

//setup messages loop
foreach ($xml->entry as $update) {
    //skip any messages set by poundmysql
    if ('poundmysql' == $update->author->name) {
        continue;
    }
...
</pre>
<p>Next I checked for the time the message was posted and if that time occurs later than 15 minutes ago, I could end the loop and the script itself, since any entries after this would also occur after the 15 minute cutoff point.</p>
<pre name="code" class="php">
...
    //time format in xml string: 2009-07-25T20:32:13Z
    //split time from date
    list($pub_date, $pub_time) = explode('T', $update->published);
    //remove the ending 'Z' from time
    $pub_time = substr($pub_time, 0, -1);

    //get time segments for mktime() call
    list($hour, $minute, $second) = explode(':', $pub_time);
    list($year, $month, $day)     = explode('-', $pub_date);

    //get the number of seconds since the UNIX epoch
    //and the time the message was posted
    $publish_time  = mktime($hour,  $minute, $second,
                            $month, $day,    $year);

    //check if message was later than last run time,
    //if so end loop
    if ($publish_time < $last_run_time) {
        break;
    }
</pre>
<p>If the message passes these two checks, I know that it will be used in the feeder. </p>
<p>I then create a bit.ly link for the original message ($update->link[0]['href']), and store the character length of the link. Then I grab the content of the message ($update->title) and store that character length.
</pre>
<pre name="code" class="php">
    //grab url of the original message, create short link, store length
    $link       = (string)$update->link[0]['href'];
    $short_link = ' ..'.$bitly->shortenSingle($link);
    $short_len  = strlen($short_link);

    //grab tweet content store length
    $content     = (string)$update->title;
    $content_len = strlen($content);
</pre>
<p>Since Twitter has a max character length of 140, I then needed to check what the character length of the new message was with the bit.ly link added, if it was longer than 140, I then needed to cutoff a section of the original message to accommodate the 140 maximum length.</p>
<pre name="code" class="php">

    //total message length
    $len_total = $short_len+$content_len;

    if (140 < $len_total) {
        //determine how many characters over 140
        $over = $len_total-140;

        //remove that many characters from the original message
        $content = substr($content, 0, -$over);
    }
</pre>
<p>The only thing left to do was to actually update the twitter status.</p>
</pre>
<pre name="code" class="php">

    $new_status = $content.$short_link;
    //update twitter status
    $twitter->update($new_status);
}
//end loop
</pre>
<p>That ends the PHP code for my twitter feeder, now I setup a cron job to run every fifteen minutes and I have my own twitter feeder feeding the MySQL community.</p>
<div style="background-color: #EEEEEE; padding: 7px;">
*/15 * * * * GET /path/to/script
</div>
<p>Since I didn&#8217;t want to actually monitor this feed, I let it run for awhile and once I verified everything was working correctly I deleted the twitter account and stopped the script from running.</p>
<p>A copy of the code used in this post can be found <a href="#" onclick="window.open('/scripts/twitter-feeder.txt', 'code', 'height=500,width=600,scrollbars=1'); return false;" title="code used for twitter feeder">here</a>.<br />
<a name="enhancements"></a></p>
<h5>Enhancements</h5>
<p>Some updates you will probably want to make before actually using this script for a real twitter account:</p>
<ul>
<li>Remove all the configuration options to their own file and store outside the document root.</li>
<li>Error checking for unavailable third-party services</li>
<li>Reverse tweets before running the loop. ATM: the script re-tweets in the reverse order the original messages were posted.</li>
<li>Implement a filtering system so no unwanted messages are inserted into your stream.</li>
<li>Update the script to use the twitter search API to guarantee that all tweets with your hashtag are captured.</li>
</ul>

                            <div id="aspdf">
                                <a href="http://albertfama.com/wp-content/plugins/as-pdf/generate.php?post=787">
                                    <span>&nbsp;</span>
                                </a>
                            </div>
                        ]]></content:encoded>
			<wfw:commentRss>http://albertfama.com/php/twitter-api-fun/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Tutorial: Integrating FUDforum</title>
		<link>http://albertfama.com/php/new-tutorial-integrating-fudforum/</link>
		<comments>http://albertfama.com/php/new-tutorial-integrating-fudforum/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 00:35:34 +0000</pubDate>
		<dc:creator>Albert Fama</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Fudforum]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[learning]]></category>

		<guid isPermaLink="false">http://albertfama.com/?p=367</guid>
		<description><![CDATA[I have recently published the first part in a new series of tutorials which will look at integrating FUDforum into an existing site. Part 1 looks at how to create FUD accounts for existing users, and how to &#8216;notify&#8217; FUD about things happening on your site. Basically introducing your site to FUD.
Back Story
It seems forums [...]]]></description>
			<content:encoded><![CDATA[<p>I have recently published the first part in a new series of tutorials which will look at integrating <a href="http://fudforum.org/forum/"  title="FUDforum">FUDforum</a> into an existing site. Part 1 looks at how to create FUD accounts for existing users, and how to &#8216;notify&#8217; FUD about things happening on your site. Basically introducing your site to FUD.</p>
<h3>Back Story</h3>
<p>It seems forums have sort of lost their luster for many; I remember when having a website meant having a forum. At that time it seemed every contract I landed, some portion of the job consisted of integrating a forum  into a site. I always hated this job, because at the time PHPBB was the forum of choice and it seemed that there was no &#8216;right&#8217; way to do it, I had simply developed a bunch of hacks which needed to be scattered around the PHPBB code base and even when complete it was still just a bunch of hacks.</p>
<p>As time moved on, the demand for forums became less and less and I had not done a forum integration in many years. That was until I went to my <a href="http://www.azphp.org/"  title="Arizona PHP User's Group">local</a> <a href="http://www.phpusergroups.org/"  title="phpusergroups.org">PHP users group</a> and ended up with a contract to do a forum integration. I really was not looking forward to the project, but it was a part of a larger job and I&#8217;m not one to turn down work.</p>
<p>Luckily the other members of the group convinced the client to use <a href="http://fudforum.org/forum/"  title="FUDforum">FUDforum</a> developed by <a href="http://ilia.ws/"  title="Ilia Alshanetsky: Personal Site/Blog">Ilia Alshanetsky</a>. I had looked into FUDforum before, had used it as a member of different sites, and assumed the code to be a higher quality simply because of who wrote it, but had never written any code to interact with it.</p>
<p>On Wednesday, the night before I was to do the forum integration I began reading the <a href="http://cvs.prohost.org/index.php/Main_Page"  title="FUDforum documentation">documentation</a> and planning how I was going to accomplish this task as easily and painlessly as possible. Looking at the sidebar navigation on the documentation wiki, I was surprised to see the heading &#8216;<a href="http://cvs.prohost.org/index.php/Category:Integration"  title="FUDforum: Integration Documentation">Integration</a>&#8216; two clicks later, a quick scan of two different pages, and I knew exactly what needed to be done. </p>
<p>After a few hours of work Thursday morning I had written a script which created accounts in the forums for existing members, I also altered the sign up, login, and logout code of the main site. With these changes the forums were basically integrated into the site, which brings me to the new tutorial series I will be posting over the next week.</p>
<h3>Integrating FUDforum</h3>
<p><strong><a href="/tutorial-integrating-fudforum-part1" title="FUDforum integration - part 1">Part 1: Introducing your site to FUD</a></strong></p>

                            <div id="aspdf">
                                <a href="http://albertfama.com/wp-content/plugins/as-pdf/generate.php?post=367">
                                    <span>&nbsp;</span>
                                </a>
                            </div>
                        ]]></content:encoded>
			<wfw:commentRss>http://albertfama.com/php/new-tutorial-integrating-fudforum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting started with Dojo (part 1)</title>
		<link>http://albertfama.com/php/getting-started-with-dojo-part-1/</link>
		<comments>http://albertfama.com/php/getting-started-with-dojo-part-1/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 02:52:41 +0000</pubDate>
		<dc:creator>Albert Fama</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Content]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Dojo]]></category>
		<category><![CDATA[project]]></category>

		<guid isPermaLink="false">http://albertfama.com/?p=304</guid>
		<description><![CDATA[During this past weekend I was contacted by a client asking if I could implement a few new functionality requests on their site. Basically they wanted to slowly enter the world of Web 2.0, by implementing small tweaks to existing functionality. 
I have been working with this client of a few years now and have [...]]]></description>
			<content:encoded><![CDATA[<p>During this past weekend I was contacted by a client asking if I could implement a few new functionality requests on their site. Basically they wanted to slowly enter the world of Web 2.0, by implementing small tweaks to existing functionality. </p>
<p>I have been working with this client of a few years now and have a great rapport with them. For this most recent project they have no requirements about which JavaScript library to use just as long as it has the functionality which is required by the project. This left me in a little bit of a dilemma, which JavaScript library should I use?</p>
<p>I have tried many libraries in the past and had used the <a rel="nofollow" href="http://developer.yahoo.com/yui/"  title="Yahoo! User Interface Library">Yahoo! User Interface Library (YUI)</a> extensively for a previous project. Although it&#8217;s a good library I have had the urge to try out <a href="http://dojotoolkit.com"  title="Dojo: the JavaScript toolkit">Dojo</a>. I first learned about the library when it came coupled with the <a href="http://zendframework.com/"  title="Zend Framework">Zend Framework</a>. After a few small personal projects I never really used either again.</p>
<p>Doing a little research on <a href="http://dojotoolkit.com"  title="Dojo: the JavaScript toolkit">Dojo</a>&#8217;s current capabilities and verifying that it has the functionality required for my project, I have decided to use Dojo and document my experience here. I&#8217;m hoping that even if you currently use a different JavaScript library that this set of posts will inspire you to try something new for a change.</p>
<p>My first task will be to build something similar to the &#8216;Suggest&#8217; functionality on Google. This afternoon I attempted to find a good tutorial explaining how this is accomplished in Dojo, but could not locate exactly what I wanted. The problem seems to be that all the combo box / auto complete tutorials for dojo create a select menu rather than a simple text box and since this is going to be implemented for a search engine the select menu option is not actually an option. (Get it &#8217;select menu&#8217;, &#8216;option&#8217;&#8230;programming humor my wife loves it.)</p>
<p>Over the next few days I will be working on this project and will have one or two more posts detailing how I implement the functionality. If anyone has not heard of Dojo or has never used it here are a few links to get you started.</p>
<h4>Dojo Links</h4>
<ul>
<li><a href="http://dojotoolkit.com"  title="Dojo: the JavaScript toolkit">Homepage</a></li>
<li><a href="http://dojotoolkit.org/downloads"  title="Dojo: Download">Download</a></li>
<li><a href="http://dojotoolkit.org/docs"  title="Dojo: Documentation">Documentation</a></li>
<li><a href="http://dojotoolkit.org/book/dojo-book-0-9/hello-world-tutorial"  title="Dojo: Hello World Tutorial">Hello World Tutorial</a></li>
</ul>
<p>My next post will assume you already have Dojo <em>installed</em> and have worked through the &#8216;Hello World&#8217; tutorial. Here are some brief notes about installing Dojo.</p>
<h5>Dojo Installation</h5>
<p>When installing Dojo you have three options</p>
<ul>
<li>Load the toolkit directly from <a rel="nofollow" href="http://dev.aol.com/dojo"  title="AOL CDN: Dojo Toolkit">AOL&#8217;s Content Distribution Network </a>(CDN) or from the <a rel="nofollow" href="http://code.google.com/apis/ajaxlibs/documentation/index.html#dojo"  title="Google CDN: Dojo Toolkit">CDN of Google</a>.</li>
<li>Download and store the toolkit on your server</li>
<li>Checkout a copy from the SVN repository (maybe not the greatest idea if your implementing on a live site)</li>
</ul>
<p>I believe the first two options are completely viable for a live website and each have their pros and cons. I choose to download the toolkit and keep it on my server. The upside is that since I have the files locally I can open them up and browse through the code whenever I would like (you can learn a lot this way).</p>
<p>&nbsp;</p>
<blockquote><p><strong>In my opinion&#8230;</strong></p>
<p>When attempting to update an existing site with the newest gadgets available, it is best to take slowly. Implement a few updates at a time, without forcing the users to change the way they use the site. The response received from the users will tell you what is worth it and when you&#8217;ve gone too far.</p></blockquote>

                            <div id="aspdf">
                                <a href="http://albertfama.com/wp-content/plugins/as-pdf/generate.php?post=304">
                                    <span>&nbsp;</span>
                                </a>
                            </div>
                        ]]></content:encoded>
			<wfw:commentRss>http://albertfama.com/php/getting-started-with-dojo-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NOTICES mean something</title>
		<link>http://albertfama.com/php/notices-mean-something/</link>
		<comments>http://albertfama.com/php/notices-mean-something/#comments</comments>
		<pubDate>Wed, 17 Jun 2009 06:34:36 +0000</pubDate>
		<dc:creator>Albert Fama</dc:creator>
				<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[environment]]></category>
		<category><![CDATA[error messages]]></category>
		<category><![CDATA[errors]]></category>
		<category><![CDATA[learning]]></category>

		<guid isPermaLink="false">http://albertfama.com/?p=264</guid>
		<description><![CDATA[In numerous books and articles the general consensus seems to be that for a production environment Errors and Warnings should be turned on and Notices  turned off; as opposed to the development environment where error reporting should be set to E_ALL (report all errors). The reasoning behind this is, Errors and Warnings mean something [...]]]></description>
			<content:encoded><![CDATA[<p>In numerous books and articles the general consensus seems to be that for a production environment Errors and Warnings should be turned <strong>on</strong> and <a href="/php/errors-and-error-messages-deciphered/#notice">Notices</a>  turned <strong>off</strong>; as opposed to the development environment where error reporting should be set to E_ALL (report all errors). The reasoning behind this is, Errors and Warnings mean something serious has gone wrong with the script and you (as the developer) need to know about it. Notices on the other hand are kind of disregarded as a nuisance in production.</p>
<p>I completely disagree with this point of view. If I write code which is not intended to generate Notices, then as the developer I want to know if and when Notices are being generated in <strong>any</strong> environment.</p>
<p>Notices are very helpful in tracking down logical errors or bugs, which cause the script not to function as expected.  In PHP they are normally generated when using a previously undeclared variable. Technically speaking there is nothing wrong with this in PHP, other programming languages are not so forgiving. </p>
<p>I personally started declaring all variables when I began to focus on the security implications of using undeclared variables (we&#8217;ll save that information for another post). After getting in the habit I found that I was able find logical errors during development even before I noticed that a bug existed. After realizing this, I now never release code which is know to generate notices. I have also started setting error reporting to E_ALL in <strong>all</strong> environments.</p>
<p>I understand that this is not feasible for everyone. It may not be possible in a professional working environment because of dealing with legacy code. Another issue could arise if you use third-party code which has not subscribed to this way of thinking. Although personally, I feel this is not an excuse there is no reason you can&#8217;t get in there and &#8216;fix&#8217; their script.  </p>
<h5>A word of warning</h5>
<p>I was once hired to fix numerous bugs on a site, all were a fairly obvious fix, but one in particular had me stumped.  I turned on notices when attempting to debug the problem and ended up with an error log that contained over 250 notices for every page load. Since this was a dev environment setup by the client for my use, it was no big deal, but if it were a heavily trafficked live site, there could have been some serious implications.</p>

                            <div id="aspdf">
                                <a href="http://albertfama.com/wp-content/plugins/as-pdf/generate.php?post=264">
                                    <span>&nbsp;</span>
                                </a>
                            </div>
                        ]]></content:encoded>
			<wfw:commentRss>http://albertfama.com/php/notices-mean-something/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trick: Image Uploads</title>
		<link>http://albertfama.com/php/trick-image-uploads/</link>
		<comments>http://albertfama.com/php/trick-image-uploads/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 22:40:18 +0000</pubDate>
		<dc:creator>Albert Fama</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[file upload]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[validation trick]]></category>

		<guid isPermaLink="false">http://obnexus.net/?p=43</guid>
		<description><![CDATA[We have all written scripts to upload files to a server, and for one reason or another I find that most of the time the script is intended for image uploads. Whenever you are uploading user files to the server it is very important that those files are validated to ensure the uploaded file is [...]]]></description>
			<content:encoded><![CDATA[<p>We have all written scripts to upload files to a server, and for one reason or another I find that most of the time the script is intended for image uploads. Whenever you are uploading user files to the server it is very important that those files are validated to ensure the uploaded file is actually what is expected. Since just checking the HTTP headers and the file&#8217;s extensions is insufficient we need to find another way to determine if the file is actually an image file.</p>
<p>While writing some validation code I came across this &#8220;trick&#8221; which can be used to determine if a file is an image file: Send the uploaded file through <a href="http://www.php.net/manual/en/function.getimagesize.php"  title="PHP Manual: getimagesize">getimagesize()</a> and check the return values. </p>
<p>As the PHP Manual states:</p>
<blockquote><p><strong>PHP Manual</strong></p>
<p>The getimagesize() function will determine the size of any given image file and return the dimensions along with the file type and a height/width text string to be used inside a normal HTML IMG tag and the correspondant HTTP content type.</p></blockquote>
<p>If PHP cannot access the file or the file is not an image, the function will generate an E_WARNING error, and return boolean FALSE. The E_WARNING error can be suppressed by using the error suppression operator &#8216;@&#8217;. As long as you know that the file is accessible to PHP (which it should be if PHP uploaded the file) and the function does not return FALSE, then you have a valid image file.</p>
<p>I first leaned about this method from the book <a rel="nofollow" href="http://www.amazon.com/php-architects-Guide-PHP-Security/dp/0973862106/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1197585311&#038;sr=1-1"  title="Amazon: php|architect's Guide to PHP Security">php|architect&#8217;s Guide to PHP Security</a> by <a href="http://ilia.ws/"  title="Personal Website: Ilia Alshanetsky">Ilia Alshanetsky</a>.</p>

                            <div id="aspdf">
                                <a href="http://albertfama.com/wp-content/plugins/as-pdf/generate.php?post=43">
                                    <span>&nbsp;</span>
                                </a>
                            </div>
                        ]]></content:encoded>
			<wfw:commentRss>http://albertfama.com/php/trick-image-uploads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Manual gets facelift</title>
		<link>http://albertfama.com/php/php-manual-gets-facelift/</link>
		<comments>http://albertfama.com/php/php-manual-gets-facelift/#comments</comments>
		<pubDate>Thu, 29 Nov 2007 22:22:45 +0000</pubDate>
		<dc:creator>Albert Fama</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[manual]]></category>

		<guid isPermaLink="false">http://obnexus.net/?p=42</guid>
		<description><![CDATA[Several weeks ago an announcement was made on php.net that the new documentation build system was ready for testing. The announcement encourages everyone to use and test the new system. I should have started using it then, just to help out and find bugs, but I glanced over the new manual and didn&#8217;t really give [...]]]></description>
			<content:encoded><![CDATA[<p>Several weeks ago an announcement was made on php.net that the <a href="http://php.net#2007-10-03-1"  title="php.net: Announcement">new documentation build system was ready for testing</a>. The announcement encourages everyone to use and test the new system. I should have started using it then, just to help out and find bugs, but I glanced over the new manual and didn&#8217;t really give it much thought. In the last several days I noticed that the php.net manual display had changed, which reminded me about the new manual, and have since switched. The new manual is located at: <a href="http://docs.php.net/manual/"  title="New PHP Manual">http://docs.php.net/manual/</a> (still in test).</p>
<p>First I would like to say that I like the look of the new manual; it seems cleaner with well defined areas. For example on a function description page the description, parameters, return values, errors/exceptions, and examples all appear in their own &#8216;box&#8217; (div tag) with a light blue background. This definitely makes it easier to locate what your look for and generally gives a nice presentation of the information.</p>
<p>My two gripes about the new manual are fairly petty. I think it is a case of &#8216;<a rel="nofollow" href="http://en.wikipedia.org/wiki/Who_Moved_My_Cheese%3F"  title="Wikipedia: Who Moved My Cheese?">Who moved my cheese</a>&#8216;, instead of actual issues with the manual.</p>
<p><strong>Gripe 1: There is too much spacing between items in the unordered lists.</strong></p>
<p>Looking at what I believe to be the CSS styling for the &#8216;li&#8217; tags, they have added a top and bottom padding of 3 pixels (6 pixels between each line). Although this makes for good separation between each item it also makes the pages longer and consequently more scrolling.</p>
<p><strong>Gripe 2: The new navigation system, specifically in two areas:</strong></p>
<ul>
<li>The index page of the manual. The <a href="http://www.php.net/manual/en/"  title="PHP Manual: index">old index page</a>, was basically like an extended table of contents. It listed the sections of the manual along with the major subsections. This was always my starting point. You may not find exactly what your looking for in the first click but you knew where you wanted to go. The <a href="http://docs.php.net/manual/en/manual.php"  title="New PHP Manual: index">new index page</a>, contains the list of sections in the left-hand navigation bar, but the page does not list any subsections. New users of the language I believe will find it more difficult to locate the information they need simply because they may not know exactly what their looking for. Now, of course, users already familiar with the language will still be able to find what there looking for but it will take more clicks to get where your going, specifically for the function reference section&#8230;</li>
<li>In the old manual when you viewed the <a href="http://www.php.net/manual/en/funcref.php"  title="Old PHP Manual: Function Reference">function reference</a> section you were presented with a long alphabetized list of groups of functions; Arrays, MySQL, Strings, etc. <a href="http://docs.php.net/manual/en/funcref.php"  title="New PHP Manual: Function Reference">Now</a> they have grouped the groups; array functions are listed below &#8216;Variable and Type Related Extensions&#8217;, string functions are listed below &#8216;Text Processing&#8217; and MySQL functions aren&#8217;t actually listed on the page, they are under &#8216;Database Extensions->Vendor Specific Database Extensions->MySQL&#8217;. Now I am all for more organization, but by grouping the groups the function reference is no longer alphabetized and the added clicks needed to get to the section you want I feel is not a bonus.</li>
<li style="list-style-type: none;">This also comes into play after you have chosen the section you want. For example, in the old manual you could be looking at the array functions, find what you need, and just leave the browser open to the array functions page while you went back to work. Then after a bit more work, if you needed to look at the string functions, you could simply click the &#8217;string&#8217; functions link in navigation bar and be there in one click. This is not possible in the new manual&#8230;Given the same situation you always need to go back to the main function reference page and start drilling down from there.</li>
</ul>
<p>I don&#8217;t want this to come off as a bashing of the new manual, these are minor issues and I probably just need to get used to the new setup. So now that you read my review, let us know what you think of the new manual.</p>

                            <div id="aspdf">
                                <a href="http://albertfama.com/wp-content/plugins/as-pdf/generate.php?post=42">
                                    <span>&nbsp;</span>
                                </a>
                            </div>
                        ]]></content:encoded>
			<wfw:commentRss>http://albertfama.com/php/php-manual-gets-facelift/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learning PHP</title>
		<link>http://albertfama.com/php/learning-php/</link>
		<comments>http://albertfama.com/php/learning-php/#comments</comments>
		<pubDate>Wed, 21 Nov 2007 19:56:12 +0000</pubDate>
		<dc:creator>Albert Fama</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://obnexus.net/?p=40</guid>
		<description><![CDATA[Over the weekend I was visiting a friend, who has his own website. He uses PHP on the site, but he is not a programmer. The site is his hobby and he has only learned enough PHP to get the job done. Simply put this is not his occupation. 
While visiting he was in the [...]]]></description>
			<content:encoded><![CDATA[<p>Over the weekend I was visiting a friend, who has his own website. He uses PHP on the site, but he is not a programmer. The site is his hobby and he has only learned enough PHP to get the job done. Simply put this is not his occupation. </p>
<p>While visiting he was in the middle of writing a small script which queried articles out of a database and displayed them according to the categories they were assigned to. Everything was working correctly, but the processing time was slower than he would like. He asked if I could take a look and see if anything could be done to speed things up. While optimizing some of the PHP and SQL code; I was showing him different functions which are built into PHP and MySQL, (these functions will always execute faster than the ones you write yourself). </p>
<p>As I was standing over his shoulder pointing out the different problematic areas, he asked me how I was able to keep all that information in my head. I simply replied that it is my job, it&#8217;s what I get paid to do. After going back and forth, what he actually wanted to know was how I  memorized all the different functions, which parameters they accept, and in what order. This is not the first time I have been asked this question so I decided to actually think about how it all happened.</p>
<p>I once read the book &#8216;On Writing&#8217; (by Stephen King), it is a book about how to become a writer. I don&#8217;t really remember a lot about the book, but I do remember one thing. He said that if you want to be a writer, you need to write everyday. It does not have to be anything great, just write something. I attempted to do this, but it became a chore and I soon stopped writing.</p>
<p>After thinking about the question my friend asked (I admit I have a horrible memory) but just like King said, do it everyday. I learned PHP simply by writing code everyday, by using PHP constantly, and little by little things sink in and stay. I never sat down with the manual and made an effort to memorize things, it just naturally happened over a period of time.</p>
<p>When I first started, I remember the fascination I had with writing something that made a computer do what I wanted. It was almost like an addiction, once I got it to do one thing, I wanted write something more complicated. Granted over the years it takes more, but I am now writing more complicated code and when it works, I get that same feeling.</p>
<p>So if you want to become a coder that is able to write scripts off the top of your head, or be able to &#8217;see&#8217; the code before you even begin, do it everyday. It does not have to be ground breaking or a completely new idea, just write something. If you find that writing code everyday becomes a chore, then you may want to try your hand at something else, maybe become an author.</p>

                            <div id="aspdf">
                                <a href="http://albertfama.com/wp-content/plugins/as-pdf/generate.php?post=40">
                                    <span>&nbsp;</span>
                                </a>
                            </div>
                        ]]></content:encoded>
			<wfw:commentRss>http://albertfama.com/php/learning-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
