PHP Fractal Generator

I was bored so I thought I’d write a PHP script to generate fractals (like you do). The Mandlebrot set is probably the most well-known fractal so I chose to write a script to generate fractals using the Mandlebrot set:

This is a 500×500 fractal plotted for x (real) values between -1.5 and 0.5 and y (imaginary) values between -1 and 1.

How it Works

The mathematics behind the mandlebrot set involve:

  • complex numbers (x+yi)
  • quadratics
  • argand diagram
  • limits

A complex numbers consists of a real component and an imaginary component. i is the square root of -1. A complex number could look like 3+2i, where 3 is the real component and 2 is the imaginary component.

An argand diagram is like a two dimensional number line. With normal real numbers, we can plot them on a one dimension number line, with negative infinity on one end, and positive infinity on the other end. Because complex numbers have an imaginary component too, we need a two-dimensional plane to plot the number.

The Mandlebrot set involves iterating through a sequence:

In words: the first value in the sequence is 0. To find the next value in the sequence, we square the current value and add the complex number (which is the variable). Depending on the input, the sequence will either tend towards infinity or it will remain bounded and oscillate/repeat. If the sequence remains bounded, then it is inside the Mandlebrot set. On my script, I’ve marked these pixels as black.

For those values outside the Mandlebrot set, we use colour to denote how long it takes to reach infinity (in fact we use a shortcut and stop when |z| > 2).

Quadratics come in when we square a complex number – you can just square them as you would with any other quadratic. However, i^2 = -1.

Conclusion

I think it’s pretty amazing how we can generate infinitely complex patterns using such simple mathematics. There is probably only about 10 lines of mathematics in the script; the rest is all PHP/image stuff.

A few notes:

  • The script is pretty server intensive. The source code I’ve provided is configured to produce a 100×100 image by default. This took 2 minutes to execute on my machine, but 5 seconds on my friends machine. Both of them are roughly the same spec. Your mileage may vary.
  • If you try to generate an image with too many pixels, your PC may crash. You have been warned 🙂
  • Try changing the x/y min/max values to zoom or to pan.
  • Feel free to hack the script, rip it apart or do whatever you want with it. It’s public domain.

PHP 5.2

The guys at PHP are getting ready for a 5.2 release – the third major release in the 5.x range. A public release candidate has been released though I’m not sure if you can get binaries or where you can get them.

Given that it took a few months to reach this point and addition of new features was allowed the changelog already looks extremely impressive. Some of the key changes include things like 3 new extensions (filter, json and zip), the date extension had the rest of its functionality enabled, much work was done in terms of getting PHP 5.2 to run faster and more efficiently (in terms on memory usage). There have also been nearly 80 bug fixes made to existing functionality, which hopefully translates to a more stable release.

Filter functionality is really nice. There’s a bit of info on it on the PHP.net documentation; it gives a safe and quick way of getting user input. It does a similar job to PEAR::Validate and the Gene_Request class I use. Hopefully this will be turned on by default.

JSON support can be really useful. JSON is emerging as a new standard for data exchange between server and clients, often used with XmlHttpRequest. I’ve currently got my own code to convert a PHP object into a JSON object which is about 50 lines long but it’s not fantastic. JSON support could save a lot of time. Again, I hope this is turned on by default.

Other changes including the bundled MySQL client library being updated to v5.0.22, quite a lot of performance improvements, image_type_to_extension(), data: stream support, memory_get_peak_usage(), error_get_last() and many bug fixes.

addslashes() allows SQL injection attacks

Most PHP programmers have probably heard of SQL injection attacks – it’s when a hacker manipulates the SQL query sent to the database in a way the programmer does not expect.

For example you all too often find code like this in "PHP for Dummies" books:

mysql_query("SELECT * FROM username='$username'");

A programmer might expect $username to contain a string like "Weebl" and it’ll work fine. However, if a hacker manages to set the value of $username to something like "Weebl’ OR user_id=5" and it’d behave totally differently. Manipulated correctly, it could be used to steal confidential data or delete it.

The vast majority of people use addslashes() to prevent such attacks – this should make the string safe for input into an SQL query. However, the recommended way is mysql_real_escape_string(). Many people, myself included, use addslashes().

The Problem 

I came across an blog entry by Chris Shiflett today regarding the whole mysql_real_escape_string and addslashes debate. He provides an example of how you can successfully inject a single quote into a string which has addslashes() used on it which the database will treat as a single quote. 

Despite the use of addslashes(), I’m able to log in successfully without knowing a valid username or password. I can simply exploit the SQL injection vulnerability.

To avoid this type of vulnerability, use mysql_real_escape_string(), bound parameters, or any of the major database abstraction libraries.

I’m unsure what conditions you need to reproduce this issue (e.g. what databases it works with, whether tables need to be configured in a specific way, etc.) but it’s a good idea to switch your code to use mysql_real_escape_string.

You could also use prepared statements in a Database Abstraction Layer (MDB2, PDO or the built-in support in mysqli); these do a pretty good job of keeping you safe from SQL injection attacks. 

Gene_Template

With Geneone I decided to get rid of Smarty for several reasons:

  • I wanted to internationalize my script. Smarty could do it, but I’d end up with code such as {"Entry Title:"|tr}. This is fine but it quickly gets ugly.
  • I wanted to filter the output for HTML. At the moment I have been doing it in a hackish way by calling htmlentities() before it was passed to Smarty. This was pretty ugly and involved more work than neccessary.
  • I’m doing a lot of advanced things which outgrow the syntax of Smarty. I’ve had to use {$object|@makelink} when $object is an array/object and {$object|makelink} when $object is a string.
  • I was getting to the point where I’d have to create function in PHP then interface it with Smarty. It was easier to go skip that extra step. In PHP you can do all the familiar stuff such as substr($str, 0, 3) instead of {$str|substr:0:3}.
  • A lot of people don’t seem to like Smarty. Templates in PHP are good because it’s already familiar to all PHP programmers. Template designers are more likely to know PHP than Smarty. If they don’t, they may learn a bit of PHP and the fact they know a little bit might mean they would be more likely to contribute to the core code.
  • Smarty is LGPL. Eventually I want Geneone to become a fully BSD licensed package.

Smarty had actually suited me well for the last couple of years so it was sad to see it go. I looked at Savant which is probably the most well known templating system which uses PHP but I decided that it was too large and the LGPL license wasn’t BSD-compatible.

Savant has template plugins which I didn’t really see the point on. Instead, I simply define a function either at the top of the template or in the functions.php file. Instead of ~300KB for Smarty and ~40KB for Savant, Gene_Template is just over 3KB. The API has been modelled after Smarty so a lot of the code from Smarty doesn’t have to change.

The API looks a bit like this:

class Gene_Template {
    var $templateDir;
    var $templateVars = array();
   
    /**
     * Assigns a value to a template variable.
     *
     * @var string $name Variable Name
     * @var string $value Variable Value
     */
    function assign($name, $value) {}
   
    /**
     * Assigns a value to a template variable by reference.
     *
     * @var string $name Variable Name
     * @var string $value Variable Value
     */
    function assignRef($name, &$value) {}
   
    /**
     * Appends a value to a template array variable.
     *
     * @var string $name Variable Name
     * @var string $value Variable Value
     */
    function append($name, $value) {}
   
    /**
     * Appends a value to a template array variable by reference.
     *
     * @var string $name Variable Name
     * @var string $value Variable Value
     */
    function appendRef($name, $value) {}
   
    /**
     * Gets the value of a template variable.
     *
     * @var string $name Variable Name
     *
     * @return mixed Variable Value
     */
    function get($name) {}
   
    /**
     * Get an array of assigned template variables.
     *
     * @return array Assigned Variables
     */
    function getAssigned() {}
   
    /**
     * Fetches a template and returns the contents.
     *
     * @var string $templateName Template Name
     * @var string $variables Template Variables
     *
     * @return string Parsed Template Content
     */
    function fetch($templateName, $variables=array()) {}
   
    /**
     * Fetches a template and displays the contents.
     *
     * @var string $templateName Template Name
     * @var string $variables Template Variables
     */
    function display($templateName) {}
}

Templates change from Smarty syntax a bit like this:

{if $actions}<ul id="actionlinks">
{foreach from=$actions item=i}
    {if $i.2} {* Current Action *}
        <li class="currentact">{$i.1}</li>
    {else}
        <li><a href="{$curlbase}/{$i.0}">{$i.1}</a></li>
    {/if}
{/foreach}
</ul>{/if}

To PHP Syntax a bit like this:

<?php if ($actions): ?>
    <ul id="actionlinks">
    <?php foreach ($actions as $i): ?>
        <?php if ($i[2]): /* Current Action */?>
            <li class="currentact"><?php _e($i[1]) ?></li>
        <?php else: ?>
            <li><a href="<?php echo $curlbase ?>/<?php echo $i[0] ?>"><?php _e($i[1]) ?></a></li>
        <?php endif; ?>
    <?php endforeach; ?>
    </ul>
<?php endif; ?>

The Smarty syntax probably looks a bit cleaner and it’s a lot lazier to type but I hope things such as syntax highlighting and familiarity with PHP will counteract the benefits of Smarty. 

Savant

I finally decided to investigate Savant today, a "simple, elegant and powerful" alternative to Smarty.

Smarty is undoubtedly the king of PHP templating engines. It’s powerful, very flexible and can be quite beautiful. I’ve used some quite advanced features of Smarty. In Evolution we use Smarty to do callbacks from the forum code to Evolution code.

One of the features I’ve liked about Smarty is the ease and elegance of embedding parts of different templates. For example $object contains an array which is the current forum discussion. $childs contains all the posts. In Smarty you can do the following:

{$object.title}
{foreach from=$childs item=i}
{include file="showpost.tpl" object=$i}
{/foreach}

In showpost.tpl, you can then refer to $object. Sure you can do it in loads of other stuff, but I really like the elegant syntax you can use in Smarty. On the other hand, Smarty can force you to do ugly stuff like this:

{tagcloudsize tags=$terms assign="total"}

{foreach from=$terms item=i}
    {tagsize tag=$i total=$total assign="size"}
    {"<em>"|str_repeat:$size}

This is one example of a limitation and fugly code in Smarty. You need to implement a callback function which takes an "assign" argument and then use what is returned.

Harry Fuecks walks through some of the issues with Smarty. 

PHP is a bit more complex than basic Smarty but once you get into the more complicated stuff, PHP turns out to be a lot simpler. A lot more people can code PHP too. 

I’m actually not sure whether I should use Savant or just roll my own templating code as Savant doesn’t actually seem to do much and I’d like to get away from using LGPL/GPL software. Anyone had experience with alternative templating engines?

PHP 5 adoption statistics

Chris Shiflett has some statistics on the adoption of PHP 5 and other versions of PHP.

  • PHP 4.4.2 will become the dominant version during June 2006.
  • PHP 5.1.2 is now the dominant PHP 5 version.
  • PHP 5 rises to 8%, and raises its adoption speed again.
  • PHP 4.3.9 and older keep a marketshare of 46% this month.

There are tons of statistics and graphs on PHP usage and usage evolution on Nexen.

It seems like many people are jumping from PHP 4 straight to PHP 5.1.

Since PHP 5 adoption is getting a bit faster, it may not be long until it’s possible to use PHP 5 code in a mainstream script without worrying too much about compatibility with people on PHP 4.

The adoption of PHP 5 so far has been disappointing considering it’s been out for quite a while but I think it should be expected as many users had got used to PHP 4’s shortcomings and PHP 5 doesn’t really contain anything revolutionary.

PHP Interactive Mode

Python programmers will be familiar with Python’s interactive mode. This is really cool. It allows you to type a line of python code and Python will execute it straight away. It’s really nice for debugging and testing. It’s also cool if you want to play around with Python.

Python Interactive Shell 

Besides Python’s extensive library, this is probably my favourite feature of Python.

PHP has a similar feature but compared to Python’s version, it kinda sucks. You can access it by typing php -a at the command line.

PHP Shell

Now PHP has a more respectable interactive shell. You will need PHP 5 to use it.

This tool could be a real boon for PHP developers, especially those developers who want to take PHP to the extreme and onto command line/GTK scripting. 

PHP 5.1.3

How on earth did this bug make it into PHP 5.1.3?

Expected result:
----------------
Array
(
[masivasid] => Array
(
[id_1] => Nzzz1
[id_2] => Nzzz2
)

)

Actual result:
--------------
Array
(
[masivasid] => Array
(
[id_1] => Nzzz1
[id_2] => Array
(
[id_1] => Nzzz2
)

)

)

This should have broken more or less every single web application out there which uses forms.

Don't upgrade to 5.1.3; instead wait for 5.1.4. 

WTF: Client Side PHP

Some guy combined XmlHttpRequest or AJAX with PHP's eval() in a Web 2.0 fashion to create a real monster.

I think the code says it all:

function saveform()
{
var firstName = escapeSql(mainForm.elements.txtFirstName.value);
var lastName = escapeSql(mainForm.elements.txtLastName.value);
/* ... */
var offerCode = escapeSql(mainForm.elements.txtOfferCode.value);

var code =
' $cn = mssql_connect($DB_SERVER, $DB_USERNAME, $DB_PASSWORD) ' +
' or die("ERROR: Cannot Connect to $DB_SERVER"); ' +
' $db = mssql_select_db($DB_NAME, $cn); ' +
' ' +
' if (mssql_query("SELECT 1 FROM APPS WHERE SSN=\''+ssn+'\'", $cn)) ' +
' { $ins = false; } ' +
' else ' +
' { $ins = true; } ' +
' ' +
' if ($ins) { ' +
' $sql = "INSERT INTO APPS (FIRSTNM, LASTNM, ..., OFFERCD) VALUES ("; ' +
' $sql+= "\''+firstName+'\',"; ' +
' $sql+= "\''+lastName+'\',"; ' +
' $sql+= "\''+offerCode+'\')"; ' +
' ' +
' /* ... */ ' +
' ' +
' mssql_query($sql, $cn); ' +
' mssql_close($cn); ';

execPhp(code);
}

No doubt the escapeSql() function is most robust in stopping SQL injection attacks. 

PHP old_function

Cool! Didn't know about this PHP construct until today. It seems like you can define functions like this:

old_function sum $a, $b (
return($a + $b);
);

This is a remnant from the PHP/FI days.