CakePHP follows the principle of "convention over configuration", which means it minimizes the amount of code and configuration you need by assuming logical, consistent naming conventions. One key convention is that database table names should be in the plural form. In CakePHP, database table naming follows a convention where plural table names (e.g., users) map to singular entity classes (e.g., User), and corresponding table classes (e.g., UsersTable).
For example:
| Element | Name |
| Table (DB) | Users |
| Model Class | User |
| Table Class | UsersTable |
| Controller | UsersController |
| Entity Class | User |
This convention helps CakePHP automatically determine the relationships between:
- Tables in the database
- Their corresponding Table classes (for database logic)
- Entity classes (representing single records)
By following the plural naming convention (e.g., users, articles, comments), you let CakePHP "just work" without needing to explicitly define table names or override defaults. However, what happens when you encounter irregular plural words like teeth or children? These don’t follow standard pluralization rules and can confuse the framework. Some English words have irregular plurals, such as:
| Singular | Plural |
| Tooth | Teeth |
| Child | Children |
| Person | People |
This tutorial will walk you through how to properly set up a table like teeth in CakePHP so it maps cleanly to a Tooth entity by following best practices.
Step 1: Create the Table
Create a table in your database called teeth:
CREATE TABLE teeth (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
created DATETIME,
modified DATETIME
);
Step 2: Create the Table and Entity Classes
TeethTable.php
Create the TeethTable class under src/Model/Table/.
// src/Model/Table/TeethTable.php
namespace App\Model\Table;
use Cake\ORM\Table;
class TeethTable extends Table
{
public function initialize(array $config): void
{
parent::initialize($config);
// Explicitly set the table and entity class
$this->setTable('teeth');
$this->setEntityClass('App\Model\Entity\Tooth');
}
}
Tooth.php
Create the Tooth entity class under src/Model/Entity/.
// src/Model/Entity/Tooth.php
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Tooth extends Entity
{
protected array $_accessible = [
'*' => true,
'id' => false,
];
}
Optional: Define Inflector Rules
CakePHP uses Inflector to guess plural/singular forms. By default, it doesn't know "tooth" ↔ "teeth". You can define it manually in config/bootstrap.php:
use Cake\Utility\Inflector;
Inflector::rules('plural', ['irregular' => ['tooth' => 'teeth']]);
Inflector::rules('singular', ['irregular' => ['teeth' => 'tooth']]);
This allows you to skip setTable() and setEntityClass() in TeethTable.php because CakePHP will now guess correctly.
Usage Example
In your controller or elsewhere, you can now do:
// In a controller
$tooth = $this->Teeth->newEmptyEntity();
$tooth->name = 'Upper Right Molar';
$this->Teeth->save($tooth);
CakePHP will know that:
- You’re inserting into the teeth table
- Each row is represented by a Tooth entity
| Element | Name |
| Table (DB) | teeth |
| Table Class | TeethTable |
| Entity Class | Tooth |
| Optional Inflection | tooth ↔ teeth |
This pattern keeps your domain language meaningful and your code clean, no weird names like teeths required.
While you can name your table teeths to “trick” CakePHP into guessing correctly, it's not semantically correct and may cause confusion later. Use Inflector::rules() or manual mapping for the best results.
That all, happy coding :)