PHP Tips and Tricks: Array Lengths

This is a simple trick.  It makes the assumption that you manage your arrays properly, and in this case, you are using an array (or list), and not a dictionary.  Basically, a list that starts at 0 (though, the method can be adjust to fit other starting points).

Anyways, there are times I need to know if an array contains 15 elements.  I can quickly discover this like so:

if ( isset($array[14]) ) {

All this does is check to see if there is a value set for element 14.  Again, this makes the assumption that the interface you are calling returns what it says it will.  It should, and if it doesn’t, that’s a serious bug.

This also comes in handy if I only want to return a subset of the information, and need to find out if there is more information.  Let’s say I want to return as little information as possible via the API (I only want to return the first page of results), but I also want to know if there are more results (for pagination, let’s say).  I can then ask the API for 16 results, and then check if there are more results like so:

$isMore = isset($array[15]);

With this simple technique, I need only return 16 results.  I don’t need to do anything else fancy, just return 16 results, display 15 of them, and recognize that there are more results.

Finally, you can use this technique to ensure the length of a string.  So, lets say we want to enforce a minimum line length for passwords, we can enforce it like so.

$isPasswordLongEnough = isset($password[7]);

Obviously in all these cases, we have to be aware of off-by-one errors. For example, $password[7] checks for a password of at least 8 characters, not 7.

Injectors: Dependency Injection with Traits

With the release of PHP 5.4, Traits were added to our toolbox.  And, if I might be so bold, it’s one of the most exciting features I’ve seen come out of PHP in a long time.

Traits is a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way which reduces complexity, and avoids the typical problems associated with multiple inheritance and Mixins.

A Trait is similar to a class, but only intended to group functionality in a fine-grained and consistent way. It is not possible to instantiate a Trait on its own. It is an addition to traditional inheritance and enables horizontal composition of behavior; that is, the application of class members without requiring inheritance.

With this in mind, I knew when I first saw traits that it was the way to solve dependency injection.  Granted, when I say solve dependency injection, I’m mostly referring to the way dependency injection (or DI) is being solved in the current incarnations of PHP frameworks.  Basically, through the use of dependency injection containers (DIC).  Essentially, a dependency injection container stores objects, or the ability to create objects, in some “master” object or container.  I’m not going to spend too much time on what DI is, or what a DIC is.  Fabien Potencier has done an excellent job on the subject with is “What is Dependency Injection” series.

Anyways, let’s be clear about two things here:

  1. Dependency injection is good.
  2. Dependency injection containers solve a real problem.

However, the current incarnations of DICs have problems of their own.  First, let’s cover a problem with basic DI, and what DIC solves.

<?php

class User
{
  protected $record;
  public function __construct( $userId )
  {
    $db = new DB( );
    $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( );
  }
  // ....
}

$user = new User( 1 );

So, you might recognize this style of programming.  A User is created by passing a $userId to the constructor, whereby it calls the DB class to fetch a record.  What we’ve done here is couple the User class to the DB class.  This means we can’t ever create a User unless we have a DB available.  If we want to create a User from some other source, we can’t without a rewrite.  It also makes testing User difficult.  To test User, we also need to use DB, and make sure that is setup.

The first step to a solution is to inject the DB into the User class like so.

<?php

class User
{
  protected $record;
  public function __construct( $userId, DB $db )
  {
    $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( );
  }
  // ....
}

$user = new User( 1, new DB( ) );

Now, when we create the User class, we need to pass in the DB container.  That way, we can “inject” into the User class any data store we want.  In fact, we’d probably want to take this a a step further and instead of requiring a DB class, we wants to require an Interface of the DataStore type.

<?php

interface DataStore
{
  public function get( $source, $condition );
  public function limit( $limit );
  public function execute( );
}

class DB implements DataStore
{
  // implementation goes here
}

class User
{
  protected $record;
  public function __construct( $userId, DataStore $db )
  {
    $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( );
  }
  // ....
}

$user = new User( '1', new DB( ) );

Okay, so here we see the DataStore hsa been quickly drafted (it’s actually a fairly bad implementation, but serves for the examples).

This means if at some point, we want to create a User from some call to an API, can can inject that instead.

<?php

interface DataStore
{
public function get( $source, $condition );
public function limit( $limit );
public function execute( );
}

class DB implements DataStore
{
// implementation goes here
}

class API implements DataStore
{
// implementation goes here
}

class User
{
protected $record;
public function __construct( $userId, DataStore $db )
{
$this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( );
}
// ....
}

$user = new User( 1, new API( ) );

And that is dependency injection.  However, a problem occurs a your class starts needing more and more.

<?php

class User
{
  protected $record;
  public function __construct( $userId, DataStore $db, ISession $session, IConfig $config, ITracker $tracker, IMailer $mailer)
  {
    $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( );
    $session->start( $this->record->userid );
    $session->lifetime( $config->yes );
    // ...
  }
  // ....
}

Suddenly, you keep adding more and more to your constructor, and it takes on a whole new meaning.  Even worse off is that you might not need the Mailer unless you want to send the user a message.  This means unless you are sending a message, you are creating an object that won’t ever get used.  This also places a lot of work on the programmer using the User class.  Every time they want want to create a User object, they need to create all these classes.  Sure, you could only require the Mailer if the user is going to message someone, and require they use a setMailer( ) function, but that creates even more confusing.

Yeah, gets fairly confusing fast.

So, what do we do about that?

Dependency Injection Container

The idea with the DIC is that you can store your objects, or the generation of those objects in one central registry (generally an array) that can be called from anywhere.  In our example, it might look like this.

<?php

class User
{
  protected $record;
  public function __construct( $userId )
  {
    $db = Container::get('DB');
    $session = Container::get('Session', array('userId' => $userId));
    // ...
  }
}

new User( $id );

In this case, Container is simply that, a container of other objects.  We map the string ‘DB’ to a method, or some system that will return to us the DB class.  Actually, that’s not quite right.  Instead, it returns, in our example, a class that implements the DataStore interface.

In our Container, we can make what DB returns actually be anything we want.

This helps tremendously in testing, because we can setup DB to be something other than an actual DB class.  It can simply be a mock DataStore object setup just for testing.

This is where we currently stand with dependency injection containers in PHP.  They are, for better or worse, global arrays we pass around.  That isn’t so much a problem.  Rather, the problem is one of discovery.  Remember how I said containers like this map a string to an object?  That’s because that’s pretty much all it does.

I pass in DB, and I hope I get back an object like DB.  But where do I go to find out what exactly is happening?  Container::get isn’t actually generating the object.  That’s most likely abstracted out someplace else.  Another problem is knowing which values get will accept.  If I call Container::get(‘Cookie’), will that work as expected?  What about Container::get(‘Mailer’)?  What do these actually return?  Nothing enforces this, nothing is easily discoverable through straight PHP code.  And, frankly, I don’t know how you’d document this.

Container::get, at best, can tell you to pass it a string, and it will return, maybe, something.

It basically comes down to this:

$user = new GoogleTracker(  );

// versus

$user = Container::get(‘Tracker’);

In one case, you know exactly which object you are going to use.  In the other, you can only assume.  In the former, you can get to the code quickly.  In the latter, you cannot.

Don’t get me wrong, DI and a DIC solves a problem.  It’s just missing a crucial piece to complete it.

Traits to the Rescue

So now we come to traits.  Let’s start with a simple example.  In most applications, their exists a concept of configuration.

namespace Lib;

class Config
{
    protected $loadedConfigFile = null;

    protected $configName;

    /**
     * @param string $configFile Full path to config file
     */
    public function __construct( $configFile )
    {

        $this->configName = $configName;
    }

    /**
     * @return object
     */
    public function getConfig( )
    {
        if ( ! isset($this->loadedConfigFile) )
        {
            $this->loadFile();
        }

        return $this->loadedConfigFile;
    }

    /**
     * Loads the config file
     *
     * @return void
     */
    protected function loadFile( )
    {
        $this->loadedConfigFile = json_decode(file_get_contents($this->configName));
    }
}

Ignore the lack of error checking (please!), and let’s explore how we could use a trait to load this.  What we want is to enforce that the same config file is only loaded once.  That way, multiple calls to create Config will only ever have to load the file once.  So, our trait would look like this.

namespace LibInjector;

trait Config
{
   /**
    * @return LibConfig
    */
   public function getConfig( $configName )
   {
        $keyName = __TRAIT__ . $configName;

        if ( ! LibContainer::exists( $keyName ) )
        {
            LibContainer::set( $keyName, new LibConfig($configName) );
        }

        return LibContainer::get( $keyName );
    }
}

Here, the Config trait is created.  We’ve contained the loading code for a Config object in a single place, and that place is easily discovered.  Now, when we want to use the Config class, we can add it to a class like so.

You’ll note I placed the Config trait into the Injector namespace. I like to think of traits used in this manner as an injector – the trait allows you the program to easily inject other needed code into your code.

namespace Lib;

class User
{
    use InjectorConfig;

    function __construct()
    {
        $this->config = $this->getConfig( 'UserConfig.json' );
    }
}

But does this really abstract out the calling of the code?  Sure!

In this case, the trait Config’s getConfig method is fairly short, but that doesn’t mean it can’t expand to handle other cases.  If you want to replace LibConfig with AnotherLibConfig, it’s simply a matter of switching it out.  You can also have getConfig use both Config libraries, determining which one to use based not the $configName passed (let’s say, to handle an XML config file, and a JSON config file, and using two different libraries to handle that).

Injectors are also testable. Granted, you’ll have to Mock out the test Injectors, but I found that to be easy as well.  Again, you can do anything you like in the injector, so handling different test cases is trivial.

Using injectors also give you the benefit of an easy code path to follow.  After all, the class is explicitly using InjectorConfig, which is a specific trait, and easily discovered.  Most IDE’s will make this as easy as clicking on the name Config and it will take you right to the appropriate trait.  And there you see the creation code.

Also, you’ll note getConfig has been given the tag @return LibConfig.  This again provides for clear documentation, and IDE’s should return the proper type, allowing for better auto completion.

I’ve yet to find a case where using an injector has made things difficult or challenging.  And it’s wonderful to work with them.  If I’m in an object and need to include  a Config or Cache object, it’s as simple as adding a use statement at the top of the class and it’s available.

Injectors

I hope you find the use of Injectors interesting.  If you have any questions, let me know.  I’ll try to answer them.  This article has been sitting in my drafts file for far too long, and I need to get it out. So, I’m sure there are errors riddled throughout.  My apologies.  However, I hope the message gets across.  Try using Injectors, and let me know how they work out for you.  I’d love to hear it.

Someone thinks this is good

No.  How this is considered good, I don’t know.  Who wrote the code isn’t important – this is the way the code is supposed to be written.  At least, this is the way it’s being demonstrated.  With a straight face.

I cannot fathom how anyone can honestly think this is good and want to encourage its use.

<?php
return array(
// lots of config stuff here

            /**
             * Routes
             */

            'ZendMvcRouterRouteStack' => array(
                'parameters' => array(
                    'routes' => array(
                        'zfcuser' => array(
                            'type' => 'Literal',
                            'priority' => 1000,
                            'options' => array(
                                'route' => '/user',
                                'defaults' => array(
                                    'controller' => 'zfcuser',
                                    'action'     => 'index',
                                ),
                            ),
                            'may_terminate' => true,
                            'child_routes' => array(
                                'login' => array(
                                    'type' => 'Literal',
                                    'options' => array(
                                        'route' => '/login',
                                        'defaults' => array(
                                            'controller' => 'zfcuser',
                                            'action'     => 'login',
                                        ),
                                    ),
                                ),

// more config stuff here
);

Blocks

  1. Do one thing.
  2. Do it well.
  3. Keep it concise.
  4. Use only what is given.
Today we continue from Comments and explore how to refactor out code from blocks.  In Comments, we learned to extract code out into it’s own method whenever we use a comment to describe a block of code.  Today, we are going to look at how to do the same thing with blocks.
A block of code is any code that exists within a if, a loop, or a switch statement.  A good rule of thumb is every time you indent your code.  Our goal is to keep indents inside your code from going beyond 2 levels.  Let’s look at a typical method where we break this rule.
public function createAction()
{
    $adminForm = new Form_User();
    $adminForm->removeElement('dealership_id');

    if ($this->getRequest()->isPost()) {
        if ($adminForm->isValid($_POST)) {
            $mAdmin = new Application_Model_DbTable_Users();
            $result = $mAdmin->createAdmin(
                $adminForm->getValue('name'),
                $adminForm->getValue('email'),
                $adminForm->getValue('password'),
                $adminForm->getValue('role')
            );

            if ($adminForm->getValue('notify') === 'yes') {
                if ($adminForm->getValue('notifyPhone') === 'yes') {
                    $notification = new Application_Model_DbTable_PhoneNotification($mAdmin);
                } else {
                    $notification = new Application_Model_DbTable_Notification($mAdmin);
                }
                $notification->sendNotification();
            }

            if ($result)
                $this->_forward ('confirm');
        }
    }

    $adminForm->setAction('/admin/create');
    $adminForm->setMethod('post');
    $this->view->form = $adminForm;
}

Before we start refactoring this, I want to cover a couple things.  First, the above is a small example, but it can still be used to explain our need.  Secondly, what we learn here can be applied to code, regardless of the size or complexity.

Complexity

Before we set out on this road, we need to define complexity.  Specifically, I’m referring to Cyclomatic Complexity.  The best definition of Cyclomatic Complexity that I’ve found is from the PHPMD page on Cyclomatic Complexity.

Complexity is determined by the number of decision points in a method plus one for the method entry. The decision points are ‘if’, ‘while’, ‘for’, and ‘case labels’. Generally, 1-4 is low complexity, 5-7 indicates moderate complexity, 8-10 is high complexity, and 11+ is very high complexity.

Our goal is to keep what we write in the low complexity category.  At this point, we should go through the sample code from above, and figure out how much complexity there is.

public function createAction()  // Complexity 1
{
    $adminForm = new Form_User();
    $adminForm->removeElement('dealership_id');

    if ($this->getRequest()->isPost()) {  // Complexity 2
        if ($adminForm->isValid($_POST)) {  // Complexity 3
            $mAdmin = new Application_Model_DbTable_Users();
            $result = $mAdmin->createAdmin(
                $adminForm->getValue('name'),
                $adminForm->getValue('email'),
                $adminForm->getValue('password'),
                $adminForm->getValue('role')
            );

            if ($adminForm->getValue('notify') === 'yes') {  // Complexity 4
                if ($adminForm->getValue('notifyPhone') === 'yes') {  // Complexity 5
                    $notification = new Application_Model_DbTable_PhoneNotification($mAdmin);
                } else {  // Complexity 6
                    $notification = new Application_Model_DbTable_Notification($mAdmin);
                }
                $notification->sendNotification();
            }

            if ($result)  // Complexity 7
                $this->_forward ('confirm');
        }
    }

    $adminForm->setAction('/admin/create');
    $adminForm->setMethod('post');
    $this->view->form = $adminForm;
}

A total of 7 complexity, on the high end of moderate complexity.  You might be looking at this code and wondering what makes it so complex.  It is simple enough.  It’s built to handle a form.  It checks input, creates a new user if the form was submitted in a valid format, and sets up notifications that were obviously a choice in the form.  It finally forwards off to the confirmation.

But, that is actually a lot of complexity.  To test this function, we’d need at least 7 test cases.  Even more so, this method violates some of our rules.  Do one thing.  It does many.  It’s not concise.  And it’s also not just using what is given.

We are going to focus on the complexity portion today.  We are going to bring down the size of this method step by step.

Indents are intents to modularize

Every time you indent your code, you should be thinking about modularizing.  In other words, if you indent your code into a block, you should consider moving that code into it’s own method.

Let’s start with the extremely large if in the middle there.  The one that checks to see if the request is a post.  When we indent that block of code inside, we should ask ourselves if that code inside can be better moved to it’s own method.  The answer is a resounding yes.  Within that block of code, we have 5 levels of complexity.  By moving all that complexity out of the createAction method, we will help decrease the complexity of that single method.  More so, we make that method easier to read, and we are able to compartmentalize the code even more.  We make our code even more reusable.

Where with comments we used the comment as an indicator of a new method, here we use the ideated block of code as an indicator.

public function createAction() // Complexity 1
{
    $adminForm = new Form_User();
    $adminForm->removeElement('dealership_id');

    if ($this->getRequest()->isPost()) { // Complexity 2
        $this->letFormHandleInput($adminForm);
    }

    $adminForm->setAction('/admin/create');
    $adminForm->setMethod('post');
    $this->view->form = $adminForm;
}

protected function letFormHandleInput ($adminForm) // Complexity 1
{
    if ($adminForm->isValid($_POST)) { // Complexity 2

        $mAdmin = new Application_Model_DbTable_Users();
        $result = $mAdmin->createAdmin(
            $adminForm->getValue('name'),
            $adminForm->getValue('email'),
            $adminForm->getValue('password'),
            $adminForm->getValue('role')
        );

        if ($adminForm->getValue('notify') === 'yes') { // Complexity 3
            if ($adminForm->getValue('notifyPhone') === 'yes') { // Complexity 4
                $notification = new Application_Model_DbTable_PhoneNotification($mAdmin);
            } else { // Complexity 5
                $notification = new Application_Model_DbTable_Notification($mAdmin);
            }

            $notification->sendNotification();
        }

        if ($result) // Complexity 6
            $this->_forward('confirm');
    }
}

Referring back to createAction, we see that the complexity has dropped to a mere 2 points.  Granted, letFormHandleInput is 6 points, but we aren’t done yet.  Each method should be easy to understand, and easy to test.  createAction is now incredibly easy to understand.  It creates a new form for display, and if it receives a post request, it let’s the form handle the input.

I’ll admit, I’m not too enamoured with the name of the new method, but it’s simple, and defines exactly what the method does.  More importantly, we’re also passing the form in.  This means that we can pass this method any form.  If something fails, we come out of the method, and continue with the display of the form.  Normally, I’d want to also define letFormhandleInput as

protected function letFormHandleInput(Zend_Validate_Interface $adminForm, array $data)

Here, $adminForm would be explicit in what it is, and I’d pass in the $_POST data, rather than calling it.  In the method itself, I’d swap out the calls to $adminForm->getValue, and instead call directly from $data.  However, this goes beyond our discussion here.  However, I make mention of this because those simple changes are not only easy to make, but value in terms of maintainability, testing, and longevity.

Because letFormHandleInput is still complex, we need to extract some methods out from it as well.  letFormHandleInput is actually wrapped directly around a giant if.  A simple check to see if the $_POST data is valid.  After that point, everything is indented. It also happens that the form doesn’t do much after that.  We grab data from it, but as I noted above, that’s easily removed. Regardless, the sign is fairly clear: indented blocks are what we are looking for.

public function createAction() // Complexity 1
{
    $adminForm = new Form_User();

    $adminForm->removeElement('dealership_id');

    if ($this->getRequest()->isPost()) { // Complexity 2
      $this->validateNewUserDataInput($adminForm, $_POST);
    }

    $adminForm->setAction('/admin/create');
    $adminForm->setMethod('post');
    $this->view->form = $adminForm;
}

protected function validateNewUserDataInput (Zend_Validate_Interface $adminForm, $data)  // Complexity 1
{
    if ($adminForm->isValid($data)) { // Complexity 2
        $this->addNewUser($data);
    }
}

protected function addNewUser ($data)  // Complexity 1
{
    $mAdmin = new Application_Model_DbTable_Users();
    $result = $mAdmin->createAdmin(
        $data['name'],
        $data['email'],
        $data['password'],
        $data['role']
    );

    if ($data['notify'] === 'yes') {  // Complexity 2
        if ($data['notifyPhone'] === 'yes') {  // Complexity 3
            $notification = new Application_Model_DbTable_PhoneNotification($mAdmin);
        } else { // Complexity 4
            $notification = new Application_Model_DbTable_Notification($mAdmin);
        }

        $notification->sendNotification();
    }

    if ($result) // Complexity 5
        $this->_forward('confirm');
}

Once again, we’ve reduced complexity, and in our resulting method, our complexity has gone down.  As well, we’ve also remove the task of creating a new user to another method.  addNewUser does exactly that, it adds a new user and all it’s associate baggage.  I also took this time to better define what we needed, and what we didn’t.  You’ll see I’m pulling directly from $data now.  No need to pass $adminForm around.  Also, letFormHandleInput only requires a Zend_Validate_Interface object now, further decoupling ourselves.  I also took the liberty of renaming letFormHandleInput to validateNewUserDataInput.  This name better describes exactly what it does.  Granted, it also goes directly to creating a new user, but that’s something for another day.

Back on topic, lets take the next step, and refactor addNewUser in the same manner we’ve been.  Let’s see, we have another block of code.  This block sets up notifications.

protected function addNewUser ($data) // Complexity 1
{
    $mAdmin = new Application_Model_DbTable_Users();
    $result = $mAdmin->createAdmin(
        $data['name'],
        $data['email'],
        $data['password'],
        $data['role']
    );

    $this->setupNotificationsForUser($data, $mAdmin);

    if ($result) // Complexity 2
        $this->_forward('confirm');
}

protected function setupNotificationsForUser (array $data, Application_Model_DbTable_Users $mAdmin)  // Complexity 1
{
    if ($data['notify'] === 'yes') { // Complexity 2
        if ($data['notifyPhone'] === 'yes') { // Complexity 3
            $notification = new Application_Model_DbTable_PhoneNotification($mAdmin);
        } else { // Complexity 4
            $notification = new Application_Model_DbTable_Notification($mAdmin);
        }

        $notification->sendNotification();
    }
}

In this case, I just decided to encapsulate the entire notification code into it’s own method.  Here now, setupNotificaitonsForUser can be passed proper data, and from that, we can setup notifications for a users outside the creation of a new user.  This means when you write your code for editing a users notification preferences, you already have your notification setup.  Complexity is at 4, but that brings us to the low category of complexity.  There is one more thing we can do to simplify this code.  However, by this point, you should already see what we can do, and how it will simplify the code even further.

By extracting out the second if/else clause in setupNotificationsForUser, we abstract away the creation process.

All these methods can be applied to other forms of blocks of code.  Every case in a switch should probably have its own method.  Any loop should call out to a method.  At every level of complexity, you want to keep things as simple as possible.  When you read a block of code, it should be simple.  It should do something specific.  It should do is quickly, and it should do it well.

Comments

I once posted  “comments indicate future refactoring.” I want to reaffirm my belief in that, and clearly explain. In order to fully appreciate this, let’s lay down some fundamental beliefs. These are beliefs I have built on experience, and later, I’ll apply them to more general fundamental beliefs like SOLID, but for now, these are simple rules I feel are good to follow.

  1. Do one thing.
  2. Do it well.
  3. Keep it concise.
  4. Use only what is given.

These aren’t overly complex rules. In fact, they are pretty simple. We are going to aim to meet these rules in a rather simple manner: using comments.

Now, let’s define what type of comments I’m referring to. I’m not talking about DocBlock comments. These are comments that allow for parsing by specific tools and allow us to generate documents about the code.

I’m also not referring to comments that repeat the code.

// increment a by 1
$a++;

That is a poor comment, and should be removed. It does nothing except add to confusion.

The comments I’m referring to, however, are a bit more involved. But let’s start with an exercise.

Code should explain what it does. It doesn’t always do this. For example, what’s the purpose of the following code?

if ( preg_match(EMAIL_REGEX, $input) || 
     is_numeric($input) || 
     preg_match(USERNAME_REGEX, $input) ) { /* ... */ }

It’s easy to see what the code is doing, but not the purpose. If we add a comment, it will help matters.

// Check to see if the user input matches one of the searchable data sets
if ( preg_match(EMAIL_REGEX, $input) ||
     is_numeric($input) || 
     preg_match(USERNAME_REGEX, $input) ) { /* ... */ }

Hey! That helps. The code checks to see if the user input matches a pattern for searching a data set. Okay, that helps. But it’s still problematic. The comment isn’t clear. Is it referring to just the if-clause, or is it referring to the block inside the if-statement. Can you trust the comment? After all, as time progresses and code enters maintenance phase, things can and will change. Is it easy to read? It’s not difficult, but when you are read the comment, you then have to mentally associate that with the code. It takes extra effort. And for what? Saying something explicit.

Maybe it’s better that we ask a simple question: What is the comment trying to tell us?

If the input matches a searchable data set, run the blocked code.

Luckily, we can say that succinctly.

if ( $this->inputMatchesSearchableData( $input ) ) { /* ... */ }

// ...
function inputMatchesSearchableData ( $input )
{
    return preg_match(EMAIL_REGEX, $input) ||
           is_numeric($input) ||
           preg_match(USERNAME_REGEX, $input);
}

Using the extra method refactoring recipe, we’ve made our code much, much easier to read. inputMatchesSearchableData says exactly what the method does, and in our original block of code, it reads much easier than the comment did. We’ve also refactored the code that checks to see if the input is searchable. We’ve split responsibility, and suddenly, our original method does one less thing.

Every time I use a comment to explain what code is doing, I always ask myself if it’s code that should be removed. If what the code is doing isn’t directly related to the parent method, the answer is most likely yes.

Often times, the comment itself is a good indicator of the name of the function. Extract the method out, and keep each method small, precise, and simple.

Object Oriented Programming: Data Mapping

The What

Just because you use objects doesn’t mean you are programming in an object oriented manner.  A function like this defeats the purpose:

public function init()
{
    $user = new User();
    return $user;
}

It immediate creates a dependency.  Whatever object init() is in, we know it relies on User.  It also prevents us from testing init() without User.  User needs to be in place, and it needs to work.  If init() fails, we don’t know if it’s init() or User.

So why bring this up here and now?  It’s in response to a post on Forrst (which you can’t see because it’s probably behind a login wall).  I don’t mean to pick on the person posting the original thread.  It’s simple a case of not knowing.  Anyways, the follow up response to my reply included: “I guess we could also put the database code within the User class itself”.

The basic question revolved around creating a new User object.  Here were my suggestions.

My suggestions

Actually, no, you want to keep your DB code in a different object. You want a Data Mapper instead to actually send the Model into a DB object. Basically:

$user = new User("[email protected]","password");
$mapper = new UserMapper($user, new MapperStore());
$mapper->save();

Now, you could move that into User.

$user = new User();
$user->save();

You’d have save() accept two optional parameters.

public function save(Mapper $mapper = null, MapperStore $store = null)

Mapper and MapperStore are interfaces, of course. That way a user could send along a different Mapper if need be. I’ll get to why you might want to do this in a bit. Anyways, if $mapper wasn’t set, save would Reflect upon the class name (User) and grab the appropriate mapper: UserMapper, and use that.

MapperStore could default to a DB Connection, and essentially do the same thing, reflect upon the User class, and save the User information to the Database.

So, how does this all become useful?

$card = new Creditcard();
$card->save();

Simple enough. But let’s say you want to store certain information in a different location. Rather than change your Model, or your mapper, or your Store, you do this:

$card->save(new SafeCardMapper(), new FileStore());

So, your Model remains the same, and the mapper merely strips out information that shouldn’t be passed on to the storage object, in this case a FileStore.

Of course, you can set this stuff when you construct Creditcard as well, and it’s a fair argument to make. Personally, I like keeping the stuff close to where it’s being used. It means I can also do this:

$card->save();
$card->save(new SafeCardMapper(), new FileStore());

(Of course, even that smells bad to me, and I’d want to consider chaining mappers and stores together somehow so I could just call save() once. Maybe something like:)

function chainStorage(MapperStore $store, Mapper $mapper = null);
...
$card->chainStorage(new FileStore(), new SafeCardMapper());
$card->save(); // This would save both DB and SafeCard mappers

Anyways, once again, this probably goes above and beyond what you want. =)

Retrospect

Even still,chainStorage() and save() bug me.  I was branching from the OP’s original comment.  I’d much prefer to turn this around, something along the lines of a real Storage system.

$storage = new Storage(array(new FileStore(), new SafeCardMapper()), array(new DatabaseStore(), new CardMapper()));
$storage->store($card);

In this case, Storage simply accepts Store/Mapper pairs (or we could have a addStorage() method which accept both a storage and mapper.  Options are obvious.  Point is, You simply pass along what to store, Storage loads the Store, and uses the mapper to pull in the data.  Card doesn’t know it’s being stored.  Nothing changes.  Mapper would hand Card an updated ID if needed after the update.

Anyways, this is why they invented refactoring.

4JC.IN

4JC.IN is useless for anyone but me, but it’s still useful for me.  A simple tool, a weekend project, and a little exploratory on the web design side of things.  The point is to have ready my own HTML bootstrapping system.  With a quick call from the web directory, I can have everything I need downloaded and setup.  The command is short, and easy to remember.

curl 4jc.in/to | sh

Yes, I’m running a remote file from the shell.  Evil me!

Really though, it’s simple.  The name is meaningful in several ways, too.

  • JC.IN sounds like Jason.  Putting the 4 in front makes it “For Jason”
  • JC is JavaScript and CSS (the original meaning).  For JavaScript and CSS In To here.

I eventually plan on adding some additional things.  Zend Framework download and set up with some basic things I always include, other libraries I’ll pick up.  Font’s I like.  A basic template for HTML.  robots.txt, humans.txt, and privacy.txt files.

All sorts of little things.

In the grand scheme of the web, 4JC.IN doesn’t do anything for anyone.  It’s a tool for me to use.  But it was fun.  It is fun.  It’s a place to put the tools I use.  I may link them into git, so a quick command will fetch me the latest files and what not from a git repository.  I don’t know.  But it’s easy. And I like it.

PTI – PHP Tools Integration for Eclipse

I use Eclipse for my PHP coding.  One thing I love about Eclipse is the numerous plugins available.  The down side is you have to know about the plugins.  One plugin I find a must have on any Eclipse installation is  PTI – PHP Tool Integration.  You can find it on the Eclipse Marketplace in the Help Menu.  It has several components.  It allows you to run unit tests through PHPUnit from the editor with a click of the button.  It can do a CodeSniffer check and display the results in your editor so you can quickly and easily fix the problems.  It also include PHP Depend and PHP Copy/Paste Detector.  The system comes with all the stuff needed to run out the gate, but you can use your own versions of the various tools.