Archive for August, 2008

Fast server-side rejection of large image uploads using $_FILES

August 28, 2008

Discovered today you can report to a user if the file(s) he/she is uploading is too large without having to wait for the file to finish uploading by checking $_FILES – the $_FILES array for each form input of type “file” has an element called “error” which returns an error code without actually uploading the file if the file is larger than than upload_max_filesize in php.ini or $_POST[“MAX_FILE_SIZE”]. It can do this because a “Content-length” http header is sent to the server first, and the file itself is then sent in the body of the http request.

Here’s a very simple example.

The form:

<form enctype="multipart/form-data">
    <input type="hidden" name="MAX_FILE_SIZE" value="1048576" />
    <input type="file" name="image" />
    <input type="submit">
</form>

The php:

if ($_FILES["image"]["error"] == UPLOAD_ERR_FORM_SIZE)
{
    echo "file too big!";
}

Note that you shouldn’t just use MAX_FILE_SIZE as I’ve done above, you also need to set upload_max_filesize appropriately in php.ini

setAttribute not working for onclick in IE

August 8, 2008

You can’t use javascript setAttribute() to set an onclick event on a link in Internet Explorer, I’ve discovered. You have to use <element>.onclick = <something> instead.

See  here http://justinfrench.com/index.php?id=25 and here http://www.quirksmode.org/js/events_tradmod.html

Changing style.display using javascript not working in IE

August 8, 2008

I was using a fairly simple js script to show/hide a div. Worked fine in firefox, didn’t work at all in IE (and had the unexpected side-effect of hiding the link I wanted to click on to toggle the show/hide). The problem code is below:

<a href="#specialConditions" name="specialConditions"
onclick="toggleDisplay('specialConditions');"> Special conds</a>

<div id="specialConditions" style="display: none;">
    ...
</div>

The function toggleDisplay() just sets style.display=’none’ if it’s equal to ‘block’ and vice-versa.

The problem turned out to be the ‘name=”specialConditions”‘ in the link – IE seems to confuse names and IDs in getElementById(), so document.getElementById(‘specialConditions’) was returning the link instead of the div.

So I changed the value of “name” in the link and it worked fine:

<a href="#specialConditionsAnchor" name="specialConditionsAnchor"
onclick="toggleDisplay('specialConditions');"> Special conds</a>

<div id="specialConditions" style="display: none;">
    ...
</div>

Lazy loading of object variables in php using __get()

August 1, 2008

Was doing a(nother) shopping application lately. In the application each Product (a class) can have many images, but they’re not displayed in the search results page or the basket page, so it seemed a bit daft to be reading the database and loading them into memory in the constructor.

What I did instead was to use the magic method __get() to load the images into the object when they were needed. __get() is called whenever something tries to access a variable that is not set or publically accessible, so basically I used that to load the images whenever some other piece of code tried to access Product::images.

Here’s the actual code:

public function __get($var)
{
    eval("$this->_load".$var."();");
    $this->{"_load".$var}();
    return $this->$var;
}

So if some other piece of code made a Product object called $product and then tried to access $product->images and the images haven’t already been loaded, a (private) function called $product->_loadimages() is called. If the images HAVE already been loaded then __get() is not called.

Very handy.

One other thing I had to so was to unset() Product::images in the constructor, so that __get() would be called when something tried to access it. I could have avoided this by making $images private, but it behaves as a public property so I didn’t want to.