<?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>Musings of a code slave &#187; PHP</title>
	<atom:link href="http://foundationphp.com/blog/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://foundationphp.com/blog</link>
	<description></description>
	<lastBuildDate>Sat, 28 Jan 2012 14:05:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>New video PHP course for complete beginners</title>
		<link>http://foundationphp.com/blog/2012/01/26/new-video-php-course-for-complete-beginners/</link>
		<comments>http://foundationphp.com/blog/2012/01/26/new-video-php-course-for-complete-beginners/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 13:27:48 +0000</pubDate>
		<dc:creator>David Powers</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://foundationphp.com/blog/?p=298</guid>
		<description><![CDATA[I&#8217;m delighted to announce that my new video course, Introducing PHP, has just been published by video2brain. The course contains nearly 5 hours of video instruction, starting with the installation of a PHP testing environment on your local computer, with &#8230; <a href="http://foundationphp.com/blog/2012/01/26/new-video-php-course-for-complete-beginners/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m delighted to announce that my new video course, <a href="http://www.video2brain.com/en/products-263.htm"><cite>Introducing PHP</cite></a>, has just been published by <a href="http://www.video2brain.com/en/">video2brain</a>. The course contains nearly 5 hours of video instruction, starting with the installation of a PHP testing environment on your local computer, with separate instructions for Windows and Mac users. You&#8217;ll then learn all the basics of PHP syntax:</p>
<ul>
<li>Using variables</li>
<li>Working with strings (text), numbers, and arrays</li>
<li>Making decisions with conditions and comparisons</li>
<li>Using built-in functions and creating your own custom functions</li>
<li>Including external files</li>
<li>Deciphering PHP&#8217;s often cryptic error messages</li>
</ul>
<p>Finally, all that knowledge is put to practical use by building a script to gather user input from an online form and send it by email. The content of the course covers similar ground to the first five chapters of my book <a href="http://foundationphp.com/phpsolutions/"><cite>PHP Solutions, 2nd Edition</cite></a>, and is aimed at people who prefer learning by watching and doing rather than from the pages of a book.</p>
<p>The course costs $39.99 on its own, but is free to video2brain subscribers. Subscription plans start at $14.99 a month ($149 a year), but until the end of March 2012, you can <a href="http://www.video2brain.com/en/subscriptions-promo?aid=263">get a discount by following this link</a>. If you&#8217;d like to try before you buy, there are four free videos from the course:</p>
<ul>
<li><a href="http://www.video2brain.com/en/videos-11941.htm">Setting Up a PHP Site in Dreamweaver</a></li>
<li><a href="http://www.video2brain.com/en/videos-11943.htm">PHP, the big picture</a></li>
<li><a href="http://www.video2brain.com/en/videos-11965.htm">Using Loops for Repetitive Actions</a></li>
<li><a href="http://www.video2brain.com/en/videos-11987.htm">How PHP Sends Email</a></li>
</ul>
<p>Although one of the videos shows how to set up a PHP site in Dreamweaver, you do <em>not</em> need Dreamweaver to follow the course. It&#8217;s completely software-neutral and contains advice on choosing a suitable script editor, with suggestions for both free and paid-for programs.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://foundationphp.com/blog/2012/01/26/new-video-php-course-for-complete-beginners/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New tutorial: send a link to a friend</title>
		<link>http://foundationphp.com/blog/2011/12/22/new-tutorial-send-a-link-to-a-friend/</link>
		<comments>http://foundationphp.com/blog/2011/12/22/new-tutorial-send-a-link-to-a-friend/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 19:48:51 +0000</pubDate>
		<dc:creator>David Powers</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://foundationphp.com/blog/?p=288</guid>
		<description><![CDATA[I&#8217;ve just published a new tutorial for a script that sends a link to a friend. It&#8217;s a very simple script, but—as long as you have a basic knowledge of PHP—you should be able to adapt it to your own &#8230; <a href="http://foundationphp.com/blog/2011/12/22/new-tutorial-send-a-link-to-a-friend/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just published a new tutorial for a script that <a href="/tutorials/sendtofriend.php">sends a link to a friend</a>. It&#8217;s a very simple script, but—as long as you have a basic knowledge of PHP—you should be able to adapt it to your own needs. The tutorial explains how the code works, and gives instructions for those sections that you need to change. If you find the instructions difficult to follow, maybe it&#8217;s time to grab hold of <a href="/phpsolutions/"><cite>PHP Solutions, 2nd Edition</cite></a> and learn how to write PHP scripts.</p>
]]></content:encoded>
			<wfw:commentRss>http://foundationphp.com/blog/2011/12/22/new-tutorial-send-a-link-to-a-friend/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Great training resource for web designers and digital artists</title>
		<link>http://foundationphp.com/blog/2011/12/21/great-training-resource-for-web-designers-and-digital-artists/</link>
		<comments>http://foundationphp.com/blog/2011/12/21/great-training-resource-for-web-designers-and-digital-artists/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 16:32:51 +0000</pubDate>
		<dc:creator>David Powers</dc:creator>
				<category><![CDATA[AJAX/JavaScript]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://foundationphp.com/blog/?p=282</guid>
		<description><![CDATA[I&#8217;m a great fan of learning from books—that&#8217;s why I written so many. But there are times when a book just won&#8217;t do. Seeing and hearing an expert show you how to do something often has much more impact. Several &#8230; <a href="http://foundationphp.com/blog/2011/12/21/great-training-resource-for-web-designers-and-digital-artists/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a great fan of learning from books—that&#8217;s why I written so many. But there are times when a book just won&#8217;t do. Seeing and hearing an expert show you how to do something often has much more impact. Several months ago, I took the plunge into making <a href="http://foundationphp.com/cs55lbv/index.php">a video course about HTML5, CSS3, and JavaScript</a>; and I&#8217;ve just finished recording a PHP course for beginners (it&#8217;s due out in the second half of January 2012). I recorded both courses for <a href="http://video2brain.com/en/">video2brain</a>, which has recently launched <a href="http://www.video2brain.com/en/subscriptions-promo?aid=263">a subscription service</a>.</p>
<p>Never heard of video2brain? It&#8217;s an Austrian company that has been providing video training in German, French, and Spanish for the past decade. It started creating courses in English in 2009, and now has more than 500 hours of English-language instruction on Photoshop, InDesign, Dreamweaver, and many other aspects of digital media. The videos have been created by some of the top names in their fields, including Rufus Deuchler, Tom Green, Angie Taylor, Todd Kopriva—not to mention me. The company has also created a large number of videos for Peachpit, one of the best known names in computer technology publishing. So, it&#8217;s no fly-by-night company.</p>
<p>As a video2brain author, I&#8217;m able to offer <a href="http://www.video2brain.com/en/subscriptions-promo?aid=263">a substantial discount</a> on the already competitive prices for the new subscription service. There are three levels of subscription:</p>
<ul>
<li><strong>Standard</strong>—$129 a year or $12.99 a month (normally $149/$14.99). This gives you unlimited access to all English courses streamed online.</li>
<li><strong>Gold</strong>—$179 a year or $17.99 a month (normally $199/$19.99). In addition to the courses, you also get access to all project files and PDF books.</li>
<li><strong>Platinum</strong>—$279 a year (normally $299). In addition to the the project files and PDF books, you can download the courses to view them offline.</li>
</ul>
<p>Students and teachers can purchase the academic version of the standard subscription for $99 a year.</p>
<p>If you subscribe during the introductory period, video2brain says it will lock the subscription price for three years. And as the collection of courses grows, you&#8217;ll get immediate access to all new titles. It&#8217;s planned to add at least four new courses each month. So, if you&#8217;re looking to brush up your digital skills and keep abreast of the latest developments, you can do so for as little as 35 cents a day. Many of the courses have sample videos that you can view free of charge, so you can judge the quality for yourself before committing your hard-earned cash.</p>
]]></content:encoded>
			<wfw:commentRss>http://foundationphp.com/blog/2011/12/21/great-training-resource-for-web-designers-and-digital-artists/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using num_rows with a MySQLi prepared statement</title>
		<link>http://foundationphp.com/blog/2011/09/24/using-num_rows-with-a-mysqli-prepared-statement/</link>
		<comments>http://foundationphp.com/blog/2011/09/24/using-num_rows-with-a-mysqli-prepared-statement/#comments</comments>
		<pubDate>Sat, 24 Sep 2011 12:48:02 +0000</pubDate>
		<dc:creator>David Powers</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://foundationphp.com/blog/?p=259</guid>
		<description><![CDATA[While refactoring some code that I had written about six years ago, I was puzzled by the MySQLi num_rows property constantly returning 0, even though I knew there were matching records in the database. It turns out that the problem &#8230; <a href="http://foundationphp.com/blog/2011/09/24/using-num_rows-with-a-mysqli-prepared-statement/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>While refactoring some code that I had written about six years ago, I was puzzled by the MySQLi <code>num_rows</code> property constantly returning 0, even though I knew there were matching records in the database. It turns out that the problem was caused by using a prepared statement, but not storing the result before attempting to access <code>num_rows</code>. I hadn&#8217;t bothered to store the result because all I wanted to know was if there were any matching records. This is the code I was using:</p>
<p><code>$stmt = $db->stmt_init();<br />
$sql = 'SELECT username FROM users WHERE username = ?';<br />
$stmt->prepare($sql);<br />
$stmt->bind_param('s', $_POST['username']);<br />
$stmt->execute();<br />
$numrows = $stmt->num_rows;</code></p>
<p>The code worked without error, so it wasn&#8217;t immediately obvious why <code>$numrows</code> was always 0. So, I checked the <a href="http://docs.php.net/manual/en/mysqli-stmt.num-rows.php">PHP documentation for <code>mysqli_stmt::num_rows</code></a>. The description is rather ambiguous in that it refers only to the need to store the result when using the procedural style, but the object-oriented example makes it clear that you need to call the <code>store_result()</code> method before accessing the <code>num_rows</code> property. When I changed my code like this, I got the expected result:</p>
<p><code>$stmt = $db->stmt_init();<br />
$sql = 'SELECT username FROM users WHERE username = ?';<br />
$stmt->prepare($sql);<br />
$stmt->bind_param('s', $_POST['username']);<br />
$stmt->execute();<br />
// store result of prepared statement<br />
$stmt->store_result();<br />
$numrows = $stmt->num_rows;</code></p>
<p>At first, it seemed counterintuitive to store a result that I was going to throw away, but that&#8217;s how <code>num_rows</code> works with a MySQLi prepared statement. Thinking about it a bit more, it makes sense because if you use the MySQLi <code>query()</code> method instead of a prepared statement, you store the result in a <code>MySQLi_Result</code> object and get the number of rows from the result like this:</p>
<p><code>$sql = 'SELECT user_id, name, username FROM users';<br />
$result = $db->query($sql);<br />
$numrows = $result->num_rows;</code></p>
]]></content:encoded>
			<wfw:commentRss>http://foundationphp.com/blog/2011/09/24/using-num_rows-with-a-mysqli-prepared-statement/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>What&#8217;s the difference between parameters and arguments?</title>
		<link>http://foundationphp.com/blog/2011/09/24/whats-the-difference-between-parameters-and-arguments/</link>
		<comments>http://foundationphp.com/blog/2011/09/24/whats-the-difference-between-parameters-and-arguments/#comments</comments>
		<pubDate>Sat, 24 Sep 2011 11:20:20 +0000</pubDate>
		<dc:creator>David Powers</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://foundationphp.com/blog/?p=254</guid>
		<description><![CDATA[When writing books aimed at beginners, there&#8217;s a difficult line to tread between giving too much and too little information. Too much information overloads the mind, running the risk of losing the reader&#8217;s enthusiasm for the subject. Too little information &#8230; <a href="http://foundationphp.com/blog/2011/09/24/whats-the-difference-between-parameters-and-arguments/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>When writing books aimed at beginners, there&#8217;s a difficult line to tread between giving too much and too little information. Too much information overloads the mind, running the risk of losing the reader&#8217;s enthusiasm for the subject. Too little information leaves questions unanswered.</p>
<p>Chapter 3 of my <a href="/phpsolutions/"><cite>PHP Solutions, 2nd Edition</cite></a> makes for pretty heavy reading. So much so that I recommend stopping halfway through on the first pass. That&#8217;s why I skirted around the difference between parameters and arguments on page 43. But I&#8217;ve piqued the interest of <a href="http://www.meetup.com/bostonphp/members/24224922/">Tom Flis</a>, one of the participants in <a href="http://www.meetup.com/bostonphp/">Boston PHP</a>&#8216;s self-study group <a href="http://www.meetup.com/bostonphp/events/28906641/">PHP Percolate</a>. He&#8217;s asked what&#8217;s the technical difference between the two words, so here goes. It&#8217;s actually quite simple.</p>
<p>When you define a function, the variables that represent the values that will be passed to it for processing are called <em>parameters</em>. For example, the following function definition has one parameter called <code>$number</code>:</p>
<p><code>function doubleIt($number) {<br />
    return $number *= 2;<br />
}</code></p>
<p>However, when you use a function, the value you pass to it is called an <em>argument</em>. So, in the following case, <code>$price</code> is passed as the argument to <code>doubleIt()</code>:</p>
<p><code>$price = 50;<br />
$inflated_price = doubleIt($price);  // 100</code></p>
<p>It&#8217;s a pretty subtle difference. A parameter contains no value; it&#8217;s simply a placeholder for the value that will be passed to the function. An argument contains a value (even if it&#8217;s <code>null</code> or an empty string) that the function processes to produce a result. Because the meanings are so similar, many developers use the words interchangeably or always refer to arguments.</p>
<p>So, now you know.</p>
]]></content:encoded>
			<wfw:commentRss>http://foundationphp.com/blog/2011/09/24/whats-the-difference-between-parameters-and-arguments/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Accessing PHP objects&#8217; methods and properties</title>
		<link>http://foundationphp.com/blog/2011/09/19/accessing-php-objects-methods-and-properties/</link>
		<comments>http://foundationphp.com/blog/2011/09/19/accessing-php-objects-methods-and-properties/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 13:09:30 +0000</pubDate>
		<dc:creator>David Powers</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://foundationphp.com/blog/?p=241</guid>
		<description><![CDATA[A couple of participants in Boston PHP&#8216;s self-study PHP Percolate, Jim Wright and Jared Stenquist, are confused about the use of the -&#62; operator, which is introduced on page 44 of PHP Solutions, 2nd Edition. Since others might be in &#8230; <a href="http://foundationphp.com/blog/2011/09/19/accessing-php-objects-methods-and-properties/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A couple of participants in <a href="http://www.meetup.com/bostonphp/">Boston PHP</a>&#8216;s self-study <a href="http://www.meetup.com/bostonphp/events/28906641/">PHP Percolate</a>, Jim Wright and Jared Stenquist, are confused about the use of the <code>-&gt;</code> operator, which is introduced on page 44 of <a href="/phpsolutions/"><cite>PHP Solutions, 2nd Edition</cite></a>. Since others might be in a similar situation, I decided to write a blog post about it.</p>
<p>Although PHP isn&#8217;t an object-oriented language, it has extensive support for objects. Also, since PHP 5, many core aspects of the language use objects rather than ordinary (procedural) functions. An <dfn>object</dfn> is a special data type that is capable of storing and manipulating values. You create an object from a <dfn>class</dfn>, which is a collection of functions and variables that define the object&#8217;s characteristics. Some classes, such as <code>DateTime</code> and <code>Mysqli</code>, are predefined by PHP, but you can also define your own.</p>
<p>The advantage of using classes and objects is that, once the class has been defined, they reduce the amount of code you need to write. An object inherits all the functions and variables defined by the class. That&#8217;s not all. Each object is independent, so you can create several objects from the same class to store different values, but they all share the same functions. Up to now, I&#8217;ve referred to functions and variables, but when talking about objects and classes, a function is called a <dfn>method</dfn>, and a variable is called a <dfn>property</dfn>. Whenever you want to use an object&#8217;s method or property, you need to use the <code>-&gt;</code> operator.</p>
<p>You create an object by calling the class&#8217;s constructor method (which has the same name as the class) with the <code>new</code> keyword. Most constructor methods also accept arguments that set the initial properties of the object. In the case of the built-in <code>DateTime</code> class, you can use a string to specify the date. Without any arguments, it creates an object for the current date and time. For example, the following code creates two objects, one for today, and the other for Christmas Day 2011:</p>
<p><code>$today = new DateTime();<br />
$xmas2011 = new DateTime('12/25/2011');</code></p>
<p>The <code>$today</code> object now contains the current date and time, but <code>$xmas2011</code> contains the date for December 25, 2011 (because the time wasn&#8217;t specified when creating the object, it&#8217;s set to midnight at the start of the day).</p>
<p>To display the day of the week, you need to use the <code>DateTime</code> class&#8217;s <code>format()</code> method, and pass it <a href="http://docs.php.net/manual/en/function.date.php">a format string</a> (they&#8217;re listed in Table 14-4 on page 402 of <cite>PHP Solutions, 2nd Edition</cite>) for the weekday name like this:</p>
<p><code>echo $today-&gt;format('l');</code></p>
<p>This displays whatever day it is today. However, the date stored in <code>$xmas2011</code> is independent of <code>$today</code>. The following code displays &#8220;Sunday&#8221;:</p>
<p><code>echo $xmas2011-&gt;format('l');  // Sunday</code></p>
<p>Using the <code>-&gt;</code> operator is very similar to passing a variable as an argument to a function. Instead of putting the variable between the function&#8217;s parentheses, you attach the function (method) to the variable with the <code>-&gt;</code> operator. What it actually means is &#8220;use the <code>format()</code> method with the value stored in this object (<code>$xmas2011</code>)&#8221;. In addition to <code>format()</code>, the <code>DateTime</code> class has other methods, such as <code>setDate()</code> and <code>add()</code>, that can be used to modify the date.</p>
<p>Many objects also have properties that you can access. An object&#8217;s properties are similar to values stored in an array. The big difference is that the class definition can control how a property is accessed and modified by specifying whether it&#8217;s <code>public</code>, <code>protected</code>, or <code>private</code>. Only <code>public</code> properties are visible and can be modified outside the class definition; <code>protected</code> and <code>private</code> ones are hidden from view. You access a <code>public</code> property using the <code>-&gt;</code> operator like this:</p>
<p><code>$someObject-&gt;propertyName</code></p>
<p>This is the equivalent of accessing an array element like this:</p>
<p><code>$arrayName['elementName']</code></p>
<p>If you&#8217;re familiar with JavaScript, it should be obvious by now that the <code>-&gt;</code> operator plays the same role in PHP as the dot operator in JavaScript. For example, in JavaScript, this produces the date for Christmas Day 2011:</p>
<p><code>var xmas2011 = new Date(2011, 11, 25); // months are zero-based<br />
alert('Christmas 2011 is on ' + xmas2011.toString());</code></p>
<p>JavaScript also uses the dot operator for properties:</p>
<p><code>objectName.propertyName</code></p>
<p>Hopefully, that clarifies the role of the <code>-&gt;</code> operator. If you still have questions, post them in the Comments section below.</p>
]]></content:encoded>
			<wfw:commentRss>http://foundationphp.com/blog/2011/09/19/accessing-php-objects-methods-and-properties/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Join others learning PHP with PHP Solutions</title>
		<link>http://foundationphp.com/blog/2011/08/25/join-others-learning-php-with-php-solutions/</link>
		<comments>http://foundationphp.com/blog/2011/08/25/join-others-learning-php-with-php-solutions/#comments</comments>
		<pubDate>Thu, 25 Aug 2011 13:42:51 +0000</pubDate>
		<dc:creator>David Powers</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://foundationphp.com/blog/?p=231</guid>
		<description><![CDATA[So far, more than 90 people have signed up to join a self-study group organized by Boston PHP to learn PHP with the help of my book, PHP Solutions: Dynamic Web Design Made Easy, 2nd Edition. This is the third &#8230; <a href="http://foundationphp.com/blog/2011/08/25/join-others-learning-php-with-php-solutions/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So far, more than 90 people have signed up to join a self-study group organized by <a href="http://www.meetup.com/bostonphp/">Boston PHP</a> to learn PHP with the help of my book, <a href="/phpsolutions/"><cite>PHP Solutions: Dynamic Web Design Made Easy, 2nd Edition</cite></a>. This is the third time that Boston PHP has run this scheme known as <a href="http://www.meetup.com/bostonphp/events/28906641/">PHP Percolate</a>, which begins again <time datetime="2011-09-01">next Thursday (September 1)</time>. I understand that nearly 200 have taken part in the previous two seasons. The fact that they&#8217;re running it again—and that so many have signed up—indicates that it must be a pretty successful way of learning PHP.</p>
<p>There&#8217;s no charge to participate. The only cost is buying a copy of my book. Although I have Amazon affiliate links on my website, I encourage you to buy it through the <a href="http://astore.amazon.com/boph-20">Boston PHP Store</a>. That way, the organizers get a small commission that helps support the activities of Boston PHP.</p>
<p>The way it works is that you commit to reading one chapter of the book (there are 17) and completing the exercises each week. There&#8217;s no classroom instruction, but you can get online support through a dedicated forum for each chapter. Also, if you live in the Boston area (the one in Massachusetts, not the one in Lincolnshire or more than a dozen other places), you can get hands-on help at the PHP Percolate Coffee Club, which is usually held every Saturday morning at a Starbucks. Boston PHP also runs occasional all-day events known as <a href="http://www.meetup.com/bostonphp/events/27206091/">Developer Dorm Room</a> in Cambridge, Massachusetts, where you can get help with PHP problems or just bounce ideas about projects off each other.</p>
<p>Although PHP Percolate is based on my book, this isn&#8217;t a wacky marketing idea that has been dreamed up by me or my publisher. It&#8217;s an idea that Boston PHP came up with independently. In fact, I didn&#8217;t learn about it until quite recently. According to the President of Boston PHP, Michael Bourque, Boston PHP is the largest and most active PHP tech community in the world, with more than 1,900 members. It has a focus on education and adoption of open source technology like PHP. Last year, they were looking for the best possible book to learn PHP, and mine was the one they chose. Naturally, I&#8217;m delighted, and I have agreed to help in whatever way I can.</p>
<p>Unfortunately, there&#8217;s a small matter of the Atlantic Ocean lying between me and Boston, so I won&#8217;t be able to attend the PHP Percolate Coffee Club or Developer Dorm Room in person. But that&#8217;s one of the joys of the internet. You don&#8217;t need to be there in person to share ideas and cooperate with others. From what I understand, PHP Percolate has also attracted people from other countries to join in. A book and an internet connection is all you need.</p>
<p>Committing to working through 17 chapters in as many weeks is a lot to ask. Work, family, and other obligations get in the way. So, not everybody manages to last the whole course. But since there&#8217;s no cost (apart from the book), there&#8217;s little to lose. In fact, I see that some of the people who dropped out part of the way through season 2 have signed up again for season 3. As one of them said, &#8220;It&#8217;s fun!&#8221;</p>
<p>So, if you&#8217;re looking for a little bit of moral support in your efforts to learn PHP, check out <a href="http://www.meetup.com/bostonphp/events/28906641/">PHP Percolate Season 3</a> with Boston PHP.</p>
]]></content:encoded>
			<wfw:commentRss>http://foundationphp.com/blog/2011/08/25/join-others-learning-php-with-php-solutions/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Corrections for my books</title>
		<link>http://foundationphp.com/blog/2011/08/14/corrections-for-my-books/</link>
		<comments>http://foundationphp.com/blog/2011/08/14/corrections-for-my-books/#comments</comments>
		<pubDate>Sun, 14 Aug 2011 18:52:32 +0000</pubDate>
		<dc:creator>David Powers</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Dreamweaver]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://foundationphp.com/blog/?p=213</guid>
		<description><![CDATA[I hate it when I find a mistake in a technical book—particularly when it&#8217;s one of mine. There&#8217;s nothing more frustrating than trying to learn a new concept and hitting a brick wall because the code doesn&#8217;t work. Mistakes creep &#8230; <a href="http://foundationphp.com/blog/2011/08/14/corrections-for-my-books/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I hate it when I find a mistake in a technical book—particularly when it&#8217;s one of mine. There&#8217;s nothing more frustrating than trying to learn a new concept and hitting a brick wall because the code doesn&#8217;t work. Mistakes creep in for a variety of reasons. But whatever the reason, I know I&#8217;m letting down my readers if there&#8217;s a serious error in one of my books. So, as well as trying to avoid errors in the first place, I try to respond to error reports as quickly as possible.</p>
<p>I recently discovered that friends of ED has closed its website and merged it with that of its parent company, <a href="http://apress.com/">Apress</a>. Unfortunately, none of my books&#8217; errata are yet listed on the new site. So, I&#8217;ve scrabbled around to put them back together and host them here. You can find the corrections for the following Apress/friends of ED titles on this site:</p>
<ul>
<li><a href="http://foundationphp.com/pos/errata.php">PHP Object-Oriented Solutions</a></li>
<li><a href="http://foundationphp.com/phpsolutions/updates.php">PHP Solutions (First edition)</a></li>
<li><a href="http://foundationphp.com/phpsolutions/errata_2e.php">PHP Solutions (Second edition)</a></li>
<li><a href="http://foundationphp.com/egdwcs3/updates.php">The Essential Guide to Dreamweaver CS3</a></li>
<li><a href="http://foundationphp.com/flash/updates.php">Foundation PHP 5 for Flash</a></li>
</ul>
<p>I find it hard to believe that there weren&#8217;t any mistakes in <cite>The Essential Guide to Dreamweaver CS4</cite>, but I can&#8217;t trace any record of corrections. I haven&#8217;t gone back to some of my older books. Good though they were, they&#8217;re based on versions of software that are no longer supported. What&#8217;s more, most of them were reprinted with corrections.</p>
<p>I also plan to keep up to date the corrections pages on this site for the books I have published with Adobe Press.</p>
<p>If you come across any errors or code that doesn&#8217;t work, please report them directly to the publisher. That way corrections can be incorporated into reprinted versions of the book. But if you don&#8217;t get an acknowledgement from the publisher within a day or so, please leave a comment here, and I&#8217;ll try to deal with the issue as quickly as possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://foundationphp.com/blog/2011/08/14/corrections-for-my-books/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Missing file for PHP Solutions, Second Edition</title>
		<link>http://foundationphp.com/blog/2011/01/05/missing-file-for-php-solutions-second-edition/</link>
		<comments>http://foundationphp.com/blog/2011/01/05/missing-file-for-php-solutions-second-edition/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 12:50:13 +0000</pubDate>
		<dc:creator>David Powers</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://foundationphp.com/blog/?p=186</guid>
		<description><![CDATA[A couple of readers have reported that download.php was missing from the ch07 folder of the download files for PHP Solutions, Second Edition. The zip file on the friends of ED download page has now been updated. If you downloaded &#8230; <a href="http://foundationphp.com/blog/2011/01/05/missing-file-for-php-solutions-second-edition/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A couple of readers have reported that <code>download.php</code> was missing from the <code>ch07</code> folder of the download files for <a href="/phpsolutions/"><cite>PHP Solutions, Second Edition</cite></a>. The zip file on the <a href="http://www.friendsofed.com/download.html?isbn=1430232498">friends of ED download page</a> has now been updated. If you downloaded the zip file before 4 January, please download the updated version. Many apologies for the inconvenience.</p>
<p>While checking the reports of the missing file, I discovered a mistake in the code on page 211 of the book. A closing curly brace is missing at the bottom of the script. Details are on <a href="/phpsolutions/errata_2e.php">the book&#8217;s corrections page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://foundationphp.com/blog/2011/01/05/missing-file-for-php-solutions-second-edition/feed/</wfw:commentRss>
		<slash:comments>51</slash:comments>
		</item>
		<item>
		<title>Preventing email header injection</title>
		<link>http://foundationphp.com/blog/2010/12/31/preventing-email-header-injection/</link>
		<comments>http://foundationphp.com/blog/2010/12/31/preventing-email-header-injection/#comments</comments>
		<pubDate>Fri, 31 Dec 2010 18:45:12 +0000</pubDate>
		<dc:creator>David Powers</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://foundationphp.com/blog/?p=181</guid>
		<description><![CDATA[More than five years have passed since New York PHP published an extremely useful article warning developers of the dangers of email header injection, and providing detailed instructions of how to prevent it. Yet barely a week goes by without &#8230; <a href="http://foundationphp.com/blog/2010/12/31/preventing-email-header-injection/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>More than five years have passed since New York PHP published an <a href="http://www.adobe.com/devnet/dreamweaver/articles/setup_php.html">extremely useful article</a> warning developers of the dangers of email header injection, and providing detailed instructions of how to prevent it. Yet barely a week goes by without PHP newcomers posting requests for help with email scripts that still contain this vulnerability. Unfortunately, many beginners seem to use outdated scripts or tutorials that ignore basic security, and have never heard of email header injection. When they&#8217;re told about it, the NYPHP article is too technical for them to understand. So, this is an attempt to make it simple.</p>
<h3>What is email header injection?</h3>
<p>The PHP <code>mail()</code> function takes up to five arguments, the first three of which are required: the address(es) the mail is being sent to, the subject line, and the body of the message. The fourth argument allows you to specify additional headers, such as From, Reply-to, Cc, and Bcc. Email header injection usually targets weaknesses in the way this fourth argument is handled to insert bogus headers to turn your online form into a spam relay.</p>
<p>One of the most common uses of the fourth argument is to insert the user&#8217;s email address into the From or Reply-to header. It&#8217;s extremely convenient, because it allows you to reply directly to an email received from an online form just by clicking the Reply button in your email program. It&#8217;s also extremely convenient for an attacker. All that&#8217;s necessary is to add a string of spurious headers into the email field of your contact form, and your website becomes an instant spam relay—unless, of course, you take suitable precautions.</p>
<h3>Preventing email header injection</h3>
<p>The <a href="http://docs.php.net/manual/en/intro.filter.php">data filters</a> introduced in PHP 5.2 make it easy to check that the value submitted through the email field of an online form contains a single email address and nothing else. So, if you want to put the user&#8217;s email address in a Reply-to header, you can check it like this (assuming the input field is named &#8220;email&#8221;):</p>
<p><code>$validemail = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);<br />
if ($validemail) {<br />
  $headers .= "Reply-to: $validemail\r\n";<br />
}</code></p>
<p>Note that <code>INPUT_POST</code> and <code>FILTER_VALIDATE_EMAIL</code> are PHP constants, and must be in uppercase.</p>
<p>Using <code>filter_input()</code> like this is a simple, and effective way to prevent the email field of a contact form being exploited for header injection. Of course, you would probably want to take further action if the email address fails validation (the filter checks only that it&#8217;s in a valid format—it doesn&#8217;t check whether it&#8217;s a genuine address), such as redisplaying the form with an error message. This blog post is concerned only with basic prevention.</p>
<h3>Is that all that&#8217;s needed?</h3>
<p>Although the email field of a contact form is the main target, you also need to be careful about allowing user input in the first and second arguments to <code>mail()</code>: the address the message is being sent to, and the subject line. If both values are hard-coded in your script, there&#8217;s nothing to worry about. However, if your form allows the user to select from a choice of destination addresses, or insert a custom subject line, you need to sanitize those values before passing them to <code>mail()</code>. Don&#8217;t be fooled by thinking that a drop-down menu in your form limits the values that can be entered. It&#8217;s very easy for an attacker to bypass your preselected values.</p>
<p>One way of handling the destination addresses is to create an array of valid addresses, and use <code>in_array()</code> to check that the submitted value is among them.</p>
<p><code>$destinations = array('me@example.com', 'you@example.com');<br />
if (in_array($_POST['to'], $destinations) {<br />
  // the address is OK to use<br />
} else {<br />
  // don't send the mail<br />
}</code></p>
<p>You can do the same with a choice of subjects. But if you want to allow the user to enter a custom subject line, you need to check that it doesn&#8217;t contain newline characters or common headers. The following code uses a regular expression to detect characters and values likely to be used in an attack:</p>
<p><code>$pattern = '/[\r\n]|Content-Type:|Bcc:|Cc:/i';<br />
if (preg_match($pattern, $_POST['subject'])) {<br />
  // reject the post, as it's most likely an attack<br />
}</code></p>
<p>I go into much more detail in <a href="/books.php">my books</a>, but hopefully this help PHP newcomers to adopt more secure coding practices with <code>mail()</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://foundationphp.com/blog/2010/12/31/preventing-email-header-injection/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

