Log <-

Archive for the ‘php’ Category

RSS   RSS feed for this category

PHP Idiotic Function Contest

I'm holding a contest about who can find the most idiotic PHP function. Rules:

  • It has to be an official part of PHP (i.e. can be found in the manual).

Leave your suggestions in the comments.

I hereby nominate the runkit_constant_redefine() function. The manual entry says:

runkit_constant_redefine - Redefine an already defined constant

There is ABSOLUTELY NO EXCUSE WHATSOEVER FOR HAVING A FUNCTION LIKE THIS IN YOUR LANGUAGE! NONE!. The person who thought this up ought to be shot on sight.

If you disagree, or can provide a rational for why this function is included in PHP, DON'T BOTHER LEAVING A COMMENT BECAUSE YOU'RE WRONG!

There. I'm a little less frustrated now.

PHP MySQL tips

Interesting PHP MySQL tips.

Some comments:

2. Always prepend the table name to the field. E.g. ProductName, SupplierPostCode.

This refers to field name aliasing, not to actual field names. He doesn't suggest that you actually name your fields like that in the table, but only when you select them: SELECT product.name AS product_name instead of SELECT product.product_name. The only real reason I can think of why you'd want to do this is for easier selecting the values in the calling code. I don't see why it would make joins easier, as it's just as easy to type JOIN order ON order.product_id = product.id, IMHO.

3. Always create a primary id field with the name of the table followed by the id. e.g. ProductID

Two things I don't agree with. First, it's not always necessary to create a primary id field. You should only add an ID field if there's no unique key for that table. Second, I don't think prepending the tablename to the ID field is a good idea for primary id fields. It's not really bad either, but I like a plain 'product.id' field better, because you can instantly recognise the unique identifier field for that table. Foreign key fields, on the other hand, do feel better with their tablename prepended: order.product_id refers to product.id.

5. Use a separate logging table or transactions for logs of table updates, deletes etc.

We usually create a duplicate table for every table in the database, and name it 'tableHistory' or something like that. Then we add some metadata fields to the history table (time, user, mutationtype, etc) and place triggers on each table so that any mutation will insert the old row into the history table for that table, along with some metadata. That way, you always have a complete history of every mutation in your database. Great for auditing, plus you can create generic 'Last changed by foo on bar' functionality very easily.

PHP Namespaces committed

Gravitronic lets us know that a patch that implements namespaces in PHP has now been committed.

The last time I took a look at the roadmap for PHP6, it was still undecided if namespaces would make the cut. Seems like they have now (although they could still revert the commit, like they did with namespaces in PHP5 if I recall correctly).

The main idea of the proposal is to attack one target and this target only – the Super_Long_Really_Annoying_Enormous_Class_Names that lately became the bane of big project developer. All other things are considered secondary to this goal – no attempt to make some different include model, packaging model, etc.
Namespaces – can we keep it simple?

Some examples of how it currently works:

Defining namespaces

<?php 
namespace Zend::DB;
 
class Connection {
}
 
function connect() {
}

Referring by full namespace name

<?php
require 'Zend/Db/Connection.php';
$x = new Zend::DB::Connection;
Zend::DB::connect();
?>

Importing

<?php 
require 'Zend/Db/Connection.php';
import Zend::DB;
import Zend::DB::Connection as DbConnection;
$x = new Zend::DB::Connection();
$y = new DB::connection();
$z = new DbConnection();
DB::connect();
?>

Though I can't quite put my finger on it, it somehow still seems like a bolt-on to me. Ah well, better than nothing, right?

What'll PHP6 bring us?

CorePHP took the PHP 6 Developer Meeting notes minutes, which covers the discussion on the upcoming changes in PHP6, and made it into an nice summary article. Interesting stuff.

Looks like they'll be breaking a lot of stuff such as removing the dreaded 'Register Globals' option, Safe mode and Magic Quotes. Good.

This piece of the minutes intrigued me:

Issue: PHP only supports type hinted arguments and not for return values or properties.
I recently saw that PHP supports type hinted arguments, but it only supports objects and arrays, not strings, integers, etc. I understand that this may seem useless to support anyway since PHP is a loosly typed language and integers will just get converted to strings and the other way around. But from my experience it's still nice to do checking on parameter types; it catches a lot of programmer errors. Too bad strings and integers aren't going to be supported as type hinted arguments.

The other thing I'm disappointed about is that there doesn't seem to be any steering towards objectifying the primitive types such as string, integer and float. I like $foo = "bar:bas"; $foo->explode(':'); better than $foo = "bar:bas"; explode($foo, ':');. And if you'll look closely at the previous example, you'll know exactelly why. (hint: it has to do with argument order).

Oh well, I'll just wait for PHP7 I guess ;-)

PHP: Directly Assign Exploded Parts To Variables

Many languages (amongst them Python and Perl) provide a way to directly assign the parts of a split string to variables. The syntax usually used is something like:

firstname, lastname = "John,Doe".split(",");

or something similar. PHP does not support such a syntax. The programmer instead has to perform all spliting, checking and assigning himself.

This little snippet of code allows you to directly assign parts of an exploded string to variables or -if the exploding does not match the number of variables- assign defaults.

function explodeAssign($string, $seperator, $vars) {
    $temp = explode($seperator, $string);
    if (count($temp) != count($vars)) {
        return(false);
    } else {
        for ($i = 0; $i != count($temp); $i++) {
            $vars[$i] = $temp[$i];
        }
        return(true);
    }
}

$string is the string you want to explode.
$seperator is the seperator you want to use.
$vars is an array containing pass-by-reference variables. (this is important, otherwise it won't work)

Some examples:

if (!explodeAssign(
  "ferry,boender,25",
  ',',
  array(&amp;$firstname, &amp;$lastname, &amp;$age))) {
    $firstname = "John";
    $lastname = "Doe";
    $age = "20";
}
 
print("Hello $firstname $lastname. You are $age years old.n");
 
if (!explodeAssign(
  "ferry,boender",
  ',',
  array(&amp;$firstname, &amp;$lastname, &amp;$age))) {
    $firstname = "John";
    $lastname = "Doe";
    $age = "20";
}
 
print("Hello $firstname $lastname. You are $age years old.n");

The output of which will be:

Hello ferry boender. You are 25 years old.
Hello John Doe. You are 20 years old.

Hope it's useful.

Update: Not as useful as I thought, as PHP has a list() language construct:

list($firstname, $lastname, $age) = explode(",", "ferry,boender,25"));
print($firstname); // ferry

Ctags and Object Oriented PHP5

About CTags

Ctags is a great utility. It creates a file with a list of 'tags' that are found in various program sources that it finds in the directory where you run it. These tags can then be read by editors so that they know where in the source to find, for instance, the definitions of functions, methods, constants and variables. Or as the CTags homepage describes it:

Ctags generates an index (or tag) file of language objects found in source files that allows these items to be quickly and easily located by a text editor or other utility. A tag signifies a language object for which an index entry is available (or, alternatively, the index entry created for that object).
Editors like Vim use it to let you peek at or jump to the definition of a function; a feature commonly thought to only exist in bloated IDE's such as Eclipse.

PHP5 Object Oriented

Unfortunately, CTags doesn't support PHP's Object Oriented features very well. All you'll get is globally defined constants and functions. It also generates tags for classes, but that's it. No support for methods or anything! Hardly very useful in it's current form, I'd say. Thankfully there is a patch available that greatly extends CTags' Object Oriented PHP support.

Fixing CTags

To fix CTags so that it does support PHP in a not-completely-retarded fashion, you'll have to patch and compile CTags yourself. Here's how:

Download CTags v5.5.4.
Download the patch (alternatively and in case the patch disappears from the previous location, download it from electricmonk's mirror.

Next, patch, build and install CTags:

[todsah@jib]~/download$ tar -vxzf ctags-5.5.4.tar.gz
[todsah@jib]~/download$ patch ctags-5.5.4/php.c ctags-php5.patch
[todsah@jib]~/download$ cd ctags-5.5.4
[todsah@jib]~/download/ctags-5.5.4$ ./configure
[todsah@jib]~/download/ctags-5.5.4$ make
[todsah@jib]~/download/ctags-5.5.4$ sudo make install

The new ctags binary will be installed in /usr/local/bin by default.

Now you can use the self-built version of ctags to create tag files that contain enough information about your PHP's source code to actually do something meaningful:

[todsah@jib]~/plugwiki$ /usr/local/bin/ctags -R --extra=+q

Fire up your Vim editor (you are using Vim, aren't you?? Get off my site, you dirty Emacs user!) and start exploiting your newly created tags file.

Using ctags in Vim

In case you don't know how to use ctags from within Vim, don't worry. It's really easy. Move the cursor on top of some method call and press Ctrl-]. Vim will jump to the definition of the method/function/constant/whatever that the cursor was currently on. To jump back to where you came, press Ctrl-t. It's a simple as that.

An example. Suppose I have the following code:

if (!$page->hasAccess(

I'll position my cursor on hasAccess and press Ctrl-]. Vim will now jump to this text:

  public function hasAccess($user, $access)
  {
    $userId = $user->getUserId();

When I type Ctrl-t, Vim will jump back to:

if (!$page->hasAccess(

and I can complete my code.

Another cool tool for Vim that uses tags is TagList.

The "Tag List" plugin is a source code browser plugin for Vim and provides an overview of the structure of source code files and allows you to efficiently browse through source code files for different programming languages.
You can see TagList in action in this screenshot of Vim.

(Thanks to Michiel van Baak for corrections in this post.)

Learn your language's basic features

Sometimes I'd really like to bash in my own head with a 2×4. I just spent at least 20 minutes figuring out why the boolean expression

($options & PW_SORT_DATE == PW_SORT_DATE)

didn't evaluate to true, even though $options had a value of 2 and so did PW_SORT_DATE. Then I suddenly realised that PHP's == operator precedes the & operator.

(($options & PW_SORT_DATE) == PW_SORT_DATE)

works like a charm.

I should know better than not too learn the basics of the programming languages I work with. :)

RSS2MySQL v0.1

For a colleague of mine:

RSS2MySQL v0.1.

A Small script which reads in an RSS feed, takes the news items and then puts them in a MySQL database.

PHPBar: The PHP reference in a sidebar

PHPbar is a pretty nice sidebar for your browser which contains a quick reference for PHP.

PHP Cheat Sheet

Downloaded it today, and it's already indispensable:

PHP Cheat Sheet