<?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>T=Machine &#187; PHP</title>
	<atom:link href="http://t-machine.org/index.php/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://t-machine.org</link>
	<description>Internet Gaming, Computer Games, Technology, MMO, and Web 2.0</description>
	<lastBuildDate>Tue, 20 Jul 2010 09:43:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Now I remember why PHP is so easy to hate&#8230;</title>
		<link>http://t-machine.org/index.php/2009/06/02/php-include-once-require-once/</link>
		<comments>http://t-machine.org/index.php/2009/06/02/php-include-once-require-once/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 14:15:19 +0000</pubDate>
		<dc:creator>adam</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://t-machine.org/?p=568</guid>
		<description><![CDATA[(aka &#8220;why do my include/require/include_once/require_once files not work / seem NOT to be included, even though they are?&#8221;)
PHP has a mechanism for including files inside each other. The architects of PHP didn&#8217;t really think much about what they were doing with a lot of the core language features (witness the foolishness over Register Globals), and [...]]]></description>
			<content:encoded><![CDATA[<p>(aka &#8220;why do my include/require/include_once/require_once files not work / seem NOT to be included, even though they are?&#8221;)</p>
<p>PHP has a mechanism for including files inside each other. The architects of PHP didn&#8217;t really think much about what they were doing with a lot of the core language features (witness the foolishness over Register Globals), and file import/include/require is a classic example.</p>
<p>This is one of the most fundamental features of the language, and it&#8217;s screwed up. It &#8220;seems&#8221; to work, so long as you write simplistic enough / small enough apps. The bigger your app, the more likely it is you&#8217;ll discover how poor this part of the language is.<br />
<span id="more-568"></span><br />
In most languages, you have a distinction between</p>
<ol>
<li>importing (IMP)
<li>including (INC)
<li>internally-evaluating (INT)
<li>externally-evaluating (EXT)
</ol>
<p>(not all languages have all of the above &#8211; most have 2 or 3 of them)</p>
<p>The first one runs at the language-level, and is surrounded by all sorts of careful compiletime/runtime code to manage exactly what happens. The second one runs at the source-file-level, and simply &#8220;dumps&#8221; the contents of another file inside the main file.  The last two are like the second, except that they &#8220;executes&#8221; the other file, and whatever that &#8220;execution&#8221; process outputs is what gets embedded &#8211; rather than the contents of the file. They differ from each other in that one executes using all the currently-in-scope info, the other executes without any access to currently scoped data.</p>
<p>PHP says &#8220;**** it, I can&#8217;t be bothered with writing code properly, I&#8221;ll just pretend all four of those are identical, and I&#8217;ll name the functions as if I meant INC, even though I don&#8217;t&#8221;.</p>
<p>Net result: the include/require/include_once/require_once statements in PHP don&#8217;t really work properly, because they have to do the work BOTH of importing AND of including AND of evaluating &#8230; all in one go.</p>
<p>(by the way &#8230; this is <a href="http://uk.php.net/manual/en/function.include.php" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://uk.php.net/manual/en/function.include.php');">subtly documented in the fourth paragraph of the docs for include()</a>, but there&#8217;s no warning in the other statement/function docs)</p>
<p>Here&#8217;s the &#8220;compromises&#8221; that have been made (with the use-cases in brackets):</p>
<ul>
<li>Files are treated as plain HTML (INC)
<li>&#8230;but also, simultaneously, as &#8220;executable, may contain PHP tags&#8221; (EXT)
<li>When a file is brought in, it is only executed when that line of code is executed (INC, INT)
<li>The scope of anything executed is the scope of the currently-executing function (INT)
<li>Any (de facto) closures (in the form of defined functions) found inside the brought-in file &#8230; are shunted into the current environment (INC, IMP)
</ul>
<p>Several of those are clearly mutually incompatible already. It&#8217;s simply not possible to put all three of those features onto a single language-statement. Unfortunately &#8230; PHP has.</p>
<p>That&#8217;s just irritating &#8211; it means that basic PHP apps suddenly break when you add a line of code, because e.g. you&#8217;ve been using include() to do EXT, or IMP, and that was fine &#8230; but you just added some code that expose it&#8217;s incompatible behaviour by showing off some of its INT functionality (or vice versa).</p>
<p>But far worse is what happens when you throw &#8220;_once()&#8221; into the mix. In practical terms, it&#8217;s actually surprisingly easy to write code that doesn&#8217;t run correctly at runtime (and this is undocumented, too). Because &#8220;_once()&#8221; is, essentially, an undefined language feature.</p>
<p>Don&#8217;t believe me? <a href="http://uk.php.net/manual/en/function.include-once.php" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://uk.php.net/manual/en/function.include-once.php');">Go read the docs</a>. Find for me the point where they state the definition of:</p>
<blockquote><p>&#8220;if the code from a file has already been included&#8221;</p></blockquote>
<p>(or &#8230; don&#8217;t bother. Take my word for it &#8211; it&#8217;s not defined).</p>
<p>If IMP, INC, and EVAL were *not* squashed into some ugly mess like they are in PHP, this *would not be a problem*, because people would just work on the &#8220;obvious&#8221; interpretation of &#8220;has already been included&#8221;, i.e.:</p>
<blockquote><p>you called &#8220;include*()&#8221; or &#8220;require*()&#8221; on this filename already</p></blockquote>
<blockquote><p>you called &#8220;include*()&#8221; or &#8220;require*()&#8221; on this filename AT THIS SCOPE already</p></blockquote>
<p>What? TWO definitions? Well, yes, dear reader, because most humans will pick the first definition. It appears correct. And for IMP and EXT &#8211; by definition &#8211; it is correct, since they ignore scope. However, sadly, INC and INT explicitly require scope to be obeyed, and they *require* the second definition to be used.</p>
<p>Guess which definition PHP uses? Bearing in mind that PHP *treats the include() file differently* depending upon which scope it&#8217;s imported at&#8230;</p>
<p>Did you guess the second option? Ha! Wrong!</p>
<p>And so, in PHP, it&#8217;s easy to write something like this:</p>
<pre>
file 1:
if( !isset( $A) )
   $A = "not blank"

file 2:
run();
function run()
{
   require_once 'file 1';
   require_once 'file 3';
}

file 3:
crashout();
function crashout()
{
  require_once 'file 1';
  if( isset($A) )
    echo "this will never happen!";
  else
    echo "PHP will claim that A is not set, even though"
      . " it is explicit set in the file that is explicitly included above!";
}
</pre>
<p>I bashed my head against a wall with this (kind of) problem until I realised what was going on: PHP has a very poor definition of &#8220;a file has already been included&#8221;.</p>
<p>And what the heck can you do to workaround this? Actually, I&#8217;m not sure yet. I&#8217;ve only recently worked out how and why the runtime does what it does. I&#8217;ve not yet worked out a simple approach to PHP programming that avoids the above problems, beyond &#8220;never use an include* statement from within a function &#8211; never ever, under any circumstances&#8221;. At least that forces the behaviour to be predictable (NB: as soon as you do an include* from within a function, each and every one of your PHP scripts will potentially cease to work). But it&#8217;s very annoying to be actively prevented from ever doing an INC/INT/EXT.</p>
]]></content:encoded>
			<wfw:commentRss>http://t-machine.org/index.php/2009/06/02/php-include-once-require-once/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>PHP: Anti-spam CAPTCHA using photos</title>
		<link>http://t-machine.org/index.php/2009/04/05/php-anti-spam-captcha-using-photos/</link>
		<comments>http://t-machine.org/index.php/2009/04/05/php-anti-spam-captcha-using-photos/#comments</comments>
		<pubDate>Sun, 05 Apr 2009 12:19:05 +0000</pubDate>
		<dc:creator>adam</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://t-machine.org/?p=519</guid>
		<description><![CDATA[I&#8217;m just finishing up a quick PHP project at the moment, which allows anyone to register an account &#8211; so as the final step before launching it, I needed to add some form of CAPTCHA system. I tried a couple of 3rd party ones and source code ones and none quite worked for me. This [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m just finishing up a quick PHP project at the moment, which allows anyone to register an account &#8211; so as the final step before launching it, I needed to add some form of CAPTCHA system. I tried a couple of 3rd party ones and source code ones and none quite worked for me. This post gives full source for a simple user-friendly photo-based CAPTCHA in PHP. Use at your own risk &#8211; but it&#8217;s short and easy to integrate.</p>
<p>NB: this was more a quick-and-dirty practice exercise than a serious attempt at a CAPTCHA.  I don&#8217;t believe in CAPTCHAs, generally &#8211; but if you ARE going to use them, it&#8217;s best to have a lot of them in the wild, so it&#8217;s harder for crackers to do &#8220;crack once, spam everywhere&#8221;. See the section at the bottom for links to suggestions for other people&#8217;s CAPTCHAs that I reckon would be better for production use if you can get them to work :).<br />
<span id="more-519"></span><br />
Most CAPTCHAs are breakable in under 10 minutes. Personally, I can break nearly every single one I&#8217;ve seen (there are a few exceptions, but then you just start hiring bored students etc to mass-crack them for you, by hand). Every now and then I have a go with new ones to prove to myself they&#8217;re still easy to break. They generally are.</p>
<p>So, I know none of this is perfect, but I wanted a minimum of:</p>
<ol>
<li>Implemented in PHP
<li>Highly effective at preventing plain simple automated attacks based on command-line scripts that I could write in under 5 minutes
<li>Doesn&#8217;t upset the user / take a long time to process / too hard for humans
<li>Doesn&#8217;t look ugly
<li>Simple and quick to integrate with my app
<li>Doesn&#8217;t use any external libraries unless those libs are already available as Debian pre-compiled packages
</ol>
<p><a href="http://spiralout.org/blog/2008/06/10/anti-spam-human-checker-php-script/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://spiralout.org/blog/2008/06/10/anti-spam-human-checker-php-script/');">I found a simple idea based on asking humans to rate photos, from a guy called David Spiral</a>, which I rather liked. Nice ideas there. If you never shared this code with anyone, it might work. Unfortunately he&#8217;d made a beginner&#8217;s mistake and encoded the ID of the &#8220;correct&#8221; answer in the source code of the HTML page as a &#8220;hidden&#8221; HTML fom field. Ahem. That took about 5 seconds even for a moronic spammer to crack (HTML source based cracks are easy, and some crack tools / rootkits will even try to automatically (!) discover them for you).</p>
<p>Likewise, he&#8217;d implemented a secondary secret algorithm which identified all the images as being incorrect by having an even random ID, or correct by having an odd random ID. That took about 30 seconds to notice and crack without even reading the PHP source (although reading the source confirmed it immediately). Again, I believe there are multiple script kiddie tools that would automatically break this for you, as a spammer. They generally cost something like $20 each to license. A pittance.</p>
<p>After a couple of minutes of thinking and fiddling, I modified his code to replace those two freebies with  secrets that are meaningless to the client. The server can still do the one-way check of whether the user submitted the &#8220;correct&#8221; answer, but at least now the user has to guess it :).</p>
<p>I also made some minor cosmetic changes (e.g. drawing the images in a grid instead of a line, and making the images themselves clickable instead of having to hit the radio buttons).</p>
<p>David has peppered his source with &#8220;(c)Copyright&#8221; himself etc, which I am not a fan of for such a trivially small example, so I&#8217;ve re-implemented it from scratch, and here it is public domain. Do with it what you will.</p>
<p>(but, just to be clear, I do like David&#8217;s approach and code, and he did &#8211; as he promised &#8211; comment it nice and clearly. Thanks, David)</p>
<h4>Install / usage instructions</h4>
<ol>
<li>save these 4 PHP files somewhere
<li>edit &#8220;secure.php&#8221; and change the SALT to a random alphanumeric string of your choice (it doesn&#8217;t matter what it is so long as you don&#8217;t share it with other people)
<li>create a sub-directory called &#8220;folders&#8221; and put two images inside, named &#8220;cat.jpg&#8221; and &#8220;dog.jpg&#8221;
<li>run index.php to see the captcha in action
</ol>
<p>To use this in your own application, it ought to be very easy to see how you can &#8220;require_once&#8221; the index.php file into your own forms (personally I would rename it to something like &#8220;captcha-generator.php&#8221; once you&#8217;ve finished testing it, simply for convenience), and correspondingly insert the process.php (again, rename the file first) inside your form-processing script(s).</p>
<p>Suggestions for improvement:</p>
<ol>
<li>include a timestamp in the secret value so that the form cannot be captured and replayed infinitely
<ul>
<li>NB: at the moment this is a fatal flaw in the code &#8211; replay attacks are *another* built-in feature of the cracking  tools
</ul>
<li>change the image-fetch to instead grab randomized images from images.google.com using hard-coded search-terms
<ul>
<li>this has the benefit that it&#8217;s impossible to simply download all the images and save them for comparison/replay attacks &#8211; assuming you choose search terms that change frequently
<li>I&#8217;d prefer to use flickr tagstreams for this, but IIRC that kind of embedding might be against flickr terms of service
<li>&#8230;and surely someone else has already done this with flickr, but I couldn&#8217;t remember what the project was called. I found <a href="http://planetjoel.com/viewarticle/630/Flickr+Captcha+Using+PHP" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://planetjoel.com/viewarticle/630/Flickr+Captcha+Using+PHP');">this one at PlanetJoel</a>, but the site kept timing out when I tried to get it. (this broke one of my cardinal requirements: that the CAPTCHA be quick and easy for human users &#8211; but I might go with the planetjoel one anyway when I move my project to production)
</ul>
</ol>
<h4>PS&#8230;</h4>
<p>I&#8217;m very jetlagged right now. I might well have done something really stupid here that invalidates the whole purpose :). Really &#8230; check this for yourself, carefully, and think about what it&#8217;s doing and why!</p>
<blockquote><p>
FILE: index.php</p>
<pre>
&lt;?php
require_once "secure.php";

define('GRIDSIZE', 3);

$numimages = GRIDSIZE * GRIDSIZE;

$index = rand(1, $numimages);
$secret = hashSpecialImageNumber($index);

if( SALT == 'YOUDIDNTCHANGETHIS' )
{
	?&gt;
	&lt;h2&gt;ERROR: Install incomplete&lt;/h2&gt;
	&lt;P&gt;
	OK, you did something really stupid: you ignored the one-line install
	instructions, and tried to run this code with the core security part
	disabled
	&lt;/P&gt;
	&lt;P&gt;
	To save you from your own ignorance, I'm not going to let the code run
	until you do what you were supposed to, i.e. edit the secure.php file
	and change the value of SALT to some random string of numbers and letters
	&lt;/P&gt;
	&lt;P&gt;
	The current value is:
	&lt;/P&gt;
	&lt;blockquote&gt;
	&lt;?php echo SALT; ?&gt;
	&lt;/blockquote&gt;
	&lt;?php
}
else
{
echo "&lt;form name='captcha' method=\"POST\" action=\"process.php\"&gt;";

echo "&lt;table&gt;";
	for ($i = 1; $i &lt;= $numimages; $i++)
	{
		if( $i % GRIDSIZE == 1 )
		{
			echo "&lt;tr&gt;";
		}
		echo "&lt;td align=\"center\"&gt;";

		$iless = $i - 1;
		echo "&lt;img src=\"image.php?secret=${secret}&#038;n=$i\"";
		echo "onclick=\"document.forms['captcha'].selectedindex[$iless].checked=true\"&gt;";
		echo "&lt;br&gt;\n";
		echo "&lt;input type=\"radio\" name=\"selectedindex\" value=\"$i\" \&gt;\n";

		echo "&lt;/td&gt;";		

		if( $i % GRIDSIZE == 0 )
		{
			echo "&lt;/tr&gt;";
		}
	}

echo "&lt;/tr&gt;&lt;/table&gt;";

echo "&lt;input type=\"hidden\" name=\"secret\" value=\"".$secret."\" \&gt;";

echo "&lt;input type=\"submit\" \&gt;";

echo "&lt;/form&gt;";
}?&gt;
</pre>
</blockquote>
<blockquote><p>
FILE: secure.php</p>
<pre>
&lt;?php
define('SALT', 'YOUDIDNTCHANGETHIS' );
function hashSpecialImageNumber( $num )
{
	return md5( SALT . $num );
}

function checkSpecialImageNumber( $num, $hash )
{
	return md5( SALT . $num ) == $hash;
}
?&gt;
</pre>
</blockquote>
<blockquote><p>
FILE: image.php</p>
<pre>
&lt;?php
require_once "secure.php";

define('STANDARD_IMAGE','images/dog.jpg');	// modify as required to suit your own images
define('SPECIAL_IMAGE','images/cat.jpg');	// modify as required to suit your own images

header('Content-Type: image/jpg');

if( checkSpecialImageNumber($_GET['n'], $_GET['secret']) )
{
	exit( readfile( SPECIAL_IMAGE ) ); // quit processing after serving the Special image
}
else
{
	exit( readfile( STANDARD_IMAGE ) ); // quit processing after serving the Standard image
}
?&gt;
</pre>
</blockquote>
<blockquote><p>
FILE: process.php</p>
<pre>
&lt;?php
require_once "secure.php";

// Compare selected image with special image number to see if correct image was selected

$input = $_REQUEST['selectedindex']; // Number of image selected on form

$secret = $_REQUEST['secret']; // Obscured Number of special image from form

if( checkSpecialImageNumber($input, $secret) )
{
	// Your "Passed validation" code here

}
else
{
	echo "&lt;H1&gt;FAIL&lt;/H1&gt;";
	echo "input number = $input&lt;p&gt;";
	echo "special = $secret&lt;P&gt;";
	echo "hash = ".hashSpecialImageNumber( $input )."&lt;P&gt;";
	echo "checkSpecial = ". checkSpecialImageNumber( $input, $secret )."&lt;P&gt;";
}
?&gt;
</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://t-machine.org/index.php/2009/04/05/php-anti-spam-captcha-using-photos/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP: how to fetch all possible values of an ENUM from MySQL</title>
		<link>http://t-machine.org/index.php/2009/04/04/php-how-to-fetch-all-possible-values-of-an-enum-from-mysql/</link>
		<comments>http://t-machine.org/index.php/2009/04/04/php-how-to-fetch-all-possible-values-of-an-enum-from-mysql/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 19:19:08 +0000</pubDate>
		<dc:creator>adam</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://t-machine.org/?p=517</guid>
		<description><![CDATA[Sadly, the code snippets on MySQL&#8217;s main website for PHP are mostly untested and buggy (try running them &#8211; half of them don&#8217;t execute because of silly mistakes).
After much trial and error, here&#8217;s one that *actually works*:

// Missing feature (?) from MySQL: find the list of valid ENUM values for a given ENUM
// (actually, returns [...]]]></description>
			<content:encoded><![CDATA[<p>Sadly, the code snippets on MySQL&#8217;s main website for PHP are mostly untested and buggy (try running them &#8211; half of them don&#8217;t execute because of silly mistakes).</p>
<p>After much trial and error, here&#8217;s one that *actually works*:</p>
<blockquote>
<pre>// Missing feature (?) from MySQL: find the list of valid ENUM values for a given ENUM
// (actually, returns all the value-arrays for ALL the enum fields in a given table, by name)
// ---------------------------------------------------------
function fetchEnumValuesForTable( $tablename )
{
	global $db; // assuming you're using PEAR:DB here, and throughout (I use it, or MDB, exclusively)

	$enumresult = $db->query("SHOW COLUMNS FROM $tablename");

	// Makes arrays out of all ENUM type fields.
	// Uses the field names as array names and skips non-ENUM fields
	while( $enumrow = $enumresult->fetchRow() )
	{
		extract($enumrow);
		if (substr($Type, 0, 4) != 'enum') continue;

		$Type = str_replace('enum', 'array', $Type);

		// Add to array
		eval( '$tmp = '."$Type;" ); // I'm not sure why, but I had to do this
		// intermediate step to get it to work

		$results[$Field] = $tmp;
	}

	return $results; // returns an array mapping each enum's "column name"
	// to "array of elements valid fo that ENUM"
}
</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://t-machine.org/index.php/2009/04/04/php-how-to-fetch-all-possible-values-of-an-enum-from-mysql/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
