Laravel 4 Mutators…The Name Doesn’t Matter

Quick Note: In this post I refer to both the Accessor and Mutator collectively as the “Mutators”. I know this is not technically “correct”, but I did it as to not confuse what most people think when they hear “Accessor”.

There was a change to the Laravel 4 Eloquent Mutators recently that some people do not like. The thing that changed was the prefix for the Mutator methods. So, instead of naming them getFoo and/or setFoo you name them giveFoo and takeFoo. Some people seemed to think that this would impact how they actually used their Models, which it does not. It actually makes it easier for you to write them.

What is an Eloquent Mutator?

So the Mutators are simply methods on your Model that you can define to modify the value of a field either before it is returned to you, or prior to being set. These methods are called automatically when you access or set the field as a property on the model (e.g. $user->settings).

Let’s take that settings for example. For this we will assume that settings is a field that holds a JSON encoded array of settings. Here is a basic User model with using Mutators to parse the settings:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class User extends Illuminate\Database\Eloquent\Model
{
    protected function giveSettings($settings)
    {
        return json_decode($settings);
    }

    protected function takeSettings($settings)
    {
        return json_encode($settings);
    }
}

Notice one important thing here, both methods are protected. This is because these methods should never be called from outside the scope of the Model. This is not required, but it is a good habit to get into. Now to access the settings you just do $user->settings.

Why not ‘get’ and ‘set’?

There are multiple reasons:

  1. Naming conflicts with the Eloquent core. There are methods such as getTable defined, which meant that you could never have a field named table, or it would fall over (well, return incorrect data in this simple case).
  2. You should be able to create your own getFoo and setFoo methods without having to worry about conflicting with anything (including future fields) or having to worry about the method prototype matching what Eloquent wants.

Number 1 could be fixed by just changing the Model methods to stop using the getFoo scheme, but that would cause people just as much “frustration”, if not more than changing the mutator naming.

Number 2 is the bigger issue.

Real World Example

Going to use one of the examples that @ben_corlett used, as it makes a lot of sense.

So, to make things nice and DI friendly (there are other reasons to do it as well), you can use Interfaces. So let’s define a simple one for a User.

1
2
3
4
5
<?php
interface UserInterface
{
    public function getName();
}

So here would be most people’s (including my own) first attempt at implementing the interface:

1
2
3
4
5
6
7
8
<?php
class User extends Illuminate\Database\Eloquent\Model implements UserInterface
{
    public function getName()
    {
        return $this->name;
    }
}

With the old mutator naming, this would be a mutator and cause an infinite loop. With the new naming, this is no longer a mutator and works as expected.

Conclusion

Are give and take the best prefixes? No. Are they horrible? No. Method naming is not a “one size fits all” type thing, some people will like them, and some people will hate them. This is one of those changes that everyone gets up in arms about, and then in a few days, your code will be changed and you will get back to making the awesome.

Here is a little anecdote that pertains to this: When I was creating FuelPHP, I changed all the factory methods in the entire framework to forge, and everyone freaked out. A week later, everyone got used to it and went back to writing code.

Lex 2.3

Lex 2.3 has just been released. This is the third version released today, two bug fixes and this minor release. This version changes the behaviour of Callback Tags slightly.

In 2.2 I attempted to make Callback Tags less greedy…this failed, miserably. It caused all sorts of unforeseen issues. So, I have rolled back those changes (for the most part).

Callback Tags are now greedy on purpose. As I explain in the README: “If a Callback Tag can be used in single or block form, then when using it in it’s singular form, it must be closed (just like HTML)”. This is exactly how HTML works. Consider you want to insert an empty paragraph, you can’t just do <p>, that would cause massive issues on the page. So instead you do <p></p>. Same concept in Lex now.

Now, I know this could get unwieldy very quickly. Take this contrived example:

1
2
3
4
5
{{ foo.bar.baz }}{{ /foo.bar.baz }}

{{ foo.bar.baz }}
    Content
{{ /foo.bar.baz }}

It isn’t too bad, but it is ugly and feels gross, and will get worse over time. But, have no fear, I have added the concept of Self Closing Callback Tags into 2.3.

This means you can self-close a Lex Callback Tag exactly as you would an HTML tag (e.g. <p />). So, our above example could be rewritten as follows:

1
2
3
4
5
{{ foo.bar.baz /}}

{{ foo.bar.baz }}
    Content
{{ /foo.bar.baz }}

You can use this concept any time your Callback Tag does not require any content.

Getting It

Update your Composer requirement to 2.3.*.

View on GitHub

Lex, PHP

A New Me in 2013

With 2013 coming up I have decided to do an overhaul of my online presence. This includes usernames/”handles”, as well as the content I put out there. I decided to do this for a two main reasons:

  1. I was bored with how things were.
  2. I felt I was not representing myself the way I wanted.

My online usernames have always been “dhorrigan” (well, since I have been over the age of 14 or so anyway). This is great, and I originally did it so that I would look “more professional” and be “taken more seriously”. Recently I have decided that my actions and words should portray those things…not my username. So with this thought in mind, I have changed (mostly) all of my usernames to DanDoesCode. It is a bit more fun and I like it better. I have also changed my URL to dandoescode.com and my Email to me@dandoescode.com.

I have always said what I thought, and that will not change. However, I will be doing it with a little more “tact” (I hate that word). I will do my best to refrain from calling people idiots, or just being negative in general. In the past, I have generally only tweeted about negative points about things. This has lead people to think that I am really negative, which I try not to be. I need to be pointing out the good in things as well, and not just spit out a bunch of hate torwards a certain project/subject.

Pertinent Changes

If you happen to link to me at all, please update the links accordingly. Here are the new ones:

Workers and Image Processing

A Litte Background

In my second week of working at Kapture, I was tasked with moving our image processing over to a worker process to help speed up the process. It wasn’t THAT slow, but we noticed certain scenarios which caused Kaptures to take longer than they should. We boiled it down to (mainly) the image processing.

So here is the basic flow of the way Kaptures USED to work so you can understand what is going on:

  1. The user takes a photo, enters the info and it starts to upload the photo via an API request, then waits for a response from the server.
  2. The API resizes it to the proper size.
  3. Inserts the photo into the Merchant’s Polaroid frame.
  4. Makes a thumbnail.
  5. Uploads the resulting image and thumbnail to S3.
  6. Enter the new Kapture info into the database.
  7. Send Response
  8. User continues with Redemption

As you can see, there is a lot going on there. This really isn’t bad most of the time, but sometimes it can get bogged down with the image resizing (if the server is under load), or S3 can be going a bit slow.

So, what to do? It is simple, offload it to a background process, right? Well, yes, that would work, however, that still adds load to the API server and slows down other requests. Our solution was to offload it to a worker process on a different server. We already had a workers server, so it was no big deal for us (not going into setting up the Queue and such).

Which Language?

We could write the worker in any language we wanted, so which did we choose? Python.

We did this for two main reasons:

  • Python is better than PHP for long running processes.
  • Python has the awesome PIL library for image manipulation.

Now that we have that sorted, let’s figure out how we want things to work.

What Should the End Result Be?

It is always a good idea to plan things out before you just go Cowboy Coding. Here is what we came up with:

  1. The user takes a photo, enters the info and the app sends the API the photo and other data, and waits for a response.
  2. Enter the new Kapture into the database.
  3. Send the photo (and some metadata) off to the Queue.
  4. Send Response
  5. User continues with Redemption

We took 3 huge steps out of the process. Now it is time to code.

Making it Work

Get it to the Queue

The first thing to figure out is how to send the user’s photo over to the worker. We use RabbitMQ for our Queue server, so we could just send the raw image data in the message we send the Queue. However, once you start to get into creating clusters of Queue servers, this will cause slow downs, and in some cases will cause some nodes in the cluster to incorrectly be taken out due to heartbeat timeouts (it is an Erlang thing).

We decided to shove the raw image data into our Redis server, then just send the Key along with our other data in the message. This is done fairly simply:

1
2
3
4
5
6
7
8
<?php
$redis = new Predis\Client(array(
    'host' => Config::get('redis.host'),
    'port' => Config::get('redis.port'),
    'database' => 4
));

$redis->set('photo:'.$image_name, file_get_contents($image_file));

Note: $image_name is guaranteed to be unique, so no chance of collisions here.

What’s next? Yup, we need to send the message to the Queue server so the worker can, well, get to work.

1
2
3
4
5
<?php
Rabbit::enque('image_proc', 'polaroid', [
    // Some other data you can't see :P
    'image_name'    => $image_name,
]);

Rabbit::enque is a class and method we have written to make sending stuff to our Queue easy. There are plenty of tutorials and code around to show you how to do this, so I won’t bore you with that. Just know that the first parameter is the Exchange name, and the second is the Queue name.

The Worker

For the worker, like I said earlier, we are using Python. The libraries we are using are as follows:

  • kombu - The AMQP Library
  • boto - S3 Stuff
  • PIL - Image Library
  • redis - Redis Library
  • requests - To make Requests to the API

I am not going to post our exact code (obviously), but here is the basic setup we have to subscribe to the Queue. This is a little more complicated than it needs to be because we will be adding more workers.

runner.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from kombu import Connection
from kombu.utils.debug import setup_logging
from workers import PolaroidWorker

setup_logging(loglevel='INFO')

# Here is where we get our configuration and do a few other things

# Create the connection to the Queue server.
# We use a with statement here so the connection is auto-closed
with Connection(hostname=config['host'],
                port=config['port'],
                userid=config['user'],
                password=config['pass'],
                virtual_host=config['vhost']) as conn:
    try:
        PolaroidWorker(conn, config).run()
    except KeyboardInterrupt:
        print('Exiting')

I have omitted the getting of our config for security purposes, but just know it is a JSON file that we grab and parse.

This file is pretty simple, it just makes a Connection to the Queue server, then creates a new PolaroidWorker (more below), and runs it.

queues.py

1
2
3
4
5
6
from kombu import Exchange, Queue

task_exchange = Exchange('image_proc', type='direct')
queues = {
    'polaroid': Queue('polaroid', task_exchange)
}

This file defines our Exchange and then a Dictionary of Queues. These are used later in our Workers.

workers.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from kombu.mixins import ConsumerMixin
from kombu.log import get_logger
from queues import queues

# S3 Stuff
from boto.s3.connection import S3Connection
from boto.s3.key import Key

# Everything else we need
import Image, cStringIO, os, redis, urllib

logger = get_logger(__name__)

class BaseWorker(ConsumerMixin):

    # The name of the queue that this worker consumes (see queues.py)
    worker_queue = None

    def __init__(self, connection, config):
        print "Worker Init"
        self.connection = connection
        self.config = config

    def get_consumers(self, Consumer, channel):
        return [Consumer(queues=queues[self.worker_queue],
                         callbacks=[self.process])]

class PolaroidWorker(BaseWorker):

    worker_queue = 'polaroid'

    def process(self, body, message):
        try:
            # This is where you process the message from the Queue
        except Exception, e:
            print "[%s] Processing Raised Exception: %s" % (body['id'], exc)
        # Acknowledge the message to the Queue
        message.ack()

So, things get a bit more complicated here. BaseWorker extends the ConsumerMixin which is provided by kombu to handle all of the “scaffolding” type things. get_consumers is called automatically when the worker starts up (part of the ConsumerMixin class). It returns an array of Consumers that will handle messages that this workers is supposed to consume. As you can see we send it the Queue we defined in the queues Dictionary we defined in queues.py, then set the callback to be the process method of the worker class.

Next, we define the worker where we actually get things done. All it defines is which worker_queue it is responsible for, then defines the process method. We put all the processing in a try/catch so that we can continue on, and just dump out the exception if there is one. Finally we acknowledge the message so that we don’t re-process it.

The Image Processing

There is a lot thet goes into this, and I can’t show you all of the code, but here is a little tid-bit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
orig_tmp_file = '/tmp/orig_' + body['image_name'] + '.png'
tmp_file = '/tmp/' + body['image_name'] + '.png'

# Open the Redis connection
r = redis.StrictRedis(host=self.config['redis-host'], port=self.config['redis-port'], db=4)

# Gets then Deletes the photo from Redis
raw_photo = r.get('photo:' + body['image_name'])
r.delete('photo:' + body['image_name'])

# Create a string buffer then open it as an image
# Note: cStringIO is much faster than StringIO, hence the usage
photo = Image.open(cStringIO.StringIO(raw_photo))

# Save the original so we can upload it later
photo.save(orig_tmp_file)

# Open the Polaroid Frame image, load it into PIL then close it.
f = urllib.urlopen(polaroid_url)
frame = Image.open(cStringIO.StringIO(f.read()))
f.close()

# Resize the image, and add the User Photo to the frame
# all in one go, then save it to the temp file
frame.paste(photo.resize((586, 497)), (13, 13))
frame.save(tmp_file)

# Get the images up to S3
framed_url = self.upload_image(s3_path_would_go_here, tmp_file)
image_url = self.upload_image(other_s3_path_would_go_here, orig_tmp_file)

# This is where we would send an API Request with all the info it needs to 
# update the records and such.

# Close the Redis connection, we don't want to leave open connections
r.connection_pool.disconnect()

# Delete the temp files
os.unlink(tmp_file)
os.unlink(orig_tmp_file)

# Some other stuff to free up memory and such that I won't bore you with

Note: Some of the variable names and other stuff has been changed.

It looks like a lot of code, but if you take out the comments, it isn’t bad.

Uploading to S3

In the above code we call self.upload_image, so here it is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def upload_image(self, key_path, file_path):
    """Uploads the given image to S3 at the given key Path."""

    # Connect to S3 if we haven't already
    if self.s3 == None:
        self.s3 = S3Connection(self.config['aws']['key'], self.config['aws']['secret'])

    # Get the S3 bucket
    bucket = self.s3.get_bucket(self.config['aws']['s3_bucket'])

    # Determine the Key (object) Path and create it
    k = Key(bucket, key_path)

    # Get a file pointer to the temp file then send it to S3
    image = open(file_path)
    k.set_contents_from_file(image)
    image.close()

    # Make the image public
    k.make_public()

    return url #We build the URL here, but I can't show you that.

Pretty simple right?

Did it Work?

Yes! Very well.

Lex 2.2 and a New Home

Lex 2.2 has just been released. Not much has changed, but a Minor version bump was required due to a backwards-incompatibility issue.

Changelog

  • Fixed a test which was PHP 5.4 only.
  • Added PHPUnit as a composer dev requirement.
  • Added a Lex\ParsingException class which is thrown when a parsing exception occurs.

The 3rd point is the one that caused the version bump. Before it would simply dump a message and then exit() (that was stupid).

New Home

Lex has been moved from the Fuel GitHub organization to the PyroCMS organization (https://github.com/pyrocms/lex). This was done because it was originally built for PyroCMS and it will be maintained by myself and the Pyro team.

With this change I have also re-named the Composer package to pyrocms/lex, so please update your composer.json files. If you try using the old one, it should tell you that it is replaced by the new one and to update your requirement.

As always if you run into issues go ahead and let me know via the Issue Tracker.

Lex, PHP

It Was Fun.

Many of you will have already known this was coming eventually. For the past 8 months or so I have been contributing to FuelPHP less and less (in-fact nothing anytime recently). Today, I am officially stepping away from the project.

Harro (@WanWizard) is, and has been, the project lead. I have full confidence in his abilities to take the project further than I ever could. I will be transfering everything (domain name, DNS, hosting accounts, etc) over to him over the next few days, so no worries about any of that.

This decision has nothing to do with the framework itself. I still believe it is, and will be, a great solution for a lot of people.

It was fun while it lasted, I just have to move on.

Is Eval Really Evil? Yes… And No.

How many times have you been told “Eval is Evil”? Probably a lot, and for good reason. The eval() function in PHP is dangerous in most situations. Why? Because executing arbitrary code can lead to very bad things. Let’s look at a real world example that I have seen used in the wild (not going to say which app…for reasons you will see).

The offending code looked something like this (class/variable names have been changed):

1
2
3
4
<?php
$method = $_GET['method'];
eval('$return = Foo::'.$method.'();');
?>

If you look at that code and say “What is wrong with that?”, then you may need to re-evaluate your career path, or read on and learn.

The above code was used to be able to call various methods (obviously). However, this is the worst possibly way to do this. It is very easy to exploit. All the user needs to do is find a valid method, then they can execute almost any code they want (let’s assume this was in index.php):

1
index.php?method=bar()%3B%24r%3Dmysql_query(%22select%20*%20from%20users%22)%3Bwhile(%24row%3Dmysql_fetch_assoc(%24r))var_dump(%24row)%3Bdie()%3B%2F%2F

If you decode that you will see that method is set to:

1
bar();$r=mysql_query("select * from users");while($row=mysql_fetch_assoc($r))var_dump($row);die();//

So when the original code is executed it will run the following:

1
2
3
<?php
eval('$return = Foo::bar();$r=mysql_query("select * from users");while($row=mysql_fetch_assoc($r))var_dump($row);die();//();');
?>

So, this will (assuming that mysql_connect() has been called and a DB selected) basically dump the entire users table to that user. I hope you can see why THAT is bad.

This is probably enough to turn you away from using it at all…which isn’t a bad thing. However, this is where I will get hate, there are times where you have no other option to use eval(), or the other options are equally as bad.

Wait, I can use eval()?

Well…sometimes, and only if you are very, VERY, careful. One of the only valid reasons I can think of to use eval() is Integration Tests.

The main reason that it is OK to use it when writing Integration Tests is because you control everything. You control the code being executed, and the environment in which it is executed. The tests deal with no end user data, so you don’t need to worry (unless you have some evil devs on your team) about arbitrary code execution.

A great example of this use is reading in tests from external files. These files can contain various data besides the code to execute to run the tests. So you read in the file, get the code that needs to be run and run it through eval() (you could also write the code out to a temp file, then include it, but it poses the same security risks, and adds unneeded load to the filesystem).

Ok, so only in tests?

Knowing when to use eval() is very simple. Ask yourself “Will this code run in production with user input?” If your answer is yes, then NO, you should not use eval()…ever (unless you REALLY know what you are doing and are REALLY sure the code being executed is safe).

Catching Syntax Errors in Eval

Since errors triggered in code ran inside eval() will not be caught by your error handler (set via set_error_handler()), you need to implement some trickery to catch PHP errors. This can be handy when you are using eval() to execute some test code.

Here is the full code sample for catching the errors:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
// We need to make sure we don't have any previous errors munging our results
@trigger_error('');
eval($code);
$error = error_get_last();

// If the message is empty, then we know it is from our error triggered above
if ($error['message'] !== '') {
    // Do whatever you want with the error...here we throw an ErrorException
    throw new ErrorException($error['message'], $error['type']);
}
?>

Ok, before you start hating on the code above, it is meant only for use during testing, so using the @ operator isn’t a big deal (c’mon, we are using eval() anyway). As you can see, there is not that much to it: Just trigger a blank error, execute the code, check to see if a new error was triggered.

I am using this in some Integration Tests I am writing for Lex for testing templates and such. I add a little more “magic” to add the correct line number in the test file that the error occured. This is possible because in the above code $error['line'] is equal to the line number of the evaluated code in which the error occured.

Haters Gonna Hate

I know I am going to get hate for this article, but that is OK. Most of you are probably going to hate just because you have heard the “Eval is Evil” line your entire career, so you have been brainwashed into thinking a certain way. Don’t hate on something just because it has a bad rep (goto anyone?).

PHP

Simple Syntax Highlighting for Tumblr

I was looking to add syntax highlighting to my blog here, and figured I would use the ever-handy (and simple) Google Code Prettifier,

It ended up being really simple, and I added a bit of JavaScript so I don’t have to manually write the <pre> tags and add the prettyprint class to code blocks. This is helpful when you are writing your posts in Markdown.

Two simple steps:

  1. Either upload the prettify.css and the prettify.js files to Tumblr and link to them, or you can link to them directly in their repository:
1
2
<link rel="stylesheet" type="text/css" href="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css" />
<script src="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js"></script>
  1. Insert the following code somewhere in your theme:
1
2
3
4
5
6
7
8
9
10
11
12
<script type="text/javascript">
    $(function() {
        var run = false;
        $("pre code").parent().each(function() {
            run = true;
            $(this).addClass('prettyprint');
        });
        if (run) {
            prettyPrint();
        }
    });
</script>

Note: Make sure you put the stylesheet link above your Theme’s CSS.

Note 2: This assumes you have jQuery already loaded.

JS

Anonymous Functions vs. Closures

Ever wonder what the difference between an Anonymous Function and a Closure is? What about a Lambda? How are they implemented in PHP? There seems to be a lot of confusion in this area, with people interchanging the words, and not really knowing what they mean, so lets dive in and answer these questions.

First things first: A “Lambda” is just another name for an Anonymous Function. You may have seen it used in some programming language (e.g. Python) and not known what it was…now you do.

Now that the easy stuff is out of the way, lets take a look at what these two things actually are. If you are confused at first, don’t worry, I will hopefully clear it up for you in a bit, these are just brief definitions of the two.

Anonymous Function - An Anonymous Function is a function that is defined, and occasionally invoked, without being bound to an identifier. It also has the variable scoping characteristics of a Closure (see below).

Closure - A Closure is a function that captures the current containing scope, then provides access to that scope when the Closure is invoked. The Closure binds non-local variable references to the corresponding variables in scope at the time the Closure is created.

From this we can derive: All Anonymous Functions are Closures, but not all Closures are Anonymous Functions.

Layman’s Terms

An Anonymous Function is a Closure without a name. A Closure is a function which binds references to non-local variables to local variables inside the function at the time of the Closure definition.

JavaScript Examples

Here a few examples written in JavaScript (I used JS here since most people have experience in using is):

Anonymous Function as Callback

1
2
3
4
5
6
7
8
9
10
function getPosts(callback) {
    // Code to fetch posts would go here...
    if (response.status == 200) {
        callback(response.body);
    }
}

getPosts(function (posts) {
    // Do something with the posts here
});

Closure as Return Value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function getProcessor(driver) {
    // Do some magic to load the processing driver here...

    // Imagine we set the driver variable to the
    // processing driver object here...

    return function (data) {
        // Notice we have access to the driver var. from the
        // getProcessor() scope.
        return driver.process(data);
    }
}

var proc = getProcessor('json');

console.log(proc(someJsonDataHere));

How about PHP?

Here is where things get interesting. In PHP 5.3, Closures and Anonymous Functions were added to the language. However, they have their quirks (one of which was fixed in PHP 5.4).

Anonymous Functions are implemented as Closure objects. PHP takes the idea that “Anonymous Functions are Closures without a name” to heart, because that is EXACTLY what they are.

Here is a simple Anonymous Function being sent to the array_map function to multiply all integers in an array by 2 (useless, I know, but hey, it is just an example):

1
2
3
4
5
<?php
$arr = array_map(function ($val) {
    return is_int($val) ? $val * 2 : $val;
}, $arr);
?>

Simple, right? Now ask yourself this: What if you want to access non-local variables in that function? After all Anonymous Functions are Closures too. Well, you can, but there is a catch: You have to explicitly tell PHP which variables it should use. That is the first of a few quirks, so let us dive into them.

Quirk #1

You MUST send the function all of the variables you want bound to the scope of the Closure using the use keyword. This is different from most other languages, where this is done automatically (like in my JS example above).

1
2
3
4
5
6
7
8
<?php
$foo = 'foo';
$bar = 'bar';

$baz = function () use ($foo, $bar) {
    echo $foo, $bar;
};
?>

Quirk #2

The bound variables are copies, of the variable, not references. If you want to be able to change the variable inside the Closure, you MUST send it by reference:

1
2
3
4
5
6
7
8
9
10
11
<?php
$foo = 'foo';
$bar = 'bar';

$baz = function () use (&$foo, &$bar) {
    $foo = 'Hello ';
    $bar = 'World!';
};
$baz();
echo $foo, $bar; // Outputs "Hello World!";
?>

Quirk #3

In PHP 5.3 if you are using a Closure inside of a class, the Closure will not have access to $this. You must send a reference to $this, however, you cannot send $this directly:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class Test
{
    protected $foo = 'foo';

    public function baz() {
        // Get a reference to $this
        $self = &$this;
        $func = function () use ($self) {
            echo $self->foo;
        }
    }
}
?>

Note: Because of the way object references are handled in PHP, you do not have to send a reference to $self if you wish to modify it.

PHP 5.4 to the Rescue

In PHP 5.4, they have added support for the usage of $this in Closures. They do this by binding the object to the Closure at the time of definition.

You can also change which object your Closure is bound to by using the bind() and bindTo() methods. You can read more about how to use these methods and exactly what they do in the PHP documentation.

So…

How should you know when to call it a Closure or Anonymous Function? Simple: You can always call it a Closure (because all Anonymous Functions are Closures), and if it doesn’t have a name, it is Anonymous. Pretty simple, right?

Hope that helped clear up the confusion. Feel free to leave questions in the comments, or I am always available on Twitter.

PHP

Lex Parser 2.0

After 4 months of no progress or changes to the Lex Parser, I decided it was time for a face lift. Although there aren’t many new features in 2.0, the things that have changed are big.

Changelog

  • PHP version requirement has been upped to 5.3
  • All code is now PSR-0, 1 and 2 compliant. (See here for more information on the standards.)
  • Lex is now a Composer Package (under the name fuel/lex).
  • The Lex GitHub repository has been moved under the fuelphp organization.
  • New and conditional tags have been added.

To learn how to install and use Lex using Composer, read the README.

As I stated in the changelog, the repository has been moved under the PyroCMS organization on GitHub. The URL is https://github.com/pyrocms/lex. This was done to centralize the code, as well as give it a broader audience to help come up with new features and spot bugs faster.