Namespace trong PHP cho người mới bắt đầu
Giải thích namespace PHP từ số 0: vì sao cần, cách khai báo, use/alias, dấu backslash, PSR-4 autoload với Composer, và cách sửa lỗi Class not found thường gặp.
Namespace trong PHP cho người mới bắt đầu
Nếu bạn từng gặp lỗi
Class "App\Models\Post" not foundmà không hiểu vì sao, bài này dành cho bạn. Ta đi từ khái niệm → cú pháp → autoload → sửa lỗi.
1. Namespace là gì? Vì sao cần?
Hãy tưởng tượng namespace giống như thư mục cho tên class. Trong máy tính, bạn
có thể có hai file cùng tên bao_cao.docx miễn là chúng ở hai thư mục khác
nhau. Namespace làm điều tương tự cho code.
Vấn đề khi không có namespace:
// file cua ban
class User { /* ... */ }
// file cua thu vien ben thu ba
class User { /* ... */ } // ❌ Fatal error: Cannot redeclare class User
Hai class cùng tên User → PHP báo lỗi trùng. Namespace giải quyết chuyện này:
// App\Models\User va Vendor\Auth\User la HAI class khac nhau
Tóm lại: namespace giúp tránh trùng tên và tổ chức code theo nhóm.
2. Khai báo namespace
Dùng từ khóa namespace, và nó phải là câu lệnh PHP đầu tiên trong file
(chỉ được đứng sau <?php và comment):
<?php
namespace App\Models; // ✅ dong dau tien
class Post
{
// ...
}
Bây giờ tên đầy đủ (Fully Qualified Name) của class này là:
App\Models\Post.
⚠️ Lỗi hay gặp: đặt bất kỳ code nào (kể cả
echo) trướcnamespace→Fatal error: Namespace declaration statement has to be the very first statement.
3. Dùng class từ namespace khác: từ khóa use
Muốn dùng App\Models\Post ở một file khác, bạn import nó bằng use:
<?php
namespace App\Http\Controllers;
use App\Models\Post; // import 1 lan o dau file
class PostController
{
public function index()
{
$posts = Post::all(); // dung ten ngan, khong can go het duong dan
}
}
Không có use thì bạn phải viết tên đầy đủ mỗi lần:
$posts = \App\Models\Post::all(); // dai dong, de sai
4. Dấu \ (backslash) — điểm gây rối nhất
Backslash trong namespace giống dấu / trong đường dẫn file:
| Cách viết | Tên gọi | Ý nghĩa |
|---|---|---|
\App\Models\Post |
Fully qualified (có \ đầu) |
Tuyệt đối, tính từ gốc — luôn đúng |
App\Models\Post |
Qualified (không \ đầu) |
Tương đối, nối vào namespace hiện tại |
Post |
Unqualified | Chỉ tên class, cần use hoặc cùng namespace |
Ví dụ dễ dính bẫy:
namespace App\Http\Controllers;
// Khong co dau \ dau -> PHP hieu la App\Http\Controllers\App\Models\Post ❌
$p = new App\Models\Post();
// Dung: co use, hoac them \ dau
use App\Models\Post;
$p = new Post(); // ✅
$p = new \App\Models\Post(); // ✅ cung dung
📌 Quy tắc vàng: khi ở trong một namespace mà muốn trỏ tuyệt đối, thêm
\ở đầu — hoặc tốt hơn, cứuseở đầu file cho gọn.
5. Gọi hàm/class có sẵn của PHP (global namespace)
PHP đặt các hàm như strlen(), count(), class Exception, DateTime... ở
global namespace (namespace gốc). Khi bạn đang trong một namespace, PHP tự
tìm hàm ở global nếu không thấy ở namespace hiện tại — nên hàm thường vẫn chạy:
namespace App\Services;
$len = strlen('hello'); // ✅ PHP tu fallback ra global
Nhưng với class thì KHÔNG tự fallback — phải thêm \:
namespace App\Services;
throw new Exception('loi'); // ❌ tim App\Services\Exception
throw new \Exception('loi'); // ✅ class global
💡 Mẹo hiệu năng nhỏ: thêm
\trước hàm global (\strlen) giúp PHP khỏi phải dò namespace hiện tại trước. Không bắt buộc, nhưng nhiều dự án lớn làm vậy.
6. Đổi tên với alias (use ... as)
Khi hai class trùng tên ngắn, dùng as để đặt bí danh:
use App\Models\User;
use Vendor\Auth\User as AuthUser; // doi ten de khoi dung
$a = new User(); // App\Models\User
$b = new AuthUser(); // Vendor\Auth\User
Import nhiều class cùng nhóm (PHP 7+):
use App\Models\{Post, User, Comment};
7. use function và use const
Import cả hàm và hằng số từ namespace khác:
use function App\Helpers\format_money;
use const App\Config\MAX_ITEMS;
echo format_money(1000);
echo MAX_ITEMS;
8. Autoload PSR-4 — "phép màu" khiến class tự nạp
Đây là phần quan trọng nhất mà người mới hay bỏ qua.
Bạn có bao giờ thắc mắc: sao chỉ cần use App\Models\Post là dùng được, mà
không cần require/include file đó? Đó là nhờ autoload theo chuẩn
PSR-4 do Composer lo.
Quy tắc PSR-4 rất đơn giản: namespace ánh xạ (map) tới thư mục. Xem
composer.json của dự án Laravel này:
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
}
Nghĩa là:
| Namespace | Thư mục | Ví dụ |
|---|---|---|
App\ |
app/ |
App\Models\Post → app/Models/Post.php |
App\Http\Controllers\ |
app/Http/Controllers/ |
→ app/Http/Controllers/... |
Database\Seeders\ |
database/seeders/ |
Database\Seeders\PostSeeder → database/seeders/PostSeeder.php |
Công thức chuyển đổi:
App\Models\Post
│ │ └── ten class = ten file (Post.php)
│ └───────── thu muc con (Models/)
└────────────── prefix App\ = thu muc app/
=> app/Models/Post.php
Khi gặp new App\Models\Post(), Composer tự tính ra đường dẫn file rồi require
giúp bạn. Bạn không phải include tay bao giờ.
9. Ba quy tắc bắt buộc để autoload chạy
- Namespace phải khớp đường dẫn thư mục (theo map trong
composer.json). - Tên class phải trùng tên file (
Post↔Post.php) — kể cả hoa/thường. - Mỗi file chỉ chứa một class (khuyến nghị mạnh của PSR).
Ví dụ đúng:
// File: app/Services/PostService.php
<?php
namespace App\Services; // App\ = app/ -> App\Services = app/Services/
class PostService // trung ten file PostService.php
{
// ...
}
10. Sửa các lỗi thường gặp
❌ Class "App\Models\Post" not found
Lần lượt kiểm tra:
- File có đúng chỗ không?
App\Models\Post→ phải làapp/Models/Post.php. - Namespace trong file có đúng không? Dòng đầu phải là
namespace App\Models;— không phảiApp\Model(thiếu s) hayapp\models(sai hoa/thường). - Tên class có trùng tên file không?
class Post↔Post.php. - Đã nạp lại autoload chưa? Sau khi thêm file/đổi namespace, chạy:
composer dump-autoload
❌ Quên use
namespace App\Http\Controllers;
class PostController
{
public function index()
{
return Post::all(); // ❌ Post khong ton tai o namespace nay
}
}
Sửa: thêm use App\Models\Post; ở đầu file (dưới dòng namespace).
❌ Sai hoa/thường thư mục
Trên Windows máy bạn có thể chạy được (Windows không phân biệt hoa/thường), nhưng
lên server Linux (như hosting thật) sẽ lỗi. Luôn viết đúng:
app/Models/ chứ không phải app/models/.
❌ Namespace không khớp sau khi di chuyển file
Chuyển Post.php từ app/Models/ sang app/Entities/? Phải sửa dòng namespace
thành namespace App\Entities; và cập nhật mọi use App\Models\Post thành
use App\Entities\Post.
11. Thứ tự khai báo trong một file (chuẩn)
<?php // 1. mo the PHP
namespace App\Services; // 2. namespace (dau tien)
use App\Models\Post; // 3. cac use
use Illuminate\Support\Str;
class PostService // 4. class
{
// ...
}
12. Cheatsheet ghi nhớ nhanh
| Muốn làm | Cách viết |
|---|---|
| Khai báo namespace | namespace App\Models; (dòng đầu) |
| Import 1 class | use App\Models\Post; |
| Import nhiều class | use App\Models\{Post, User}; |
| Đổi tên tránh trùng | use ...\User as AuthUser; |
| Import hàm / hằng | use function ...; / use const ...; |
| Gọi class global trong namespace | thêm \: new \Exception() |
| Map namespace ↔ folder | khai trong composer.json → psr-4 |
| Sau khi thêm/sửa file | composer dump-autoload |
Kết
Chỉ cần nhớ ba ý cốt lõi:
- Namespace = "thư mục cho class", tránh trùng tên.
useđể gọi tên ngắn; thêm\khi cần trỏ tuyệt đối / class global.- PSR-4: namespace phải khớp đường dẫn, class khớp tên file — sai là
Class not found.
Nắm được namespace là bạn đã hiểu 80% cách một dự án PHP/Laravel tổ chức code.