When should I use camelCase / Camel Case or underscores in PHP naming?

Many people have many different preferences and for the most part they're often just that, preferences. Beyond it being what people are used to or that it's popular, there's rarely any rhyme of reason as to why the average person prefers a particular style. Unfortunately that tends not to give you any idea of why to use any particular convention when it comes to more practical matters.

Many people rely on PSR, which eases the task of having to establish conventions. In any development team conventions should be established to ease consistency. The PSR's can save some time versus doing it yourself. Although a useful start, you should not feel that PSR suggestions are authoritative. It's ultimately up to you how you write your PHP but if you are starting from scratch you should first investigate how others do it. That doesn't mean you have to do it the same way, but it's a start.

PSR has certain limitations:

  1. It is established by consensus rather than any particular science meaning that it tends to be inconsistent.
  2. It's not entirely thorough. You'll eventually find situations for which it doesn't specify any options.
  3. It was originally intended to improve compatibility between frameworks but it now includes include matters of taste rather than compatibility. In a great many cases which convention you use will have about as much impact on compatibility as which colour your socks are will have on them fitting your feet.
  4. Compatibility between frameworks tends to be of little or not significant concern for many if not most projects. Especially for closed source commercial projects.
  5. They are purely suggestions from an unofficial third party. Someone may prefer to stir their coffee counter clockwise and recommend that over the internet but in reality which direction you stir it is up to you or the team that you're on. Starbucks, Nero and Costa might release a joint statement recommending that you stir clockwise but you don't need to listen to them if you don't want to.

Putting that aside there are a couple of semantic and practical differences between camel case (camel) and snake case (snake).

The immediate difference is that camel uses a character less to separate words; it's more compact. This might not always be so if you convert your object to JSON and then compress it to send to the browser. Though in most cases the difference will be negligible, camel will in some cases compress more or less efficiently. You're not likely to have to worry about this. In general there a very trivial and insignificant performance differences across the board between the two.

Compactness comes with a price, both from a human perspective and a programmatic perspective. It can be more difficult to separate and work with terms. There's a reason we unzip our files to work on them before zipping them up again and although more subtle the same principle applies here, compact is harder. In a sense it's also lossy, that is the delimiter mutates the character. It's inconvenient as it doesn't always apply to the first character. You can't simply split and join by case. One of the reasons that's important is for dynamic access or meta coding where properties and methods might be determined automatically for example by assembling a set of tokens.

If I created a generator that would automatically create objects to represent tables in a database and to serve as a repository then I might generate methods on that class to be able to fetch by each column. I could be looking at either get_by_username|get_by_email or getByUsername|getByEmail.

If I had (get_by|getBy)($field, $value) then I would be passing username or email for the field, those are the original forms. In this case I have to ucfirst each field when creating the class. Taking this a step further what if I provide these dynamically through __call? In that case each time I need to convert the camel with at least lcfirst where as using snake case all I have to do is bolt it on to the end of the string, it maps one to one without transformation or worrying so much if it's at the end or the start. Consider mapping to two fields (such as operation and field) to a class member:

  • lcfirst if append or capitalized, split by case, map lcfirst to second onwards
  • split, map ucfirst to all if append otherwise to rest, concat

Versus:

  • split
  • join

Snake preserves the token in its original form by default and if not it tends to be easier to transform easily separated words individually.

It's very common to use meta coding in PHP to get the most out of it which would include a fair amount of string based runtime polymorphism. You're fairly likely to eventually encounter a case where you'll find more benefit with snake than camel where you want to code dynamically.

ifCamelCaseWereReallyThatGreatEveryoneWouldBeAnsweringProgrammingQuestionsOnStackOverFlowLikeThis. asYouCanSeeForAnythingButTheShortestPhrasesShortFormQuicklyBecomesTiring. youCanUsuallyGetAwayWithItInProgrammingAsItsInSmallDosesAndInASeaOfWhiteSpace. anotherAnnoyanceWithCamelCaseIsWhenYouHaveAbbreviationsOrSingleLetterWords. itNotAllGood.

Semantically people also tend to use snake to namespace and do not use it with phrases. Conversely camel tends to be used for small phrases or sentences that read in plain English sequentially or as a title. That's particularly common in OOP where the classname tends to offer the first and most commonly needed layer of categorisation and today tends to increasingly permit nested namespaces (fully supported in PHP). If you're doing something categorically, that is combining words from sets in different categories in order rather than combining words in English to create a phrase then the convention is to use snake. It's also more likely in that case what you'll find yourself doing meta coding.

For example database_statement_row_read_next() isn't entirely a valid or typical English phrase. Where as Database\Statement::readNextRow at the end becomes a valid and standard English expression.

Although English is more comfortable and familiar it has certain problems. Things aren't always in the same order or said the same way when they could be (it's inconsistent) which again might makes it more awkward with meta coding where it's natural to work with sets of words and to combine them without worrying about sometimes needing two instead of one word, order or words, turns of phrase, etc.

If you're writing out names to be fragments of plain English as a rule of thumb you should use camel primarily because that's overwhelmingly the convention used. If you don't strictly care about the order of the words matching up with the order they should be in in English but do care about categorisation and organisation then explicit delimiters tend to be the standard.

What they don't tell you about camel is that by convention you're nearly always expected to write it while also adhering to English grammatical rules which doesn't always workout as well as categorical naming in occasional circumstances.

More correct terms would be:

  • underscore delimited = alpha_beta
  • case delimited = alphaBeta
  • capitalised case delimited = AlphaBeta

In the last case the first upper case doesn't delimit.

In the programming world in general using case delimited (mixture of capitalised and uncapitalised) tends to be the standard for OOP. Generally speaking you would generally end up being more consistent sticking to that in PHP as well, especially for any OOP related names such a methods.

Conversely for procedural, functional and local variables there's a fairly strong tendency among popular languages for them to use snake.

Whatever you opt for try to be consistent as possible and where there are difference you should have both a reason and a convention for that. If you're mixing the two then you might put one behind a facade. Camel tends to be intended for human consumption and to be read as valid English where as snake if needed for meta coding might be something you can nest behind a facade.

Specifically for your proposals:

Variables / Properties:

  • userid will become hard to read and also end up creating other words. It also would not be possible to translate it to another standard format.
  • user_id is fine.
  • userId is fine
  • userID is bad. That it would translate to user_i_d rather than user_id.

Classes:

  • MyCustomClass is a universal and very consistent standard that also makes sense in that classnames are titles and should be capitalised.
  • myCustomClass Might make it look like someone put a method when they meant to put a classname.

Functions / Methods:

  • my_custom_function This is the simplest thing that could possible work (within reason) though out of the convention of not sticking to English grammar but English words using it to namespace you could just call it function_custom or function_default.
  • my_Custom_Function isn't the simplest thing that could possible work. The capitalisation is redundant and serves no purpose those it reveals a hidden benefit of dedicated character delimited, it can preserve case.

Some people might be lulled into using both to offer one or more level of nesting. What ever you to for that it'll end up ugly. It's the same concept as CSV within CSV or a two dimensional array. Both camel and snake are used to represent an array of single words. If you want to represent two arrays of words then you'll need something special such as a combination of the two or more than one delimiter which might include a multiple character delimiter. If you're in that situation it's very likely a case of YAGNI as in practice camel or snake on their own is nearly always enough. If you're going to mix them up that should be part of a strategy that's more than superficial and either documented or obvious.

A relevant example of this might be the get_by_username|get_by_email case. I might decide to always have [$operation, $field]. Both operation and field might need to be described with more than one word each. This might lead to using camel for both field and operation but snake to separate field and operation. That would give for example getBy_username, deleteBy_username or getBy_firstName. It's not beautiful but might be argued to serve a practical purpose. It's also somewhat common to start with snake to provide a namespace and then end with camel which is essentially what you get using OOP namespaces, classes and methods. It's not wrong to mix things up if for good reason but more often than not a mix of styles like this tends to instead be a bad code smell that leads you to an unflushed toilet.


Based on the framework we are using, it can be different. We should follow the naming convention that is followed by the framework we are using to develop application.

Each framework follow different naming convention. Example:

  • Zend does not permit underscores
  • Symfony also encourages camelCase
  • Wordpress encourages underscores and does not like camelCase
  • CodeIgniter also promotes underscores

So: Use whatever your framework uses or create your own naming convention.

But for the basic naming conventions for PHP developers, I have found this to use.

For Variable

We can use lower case underscore. Like

$first_name = "John";
$last_name = "Doe";

(most of the php developer and frameworks like LV uses this. Also wordpress use this naming convention to declare variable.)

For Constants

We can use ALL CAPS case. Like

define('DB_HOST', 'localhost'); 
define('DB_USER', 'db_user');

(most of the php developer and frameworks and CMS use this naming convention to declare php constant.)

For Class Name

We can use pascal case. Like

class UserDetails {
    // 
}

(PHP frameworks like LV use this convention and many php developer use this naming convention.)

For Function and Class Method Name

We can use camel case. Like

function getName() {
    // Do something
}

(PHP frameworks like LV use this convention and many php developer use this naming convention.)

Note: But wordpress follow lower case under_score to declare function.

function get_name() {
    // Do something
}

You can get more details here.


From the PSR basic coding standard (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md)

Class names MUST be declared in StudlyCaps (ie: PascalCase).

Class constants MUST be declared in all upper case with underscore separators.

Method names MUST be declared in camelCase.

This guide intentionally avoids any recommendation regarding the use of $StudlyCaps, $camelCase, or $under_score property names.

<?php
namespace Vendor\Model;

class Foo
{
    const VERSION = '1.0';
    const DATE_APPROVED = '2012-06-01';

    private $StudlyCapsProp = null;
    protected $camelCaseProp = null;
    public $under_score_prop = null;

    public function fooBar()
    {

    }
}