2 min read

Simple PHP Refactoring

Simple PHP Refactoring

Today I needed to write some code to grab a list of CC addresses from an email, and I thought showing the steps I took could make for an entertaining blog post.

I know everyone works differently and when I’m facing a coding challenge the first thing I do is try my best to just get it to work. I don’t care how the code looks or anything. The only goal is to make it work. Here is my first working attempt at solving the problem of grabbing the CC’s:

[code lang=text]
/**
*
* Returns an ​array of email addresses
* ['john@example.com', 'jane@example.org'];
*
*/
public function getCC()
{
if ($ccs = $this->getHeaderByKey('cc')) {
$adrListArray = imap_rfc822_parse_adrlist($ccs, null);
$ccs = [];
foreach ($adrListArray as $item) {
$ccs[] = $item->mailbox.'@'.$item->host;
}
return $ccs;
}
return false;
}
[/code]

This code is using PHP’s imap_* functions to first see if the CC header is set in the .eml file, then the imap_rfc822_parse_adrlist function to parse an email address string. This is useful to normalize​ the output of an email address list. The getHeaderByKey either returns the string of the header or false.

After I got it working the temporary variable was really annoying me, so I next refactored to the following:

[code lang=text]
public function getCC()
{
if ($ccs = $this->getHeaderByKey('cc')) {
$adrListArray = imap_rfc822_parse_adrlist($ccs, null);
return array_map(function($item){
return $item->mailbox.'@'.$item->host;
}, $adrListArray);
}
return false;
}
[/code]

That started feeling better, but I really don’t like that all that code nested inside the if.

[code lang=text]
public function getCC()
{
if (! $ccs = $this->getHeaderByKey('cc')) {
return false;
}

$adrListArray = imap_rfc822_parse_adrlist($ccs, null);
return array_map(function($item){
return $item->mailbox.'@'.$item->host;
}, $adrListArray);
}
[/code]

Now it feels cleaner to me and could be further simplified by removing the $adrListArray temporary variable:

[code lang=text]
public function getCC()
{
if (! $ccs = $this->getHeaderByKey('cc')) {
return false;
}

return array_map(function($item){
return $item->mailbox.'@'.$item->host;
}, imap_rfc822_parse_adrlist($ccs, null));
}
[/code]

Personally, I think it’s cleaner than what I had the start, but even now I’m not 100% happy with it. I don’t like the $ccs variable assignment in the if statement, I think the method name should be changed to better represent this returning an array of email addresses. It’s not a single CC.

I think it’s a fun exercise writing out why you made the improvements that you did and thinking through how to make your code readable. I know this is subjective, but I find the last example easier to grasp vs. ​the first. What do you think? Do you see any other improvements that could be made?