Originally published on decentphp.dev — part of the Writing decent PHP course. View this lesson on the original site.
"Utility" usually means "I have not named this yet"
Words like helper, util, common, misc, manage, process, handle, and do show up when someone could not think of a better name and shipped the placeholder.
These words are not technically wrong, but they tell the reader nothing. They survive in the codebase because they are easy to type and hard to argue with in code review — and that is exactly why they keep accumulating.
This lesson is not about class suffixes (lesson 2.6 covered that). It is about the same vague language showing up everywhere: function names, file names, parameter names, package names, and even commit messages.
Before
Notice how often utility language turns up. Count the placeholder words: Helpers, Common, Utils, doStuff, process, handle, data, item, result. Nine words across one tiny class, and not one of them tells you what the code is for.
<?php
namespace App\Helpers;
class CommonUtils
{
public static function doStuff(array $data): array
{
return self::process($data);
}
public static function process(array $data): array
{
$result = [];
foreach ($data as $item) {
$result[] = self::handle($item);
}
return $result;
}
public static function handle(array $item): array
{
return [
'id' => $item['id'],
'value' => $item['v'] * 1.2,
];
}
}
Read the class top to bottom and try to answer:
- what is the namespace
Helpersfor? - what does
CommonUtilsown? - what does
doStuffdo? - what does
processmean here? - what does
handledo thatprocessdoes not? - what is
$dataactually a list of? - what is the
* 1.2rule?
Every word is doing the bare minimum. The class works, but it forces every reader to open the function bodies before they can reason about anything.
After
Same code, same behaviour, but every word commits to a meaning.
<?php
namespace App\Pricing;
final class VatInclusivePriceCalculator
{
private const VAT_MULTIPLIER = 1.2;
public function applyVatToProducts(array $products): array
{
return array_map([$this, 'applyVatToProduct'], $products);
}
private function applyVatToProduct(array $product): array
{
return [
'id' => $product['id'],
'price_in_pence' => (int) round($product['price_in_pence'] * self::VAT_MULTIPLIER),
];
}
}
Now every name carries information:
- the namespace says it is pricing code
- the class says it calculates VAT-inclusive prices
- the public method says it applies VAT to a list of products
- the private method says it applies VAT to a single product
- the constant says what
1.2means - the field name says the unit (
price_in_pence)
Why this version is better
- a new reader knows what the class does without opening any method
- the placeholder words have been replaced with words that explain a rule, not just an action
- the constant means the next reader can change the VAT rate in one named place
- the file path (
App\Pricing\...) reinforces what lives here
A vocabulary swap sheet
When you spot a vague word, here is the question to ask:
| Vague word | Better question | Likely better name |
|---|---|---|
Helper |
helps with what? | OrderTotalCalculator, EmailFormatter |
Util / Utils |
utility for what concept? | CurrencyConverter, DateRangeParser |
Common |
common to which features? | Shared\Money, Auth\SessionToken |
Misc |
miscellaneous to whom? | break it up; nothing should land here |
Manager |
manages what, in what way? | SubscriptionLifecycle, CacheInvalidator |
Process |
process means which steps? | chargeCustomer(), notifyCustomer() |
Handle |
handle what event or input? | onPaymentFailed(), validateSignupInput() |
Do |
do what action? | sendInvoice(), archiveOrder() |
Stuff |
stuff is never the answer | rename the parameter; see lesson 2.5 |
Data |
data of what? | $signupInput, $invoicePayload |
Info |
information about what? | $customerProfile, $orderSummary |
If the answer to the "better question" column is "actually, several different things", the unit (function or class) is doing too many jobs and the name is hiding it.
Where utility language hides
- Namespace and folder names —
App\Helpers,App\Common,src/utils/ - File names —
helpers.php,functions.php,common.php - Class names —
Manager,Helper,Utils,Processor - Method names —
process(),handle(),manage(),doX() - Parameter names —
$data,$item,$row,$thing - Variable names inside functions —
$result,$temp,$out - Commit messages — "misc fixes", "general cleanup", "various improvements"
- PR titles — "Refactor stuff", "Update helper", "Tidy up"
Each one looks small. Together they slowly rot the searchability of the project, because nobody can grep for "the place that does X" — every search returns dozens of hits in Helper, Utils, and Common.
A small vague-language smell test
When a name lands in your editor, ask:
- If I could only read the name, would I know what this is responsible for?
- Is the name something I would say out loud to a colleague? ("I changed the customer email validator" sounds normal; "I changed the helper" does not.)
- Could I describe the change in a commit message without using vague words like "stuff" or "general"?
If any answer is no, the name is acting as a placeholder — and placeholders almost never get replaced unless you replace them now.
From Writing decent PHP — Naming variables, functions, classes, and files well