So, I’ve been giving some thought lately to this whole idea of using custom method names vs constants within a class to prevent typo errors when passing strings to a commonly used method name.

As an example, let’s talk about a simple example class for a module with options that can be set.  Many times you’d see this written one of two ways for the options.

The first example is probably the most common and simplest. We just use simple public methods that take a string and return the result. The advantage of this is that it’s clean and simple. There are many downside, but primarily, you don’t know if the string you passed is correct or not and you don’t have any autocomplete.


<?php

namespace WidgetFactoryModules;

class MyModule extends MyORM
{

/**
* Shared method to get the option value from the db
* @param string $option
* @return mixed
/
public function getOption($option) {
return $this->query(“SELECT value FROM module_option WHERE name = ?”, array($option));
}


/*

* Update the option value
* @param string $option
* @param mixed $value
* @return mixed
*/
public function setOption($option, $value) {
return $this->query(“UPDATE module_option SET value = ? WHERE name = ?”, array($value, $option));
}
}

Adding onto the last example you’ll notice that custom method names were added for each option passing the string param to the shared getter and setter methods. The advantages of this approach is that you don’t have to worry about mistyping strings with passing them as parameters and you’ll get to maintain autocomplete, allowing you to see all the options available. Not too bad, but a little cluttered in my opinion and harder to maintain.

        
<?php

namespace WidgetFactoryModules;

class MyModule extends MyORM
{

/**
* Shared method to get the option value from the db
* @param string $option
* @return mixed
/
private function getOption($option) {
return $this->query(“SELECT value FROM module_option WHERE name = ?”, array($option));
}


/*

* Update the option value
* @param string $option
* @param mixed $value
* @return mixed
/
private function setOption($option, $value) {
return $this->query(“UPDATE module_option SET value = ? WHERE name = ?”, array($value, $option));
}


/*

* Should we send emails with this module?
* @return mixed
/
public function getOptionSendEmails() {
return $this->getOption(“sendEmails”);
}


/*

* Update the sendEmails option
* @param mixed $value
* @return mixed
/
public function setOptionSendEmails($value) {
return $this->setOption(“sendEmails”);
}


/*

* Is sharing to social networks enabled by default?
* @return mixed
/
public function getOptionShareByDefault() {
return $this->getOption(“shareByDefault”);
}


/*

* Update the shareByDefault option
* @param mixed $value
* @return mixed
*/
public function setOptionShareByDefault($value) {
return $this->setOption(“shareByDefault”);
}
}

After giving this some more thought though, I was thinking about the power of constants to improve on this and came up with a bit of a hybrid, if you will.

        
<?php

namespace WidgetFactoryModules;

class MyModule extends MyORM
{

const SEND_EMAILS = "sendEmails";
const SHARE_BY_DEFAULT = "shareByDefault";


/**
 * Shared method to get the option value from the db
 * @param string $option
 * @return mixed
 */
public function getOption($option) {
    return $this-&gt;query("SELECT `value` FROM `module_option` WHERE `name` = ?", array($option));
}


/**
 * Update the option value
 * @param string $option
 * @param mixed $value
 * @return mixed
 */
public function setOption($option, $value) {
    return $this-&gt;query("UPDATE `module_option` SET `value` = ? WHERE `name` = ?", array($value, $option));
}

}

Something along these lines. This is obviously called with something like…

        
$myModule = new WidgetFactoryModulesMyModule;
echo $myModule->getOption($myModule::SEND_EMAILS); //sendEmails
        
    

Now, this is certainly not complete, you could put some checks in place within the class to ensure you’re getting a valid value, then throw an exception. You could also make the getOption method static and setup a constructor if necessary to instantiate the class. But overall, I quite like the idea. You’re able to keep a clean class, easy to maintain, and you still get autocomplete.

I’d love to hear other people’s thoughts on this topic. Let me know!