<?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>Tiffany B. Brown &#187; PHP</title>
	<atom:link href="http://tiffanybbrown.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://tiffanybbrown.com</link>
	<description>A web log about web development and internet culture with frequent detours into other stuff.</description>
	<lastBuildDate>Wed, 23 May 2012 16:23:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Yes, you really do need to learn JavaScript</title>
		<link>http://tiffanybbrown.com/2009/12/03/yes-you-really-do-need-to-learn-javascript/</link>
		<comments>http://tiffanybbrown.com/2009/12/03/yes-you-really-do-need-to-learn-javascript/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 16:20:03 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[Web Development & Programming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php advent]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/?p=2881</guid>
		<description><![CDATA[From Ed Finkler&#8216;s PHP Advent 2009 piece, You Really Need to Learn JavaScript: When I say &#8220;you need to learn JavaScript,&#8221; I don’t mean &#8220;learn how to copy and paste an example,&#8221; or &#8220;learn how to generate JavaScript with PHP.&#8221; I mean learn it as well as you already know PHP &#8212; or better. Why? Because JavaScript [...]]]></description>
			<content:encoded><![CDATA[<p>From <a href="http://funkatron.com/" class="ext">Ed Finkler</a>&#8216;s PHP Advent 2009 piece, <a href="http://phpadvent.org/2009/you-really-need-to-learn-javascript-by-ed-finkler" class="ext">You Really Need to Learn JavaScript</a>:</p>
<blockquote><p>When I say &#8220;you need to learn JavaScript,&#8221; I don’t mean &#8220;learn how to copy and paste an example,&#8221; or &#8220;learn how to generate JavaScript with PHP.&#8221; I mean learn it as well as you already know PHP &#8212; or better.</p>
<p>Why? Because JavaScript drives rich clients, and all indications are that clients will be getting richer. You won&#8217;t be able to get away with just adding small snippets of JS to add tooltips and simple animations. Complex processing and UI management will require real knowledge of how to write JS, and how in [sic] interacts with the client&#8217;s APIs &#8212; the DOM, local storage, networking, OS features, and more.</p></blockquote>
<p>And I will add: not <a href="http://jquery.com/" class="ext">jQuery</a>, not <a href="http://mootools.net/" class="ext">MooTools</a>, not <a href="http://www.dojotoolkit.org/" class="ext">Dojo</a>, but real, actual, JavaScript (and <a href="http://domscripting.com/" class="ext">DOMScripting</a>). Finkler tells you why and points you to some resources for learning more. </p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2009/12/03/yes-you-really-do-need-to-learn-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP in Arabic: An interview with Khaled Al-Shamaa</title>
		<link>http://tiffanybbrown.com/2009/11/18/php-in-arabic-an-interview-with-khaled-al-shamaa/</link>
		<comments>http://tiffanybbrown.com/2009/11/18/php-in-arabic-an-interview-with-khaled-al-shamaa/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 16:24:22 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[arabic]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[l10n]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[localization]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/?p=2610</guid>
		<description><![CDATA[PHP Classes interviews Khaled Al-Shamaa about his AR-PHP project, a series of PHP classes designed to handle Arabic-language web applications. Because Arabic uses a non-Latin character set, it presents a new set of challenges. PC: Developing Web applications in Arabic requires special care. What are the most important concerns and what components do you provide [...]]]></description>
			<content:encoded><![CDATA[<p>PHP Classes <a href="http://www.phpclasses.org/blog/post/107-PHP-in-Arabic.html" class="ext">interviews Khaled Al-Shamaa</a> about his <a href="http://www.ar-php.org/" class="ext">AR-PHP</a> project, a series of PHP classes designed to handle Arabic-language web applications. Because Arabic uses a non-Latin character set, it presents a new set of challenges. </p>
<blockquote><p>
<b>PC: </b> Developing Web applications in Arabic requires special care. What are the most important concerns and what components do you provide to address those concerns?</p>
<p><b>KA:</b>  Besides the search issue presented above, some of Arab countries use Hijri calendar instead of Gregorian calendar. So I developed classes to convert dates between those two calendars, as well as an Arabic version from date and strtotime PHP functions. &#8230; Another issue that is handled in this project is related to rendering Arabic text correctly in some libraries like GD, PDF, SWF and even VRML.</p></blockquote>
<p>This interested me simply because it raises awarness of cultural, linguistic, and character set challenges that monolingual developers, or Western character set developers don&#8217;t often think about. [Via <a href="http://www.phpdeveloper.org/news/13547">PHP Developer</a>]</p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2009/11/18/php-in-arabic-an-interview-with-khaled-al-shamaa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[PHP quickie] Select a certain number of words from a string</title>
		<link>http://tiffanybbrown.com/2009/03/26/php-quickie-select-a-certain-number-of-words-from-a-string/</link>
		<comments>http://tiffanybbrown.com/2009/03/26/php-quickie-select-a-certain-number-of-words-from-a-string/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 13:38:28 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[string manipulation]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/?p=1893</guid>
		<description><![CDATA[An alternative to subst() that selects entire words rather than a specified number of characters. I used this on a recent project where I needed to create a meta tag description from text and HTML stored in a database. Uses PHP&#8217;s native str_word_count() function. function select_number_of_words($input,$number_of_words){ $output = ''; $input = strip_tags($input); $input = str_word_count($input,1); [...]]]></description>
			<content:encoded><![CDATA[<p>An alternative to <a href="http://us2.php.net/manual/en/function.substr.php"><code>subst()</code></a> that selects entire words rather than a specified number of characters. I used this on a recent project where I needed to create a meta tag description from text and HTML stored in a database.</p>
<p>Uses PHP&#8217;s native <a href="http://us2.php.net/manual/en/function.str-word-count.php"><code>str_word_count()</code> function</a>.</p>
<pre>
function select_number_of_words($input,$number_of_words){
	$output = '';
	$input = strip_tags($input);
	$input = str_word_count($input,1);  // second parameter returns the string as an array.
	for($i=0; $i< $number_of_words; $i++){
		$output .=$input[$i].' ';
	}
	return trim($output); // cut off the last space.
}
</pre>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2009/03/26/php-quickie-select-a-certain-number-of-words-from-a-string/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Collecting e-commerce conversion data with Zen Cart and Google Analytics</title>
		<link>http://tiffanybbrown.com/2009/02/19/zen-cart-and-google-analytics/</link>
		<comments>http://tiffanybbrown.com/2009/02/19/zen-cart-and-google-analytics/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 09:00:44 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[ecommerce]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[online shopping]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[zen cart]]></category>
		<category><![CDATA[zencart]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/?p=1785</guid>
		<description><![CDATA[Google Analytics allows you to collect pretty robust data about how users move through your e-commerce site. Here&#8217;s how to make it work with Zen Cart, an open source shopping cart. For this tutorial, you will need: A Zen Cart-based shopping cart A Google Analytics account and the tracking code for both conversions and page [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://google.com/analytics">Google Analytics</a> allows you to collect pretty robust data about how users move through your e-commerce site. Here&#8217;s how to make it work with <a href="http://www.zen-cart.com/">Zen Cart</a>, an open source shopping cart.</p>
<p>For this tutorial, you will need:</p>
<ul>
<li>A Zen Cart-based shopping cart</li>
<li>A Google Analytics account and the tracking code for both conversions and page views.</li>
<li>Experience with <a href="http://www.php.net/">PHP</a> and <a href="http://dev.mysql.com/">MySQL</a> programming</li>
</ul>
<p>Also check out Google&#8217;s support article <a href="http://www.google.com/support/googleanalytics/bin/answer.py?hl=en&#038;answer=55528">How do I track e-commerce transactions?</a> and become <abbr title="best friends forever">BFF</abbr>s with the <a href="http://www.zen-cart.com/wiki/" class="ext">Zen Cart wiki</a>. </p>
<h2>Creating a custom functions file</h2>
<p>Create a file to <a href="http://www.zen-cart.com/wiki/index.php/Customisation_-_Templates#Automatically_included_files">house your custom functions</a>. Name it whatever you&#8217;d like (with a PHP extension, of course). Put it in your includes/functions/extra_functions/ directory. </p>
<p class="editors-note">A word of caution: I created these functions with my own SQL, outside of the Zen Cart framework. There may be a better way to do it.</p>
<p>In the file you created above, add the following code:</p>
<pre>
# get the product ID out of session key
function custom_get_prodId($productkey){
	$pid = explode(':',$productkey);
	return $pid[0];
}

#get the product data
function custom_get_product($prodID,$return='all'){
	global $db;
	reset($data);
	$q = sprintf("SELECT
			pd.products_name,
			pd.products_description,
			cd.categories_name, p.products_price
			FROM categories_description AS cd, products AS p, products_description AS pd
	 		WHERE  p.products_id = 183
   				AND p.master_categories_id = cd.categories_id
   				AND p.products_id = pd.products_id",$prodID);
	$res = $db->Execute($q);
	return $res->fields;
}
# get the current user's data
function custom_get_userinfo($custID){
	global $db;
	reset($data);
	$q = sprintf("SELECT
			ab.entry_street_address,
			ab.entry_postcode,
			ab.entry_city,
			ab.entry_state,
			c.countries_name,
			c.countries_iso_code_2
			FROM address_book AS ab, countries AS c
			WHERE customers_id=%d
			   AND ab.entry_country_id = c.countries_id
				  ",(int)$custID);
	$res = $db->Execute($q);
	return $res->fields;
}
</pre>
<p>Adjust the names of the tables if you have added a custom table prefix during your Zen Cart configuration. We&#8217;ll use these functions to get us the user data and product data we need. </p>
<h2>Edit the checkout success and global footer files</h2>
<p>Add the conversion tracking code &#8212; provided by Google Analytics &#8212; to the checkout success page template. It&#8217;s located in your templates directory, includes/templates/YOUR_TEMPLATE_DIR/templates/tpl_checkout_success_default.php.</p>
<p>Also add the regular Google Analytics tracking code to your footer file (found in includes/templates/YOUR_TEMPLATE_DIR/common/tpl_footer.php).</p>
<p><em>Below your Google Analytics code</em>, but also in your footer file, add the code below.</p>
<pre>
&lt;?php
# do this on the checkout success page only.
if($_GET['main_page'] == 'checkout_success'): 

$userdata = $_SESSION['cart'];
$moreud = custom_get_userinfo($_SESSION['customer_id']);
?&gt;
&lt;script type="text/javascript"&gt;
pageTracker._addTrans(
    "&lt;?=$userdata-&gt;cartID; ?&gt;",
    "www.YOURDOMAINNAME.com",
    "&lt;?=$userdata-&gt;total; ?&gt;",
    "",
    "&lt;?=$_SESSION['shipping']['cost']; ?&gt;",
    "&lt;?=$moreud['entry_city'];?&gt;",
    "&lt;?=$moreud['entry_state'];?&gt;",
    "&lt;?=$moreud['countries_name'];?&gt;"
  );
&lt;?
# for each product ID key in the userdata session
foreach($userdata-&gt;contents as $k=&gt;$v):
	/*
	the product id gets stored as an array key as xxx:funkymd5key
	ex: 183:fw920e8ktw327uio67xew9mn. custom_get_prodId extracts
	the product id part of that key.
	*/
	$pid = custom_get_prodId($k);
	$data = custom_get_product($pid,'all');
?&gt;

 pageTracker._addItem(
    "&lt;?=$userdata-&gt;cartID; ?&gt;",
    "&lt;?=getProdId($k); ?&gt;",
    "&lt;?=strip_tags($data['products_name']);?&gt;",
    "&lt;?=$data['categories_name'];?&gt;",
    "&lt;?=number_format($data['products_price'],2);?&gt;",
    "&lt;?=$v['qty']; ?&gt;"
  );
&lt;? endforeach; ?&gt;
pageTracker._trackTrans();
&lt;/script&gt;

&lt;?php endif;
} // flag_disable_footer
?&gt;
</pre>
<div class="editors-note">Providing this code with the following disclaimers: </p>
<ol>
<li>It may not work for you. </li>
<li>I&#8217;m not responsible if it does.</li>
<li>I can&#8217;t offer personalized support.</li>
</ol>
<p>In short: you&#8217;re on your own.
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2009/02/19/zen-cart-and-google-analytics/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Security vulnerability found in WordPress; Upgrade to 2.6.3</title>
		<link>http://tiffanybbrown.com/2008/10/23/security-vulnerability-found-in-wordpress-upgrade-to-263/</link>
		<comments>http://tiffanybbrown.com/2008/10/23/security-vulnerability-found-in-wordpress-upgrade-to-263/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 01:58:26 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[snoopy library]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/?p=1536</guid>
		<description><![CDATA[News of a vulnerability in the Snoopy open source PHP library has surfaced. WordPress uses the Snoopy library to power feeds in administration section&#8217;s Dashboard. A fix &#8212; WordPress 2.6.3 &#8212; was released today. You can download the entire package, or just download the two affected files and upload them to your server.]]></description>
			<content:encoded><![CDATA[<div class="photo"><img src="http://files.tiffanybbrown.com/wplogo.png" alt="WordPress" style="border:0;" /></div>
<p>News of a <a href="http://secunia.com/Advisories/32361/">vulnerability</a> in the <a href="http://sourceforge.net/projects/snoopy/">Snoopy</a> open source PHP library has surfaced. WordPress uses the Snoopy library to power feeds in administration section&#8217;s Dashboard.</p>
<p>A fix &#8212; <a href="http://wordpress.org/development/2008/10/wordpress-263/">WordPress 2.6.3</a> &#8212; was released today. You can download the <a href="http://wordpress.org/download/">entire package</a>, or just download the two <a href="http://trac.wordpress.org/export/9310/tags/2.6.3/wp-includes/class-snoopy.php">affected</a> <a href="http://trac.wordpress.org/export/9310/tags/2.6.3/wp-includes/version.php">files</a> and upload them to your server.</p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2008/10/23/security-vulnerability-found-in-wordpress-upgrade-to-263/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UPDATED: Atlanta, GA: PHP Atlanta &#8220;Join-Fu: The Art of SQL&#8221;</title>
		<link>http://tiffanybbrown.com/2008/07/18/atlanta-ga-php-atlanta-join-fu-the-art-of-sql/</link>
		<comments>http://tiffanybbrown.com/2008/07/18/atlanta-ga-php-atlanta-join-fu-the-art-of-sql/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 19:33:43 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Tech Events]]></category>
		<category><![CDATA[Atlanta]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[atlantaphp]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[jay pipes]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[underarmchairmedia]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/?p=1336</guid>
		<description><![CDATA[This meeting has been rescheduled to Thursday, August 14th at 7 p.m. Jay Pipes of MySQL AB and co-author of Pro MySQL, comes to Atlanta this month to present &#8220;Join-Fu: The Art of SQL.&#8221; I&#8217;ve seen Pipes speak before, and his presentation was incredibly informative. If you do a lot of development with MySQL, you [...]]]></description>
			<content:encoded><![CDATA[<div class="editors-note">This meeting has been <a class="ext" href="http://www.atlantaphp.org/archive/84">rescheduled</a> to <b>Thursday, August 14th at 7 p.m.</b></div>
<p><a href="http://jpipes.com/">Jay Pipes</a> of MySQL AB and co-author of <a class="book title" href="http://www.amazon.com/gp/redirect.html?ie=UTF8&#038;location=http%3A%2F%2Fwww.amazon.com%2FMySQL-Experts-Voice-Open-Source%2Fdp%2F159059505X%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1216408117%26sr%3D8-1&#038;tag=webinista-20&#038;linkCode=ur2&#038;camp=1789&#038;creative=9325">Pro MySQL</a><img src="http://www.assoc-amazon.com/e/ir?t=webinista-20&amp;l=ur2&amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, comes to Atlanta this month to present &#8220;Join-Fu: The Art of SQL.&#8221; </p>
<p>I&#8217;ve seen Pipes speak before, and his presentation was incredibly informative. If you do a lot of development with MySQL, you should definitely attend. </p>
<div class="event-details">
<h3>Event details</h3>
<ul>
<li><b>When:</b> Thursday, August 14th, 2008 from 7 p.m. until 9 p.m.
</li>
<li><b>Where:</b> <a href="http://www.atlantaphp.org/directions-canadian-consulate/">Consulate General of Canada</a> 17th floor Colony Square (see the concierge for access)</li>
<li><b>How much?:</b> Free to attend.</li>
<li><a href="http://www.atlantaphp.org/archive/83" class="ext">More information</a></li>
</ul>
</div>
<h4>Related:</h4>
<ul>
<li>Jay Pipes&#8217;s <a href="http://www.jpipes.com/index.php?/archives/239-Slides-for-Join-Fu-The-Art-of-SQL-I-and-II.html" class="ext">Slides for Join-Fu: The Art of SQL (I and II)</a> (I do not know whether this will be the same talk as the one Pipes will give next month.)</li>
<li><a href="http://tiffanybbrown.com/category/tech+events/feed/" title="RSS Feed">RSS for Tech Events</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2008/07/18/atlanta-ga-php-atlanta-join-fu-the-art-of-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Atlanta, GA: php&#124;works and PyWorks</title>
		<link>http://tiffanybbrown.com/2008/07/18/atlanta-ga-phpworks-and-pyworks/</link>
		<comments>http://tiffanybbrown.com/2008/07/18/atlanta-ga-phpworks-and-pyworks/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 15:49:48 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tech Events]]></category>
		<category><![CDATA[conferences]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/2008/07/18/atlanta-ga-phpworks-and-pyworks/</guid>
		<description><![CDATA[Marco Tabini &#38; Associates, publishers of PHP Architect and Python Magazine are bringing their php&#124;works conference back to Atlanta this fall, November 12th through 14th, 2008. This year, though, the conference has an added bonus: PyWorks, a conference devoted to Python. Registering for one conference allows you to attend both. Both conferences have an open [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://tiffanybbrown.com/images/uploads/2008/phpandpy.png" alt="" class="rightimg"/><br />
Marco Tabini &amp; Associates, publishers of <a href="http://www.phparch.com/">PHP Architect</a> and <a href="http://pymag.phparch.com/">Python Magazine</a> are bringing their <a href="http://phpworks.mtacon.com/" class="b">php|works</a> conference back to Atlanta this fall, <b class="event-date">November 12th through 14th, 2008</b>. </p>
<p>This year, though, the conference has an added bonus: <a href="http://pyworks.mtacon.com/" class="b">PyWorks</a>, a conference devoted to Python. Registering for one conference allows you to attend both. </p>
<p>Both conferences have an open call for papers, which ends July 25, 2008. Registration costs $599 (discounts are available).</p>
<p><a href="http://tiffanybbrown.com/tag/tech+events/feed/"><b>RSS:</b> Tech Events</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2008/07/18/atlanta-ga-phpworks-and-pyworks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debugging tip: &#8220;Disallowed Key Character&#8221; error in CodeIgniter</title>
		<link>http://tiffanybbrown.com/2008/05/06/debugging-tip-disallowed-key-character-error-in-codeigniter/</link>
		<comments>http://tiffanybbrown.com/2008/05/06/debugging-tip-disallowed-key-character-error-in-codeigniter/#comments</comments>
		<pubDate>Tue, 06 May 2008 21:24:17 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development & Programming]]></category>
		<category><![CDATA[carriage return]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[line breaks]]></category>
		<category><![CDATA[line feed]]></category>
		<category><![CDATA[whitespace]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/?p=1285</guid>
		<description><![CDATA[After 6 hours of massive anxiety, stress, near tears, one pound on my desk, and some hair pulling, I tracked down the source of a nagging Disallowed Key Character error that I received while using CodeIgniter: an extra line break. The line feed (LF) and carriage return (CR) characters (and their hex code equivalents (%0D [...]]]></description>
			<content:encoded><![CDATA[<p>After 6 hours of massive anxiety, stress, near tears, one pound on my desk, and some hair pulling, I tracked down the source of a nagging <strong>Disallowed Key Character</strong> error that I received while using <a href="http://www.codeigniter.com/">CodeIgniter</a>: <strong>an extra line break</strong>.</p>
<p>The line feed (LF) and carriage return (CR) characters (and their hex code equivalents (%0D and %0A) are forbidden in CodeIgniter&#8217;s framework. The hard part is tracking down exactly <em>where</em> that extra line break character lives.</p>
<p>In my case, there was an extra line of blank, barren, not-all-that-obvious white space at the very, very end of one of my controller files, just <em>after</em> the closing <code>?&gt;</code>. </p>
<h3>Related:</h3>
<ul>
<li><a href="http://tiffanybbrown.com/2005/02/15/php_header_error_messages/">PHP header error messages</a></li>
<li><a href="http://tiffanybbrown.com/2006/03/21/four_common_p_h_p_errors_and_what_they_mean/">Four common P H P errors and what they mean</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2008/05/06/debugging-tip-disallowed-key-character-error-in-codeigniter/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Turn text files into pull down menus</title>
		<link>http://tiffanybbrown.com/2008/02/26/turn-text-files-into-pull-down-menus/</link>
		<comments>http://tiffanybbrown.com/2008/02/26/turn-text-files-into-pull-down-menus/#comments</comments>
		<pubDate>Wed, 27 Feb 2008 02:16:43 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[drop down menu]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[pull down menu]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/2008/02/26/turn-text-files-into-pull-down-menus/</guid>
		<description><![CDATA[UPDATE: This could also be done with the foreach() construct, but here &#8212; on my set-up at least &#8212; the for loop is a teensy bit faster. I developed this PHP function for a project I&#8217;m working on. I&#8217;m posting it here in case I need it again, or in case you find it handy. [...]]]></description>
			<content:encoded><![CDATA[<p class="editors-note"><b>UPDATE:</b> This could also be done with the <code>foreach()</code> construct, but here &#8212; on my set-up at least &#8212; the <code>for</code> loop is a teensy bit faster.</p>
<p>I developed this PHP function for a project I&#8217;m working on. I&#8217;m posting it here in case I need it again, or in case you find it handy.</p>
<pre>
#Input text files must contain one item per line
function print_menu($txtfile_or_files){
	$args = func_get_args();
	$num_args = func_num_args();
	$input = array();

	for($i = 0; $i &lt; $num_args; $i++){
		// get contents of each text file specified
		$lines = file($args[$i]); 

		// get each line from each file an add to array
		for($j = 0; $j &lt; count($lines); $j++){
			array_push($input,$lines[$j]);
		}
	}
	// sort alphabetically
	sort($input,SORT_STRING);		

	for($i = 0; $i &lt; count($input); $i++){
		$value = str_replace(' ','_',strtolower(trim($input[$i])));
		echo '&lt;option value="'.$value.'"&gt;'.trim($input[$i])."&lt;/option&gt;\n";
	}
}
</pre>
<h3>Configuration and use</h3>
<p>The variable <code>$txtfile_or_files</code> should be a comma-separated list of paths to plain text files. This function accepts multiple arguments, in case you want to string multiple files into one menu.</p>
<p>Each text file should contain one item per line. For example:</p>
<pre>
Red
Blue
Orange
Green
</pre>
<p>Add another line or two of code if you need to indicate whether the form field value has already been selected.</p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2008/02/26/turn-text-files-into-pull-down-menus/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Damn &#8230; my VPS is being cracked</title>
		<link>http://tiffanybbrown.com/2007/11/07/damn-my-vps-is-being-cracked/</link>
		<comments>http://tiffanybbrown.com/2007/11/07/damn-my-vps-is-being-cracked/#comments</comments>
		<pubDate>Wed, 07 Nov 2007 19:35:06 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[cracking]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[web servers]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/2007/11/07/damn-my-vps-is-being-cracked/</guid>
		<description><![CDATA[UPDATE: What appears to have happened &#8230; Yeah, as I type this, I&#8217;m getting hit with an attack. I&#8217;m not precisely sure of the motive. I just know that there are two directories on my server that should not be there and the attack appears to be coming through a specific URL. It&#8217;s been happening [...]]]></description>
			<content:encoded><![CDATA[<p class="editors-note"><b>UPDATE:</b> <a href="http://tiffanybbrown.com/2007/11/09/wp-super-cache-v01-vulnerable-to-injection-vps-crack-update/">What appears to have happened &#8230;</a></p>
<p>Yeah, as I type this, I&#8217;m getting hit with an attack. I&#8217;m not precisely sure of the motive. I just know that there are two directories on my server that <em>should not be there</em> and the attack appears to be coming through a specific URL. It&#8217;s been happening for several days now<del datetime="2007-11-07T22:35:00+00:00">It just started today</del>, according to my server logs, and the attacker is <a href="http://78.90.51.85/html/safeon.txt">using</a> / <a href="http://78.90.51.85/html/test.txt">attempting to use</a> PHP functions that interact with the shell.</p>
<p>He was also able to grab a whole bunch of data about my server as you can see from the above-linked code. I have my suspicions about how it is getting through, but nothing I can prove just yet. I&#8217;m going to look into it and see what I can come up with. </p>
<p>In the meantime, I&#8217;m just going to ask nicely that he (assuming this is a guy) please, <em>please</em> stop, and don&#8217;t mess up any of my stuff while visiting.  </p>
<p>And please take steps to disable certain system-affecting functions in your php.ini file (if you have access). </p>
<p><strong>UPDATE:</strong> This crack appears to involve a <a href="http://www.ossec.net/wiki/index.php/ShellBOT">ShellBOT</a> as well.</p>
<p><strong>UPDATE 2:</strong> ShellBOTs are bad. Apparently they open a connection to an <a href="http://www.networksecurityarchive.org/html/Incidents/2004-10/msg00032.html">IRC server</a> allowing all kinds of nasty things to happen. So hoping nothing serious was compromised.</p>
<p><strong>UPDATE 3:</strong> Interesting to know: when working in the shell, your file name does <em>not</em> need to have the &#8216;proper&#8216; extension that it would on a web server in order to be executed. </p>
<p>Let&#8217;s say you have a plain text file named &#8216;hello.txt.&#8217; It contains one line: <code>&lt;?php echo 'hello world';?&gt;</code>. In order for this file to run as a web page, it would need to have a .php (or whatever is designated in your server configuration file). But as a shell script, it could have just about any name and still be executed by typing &#8216;php hello.txt&#8217; at the command line. </p>
<p>In this case, the attacker grabbed (or attempted to grab) a ShellBOT written in Perl from another server  (file name b.txt) and execute it by sending the &#8216;perl b.txt&#8217; after the wget command. </p>
<p><b>UPDATE 4:</b> I&#8217;m pretty sure my suspicions have been <a href="http://twitter.com/codepo8/statuses/396467782">confirmed</a>. It seems that at least <a href="http://twitter.com/factoryjoe/statuses/396472592">one other person</a> has had an issue with <a href="http://ocaoimh.ie/2007/11/05/wordpress-super-cache-01/">WP Super Cache</a> opening their server to attack. I suspected this early on, and deleted the plugin and its associated files. As an added measure, I disabled those functions that can execute system commands. So far, so good. I can&#8217;t say my server is now <em>secure</em>, but I&#8217;m hoping that hole has been filled. </p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2007/11/07/damn-my-vps-is-being-cracked/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Review: Learning PHP Data Objects by Dennis Popel</title>
		<link>http://tiffanybbrown.com/2007/10/23/review-learning-php-data-objects-by-dennis-popel/</link>
		<comments>http://tiffanybbrown.com/2007/10/23/review-learning-php-data-objects-by-dennis-popel/#comments</comments>
		<pubDate>Tue, 23 Oct 2007 05:01:56 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[pdo]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/2007/10/23/review-learning-php-data-objects-by-dennis-popel/</guid>
		<description><![CDATA[Packt Publishing graciously provided me with a copy of this book to review. PHP supports more than a dozen database setups, including the SQLite library bundled with PHP 5. That&#8217;s a lot of databases, and each one has its own connection syntax and server-specific functions. So what happens when you want to be able to [...]]]></description>
			<content:encoded><![CDATA[<p span class="editors-note">Packt Publishing graciously provided me with a copy of this book to review.</p>
<p><img src='http://tiffanybbrown.com/images/uploads/2007/10/learningpdo.jpg' alt='Learning P H P Data Objects' class="rightimg" /> PHP supports more than a dozen database setups, including the <a href="http://sqlite.org/">SQLite</a> library bundled with PHP 5. That&#8217;s a lot of databases, and each one has its own connection syntax and server-specific functions. </p>
<p>So what happens when you want to be able to swap one database for another? You turn to an abstraction library, such as <a href="http://php.net/pdo"><abbr title="PHP Data Objects">PDO</abbr></a>.
</p>
<p>In <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&#038;location=http%3A%2F%2Fwww.amazon.com%2FLearning-Data-Objects-Dennis-Poppel%2Fdp%2F1847192661%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1193074907%26sr%3D8-1&#038;tag=webinista-20&#038;linkCode=ur2&#038;camp=1789&#038;creative=9325" class="book title">Learning PHP Data Objects</a><img src="http://www.assoc-amazon.com/e/ir?t=webinista-20&amp;l=ur2&amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, Dennis Popel takes you through the process of building an application using <abbr class="say">PDO</abbr> with My<abbr class="say">SQL</abbr> and SQLite.</p>
<p>Aimed squarely at PHP developers who are new to <abbr class="say">PDO</abbr>, Popel covers how to make connections, handle errors, and use prepared statements with <abbr class="say">PDO</abbr>. He also discusses transactions, <a href="http://en.wikipedia.org/wiki/Model-view-controller"><abbr title="Model-View-Controller">MVC</abbr> development</a>, and the appropriateness of using PDO versus other abstraction libraries.</p>
<p>Where <span class="book title">Learning PHP Data Objects</span> shines,  however is in its code examples. They are easy to follow, and Popel smartly alerts readers to potential gotchas in developing the sample application.</p>
<p>The book assumes an understanding of <abbr title="Object-oriented P H P">OOPHP</abbr> &#8212; necessary because PDO is entirely object-oriented. To get the most out of it, you should be familiar with object-oriented principles and syntax. While Appendix A does give readers a quick overview of <abbr class="say">OOPHP</abbr>, for a more thorough treatment, you&#8217;ll need to look elsewhere.</p>
<p>It&#8217;s a solid, though not quite perfect book. For example, Popel only sort-of mentions a potentially huge gotcha: when you may need to specify a <a href="http://tiffanybbrown.com/2007/10/22/solution-for-cant-connect-to-local-mysql-server-through-socket-tmpmysqlsock-error-when-using-pdo/">unix_socket parameter</a> in the connection string. It&#8217;s a problem I think would be common enough and confusing enough to discuss and demonstrate. I also think Popel could have been a bit clearer about when and why to use <code>PDOStatement->closeCursor()</code>.</p>
<p>Those are minor quibbles however, easily solved by consulting the documentation or doing a Google search. Overall, this book is nice introduction to the whys and hows of using PDO to develop database driven applications.</p>
<div class="quickfacts">
<h3>Quick facts</h3>
<ul>
<li class="book title">Learning PHP Data Objects</li>
<li class="book author">By Dennis Popel</li>
<li class="book publisher"><a href="http://www.packtpub.com/">Packt Publishing</a></li>
<li class="book release">September 2007</li>
<li class="book price">$39.99</li>
<li>ISBN number: <span class="ISBN">978-1-847192-66-0</span></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2007/10/23/review-learning-php-data-objects-by-dennis-popel/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Solution for &#8220;Can&#8217;t connect to local MySQL server through socket &#8216;/tmp/mysql.sock&#8217;&#8221; error when using PDO</title>
		<link>http://tiffanybbrown.com/2007/10/22/solution-for-cant-connect-to-local-mysql-server-through-socket-tmpmysqlsock-error-when-using-pdo/</link>
		<comments>http://tiffanybbrown.com/2007/10/22/solution-for-cant-connect-to-local-mysql-server-through-socket-tmpmysqlsock-error-when-using-pdo/#comments</comments>
		<pubDate>Mon, 22 Oct 2007 14:54:34 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[pdo]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/2007/10/22/solution-for-cant-connect-to-local-mysql-server-through-socket-tmpmysqlsock-error-when-using-pdo/</guid>
		<description><![CDATA[If you&#8217;re trying to get up-and-running with PDO, you may experience a &#8220;Can&#8217;t connect to local MySQL server through socket &#8216;/tmp/mysql.sock&#8217;&#8221; error when trying to connect to your database, even if your php.ini and my.cnf files contain a different default socket path for MySQL. It&#8217;s counterintuitive to a degree, but it&#8217;s actually expected behavior. The [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re trying to get up-and-running with <abbr title="P H P Data Objects">PDO</abbr>, you may experience a &#8220;Can&#8217;t connect to local MySQL server through socket &#8216;/tmp/mysql.sock&#8217;&#8221; error when trying to connect to your database, even if your php.ini and my.cnf files contain a different default socket path for MySQL.</p>
<p>It&#8217;s counterintuitive to a degree, but it&#8217;s actually expected behavior. The good news is that <a href="http://osdir.com/ml/php.pecl.devel/2006-11/msg00019.html">the fix</a> is easy. Simply include the unix socket path in your connection string. </p>
<pre>
$connection = new PDO("mysql:host=localhost;dbname=test;unix_socket=/path/to/socket/found_in_php.ini_or_my.cnf",'username','password');
</pre>
<p><b>Related:</b> Notes from &#8220;<a href="http://tiffanybbrown.com/2006/06/16/nyphp-con-introduction-to-pdo/">Introduction to PDO</a>,&#8221; a talk by Ilia Alshanetsky at NYPHPCon 2006.</p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2007/10/22/solution-for-cant-connect-to-local-mysql-server-through-socket-tmpmysqlsock-error-when-using-pdo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

