Laravel vs Core PHP
Every PHP developer starts with Core PHP. You learn how variables work, how to connect to a database, how to handle form submissions. That foundation is valuable and necessary. But at some point, the question comes up: should I keep writing plain PHP or should I learn a framework like Laravel?
This lesson answers that question with real code comparisons — not opinions. You will see exactly how the same tasks look in Core PHP versus Laravel, and by the end, you will have a clear picture of when each approach makes sense.
What Is Core PHP?
Core PHP (also called plain PHP or vanilla PHP) means writing PHP without any framework. You handle everything yourself: folder structure, database connections, routing, security, and all application logic. There are no rules enforced by a framework — you are free to organize your code however you like.
This freedom is both an advantage and a disadvantage. For a quick five-line script, it is perfect. For a project with fifty pages, ten developers, and a database with twenty tables, it becomes a serious problem.
Side-by-Side Comparisons
The fastest way to understand the difference is to look at real code doing the same thing in both approaches.
1. Handling a URL Request (Routing)
Core PHP:
// You have to check the URL manually and include the right file
$url = $_SERVER['REQUEST_URI'];
if ($url === '/products') {
include 'pages/products.php';
} elseif ($url === '/about') {
include 'pages/about.php';
} elseif ($url === '/contact') {
include 'pages/contact.php';
} else {
include 'pages/404.php';
}
As routes grow, this becomes an unmaintainable chain of if/else blocks. There is no support for dynamic segments like /products/15 without additional string parsing logic.
Laravel:
// routes/web.php — clean, readable, handles dynamic segments automatically
Route::get('/products', [ProductController::class, 'index']);
Route::get('/products/{id}', [ProductController::class, 'show']);
Route::get('/about', [PageController::class, 'about']);
Route::get('/contact', [PageController::class, 'contact']);
Laravel's router handles dynamic URL segments, HTTP method validation, middleware, named routes, and route groups — all built in.
2. Connecting to and Querying a Database
Core PHP:
// Every file that needs the database has to establish a connection
$conn = mysqli_connect("localhost", "root", "", "myapp");
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
// Fetch a product — must write raw SQL every time
$id = $_GET['id'];
$stmt = mysqli_prepare($conn, "SELECT * FROM products WHERE id = ?");
mysqli_stmt_bind_param($stmt, "i", $id);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$product = mysqli_fetch_assoc($result);
echo $product['name'];
You write the connection setup repeatedly, manage prepared statements manually, and handle errors yourself every time. If your database credentials change, you update every file that connects.
Laravel:
// Connection is configured once in .env — never repeated in code // DB_HOST=localhost // DB_DATABASE=myapp // DB_USERNAME=root // Fetch a product — Eloquent handles the query, binding, and error handling $product = Product::findOrFail($id); echo $product->name;
One line. The connection is managed by Laravel. SQL injection protection is automatic. If the product does not exist, Laravel returns a proper 404 response automatically.
3. Inserting Data Safely
Core PHP:
// You must manually sanitize, prepare, bind, and execute
$name = $_POST['name'];
$price = $_POST['price'];
$status = $_POST['status'];
$stmt = mysqli_prepare($conn, "INSERT INTO products (name, price, status) VALUES (?, ?, ?)");
mysqli_stmt_bind_param($stmt, "sds", $name, $price, $status);
if (mysqli_stmt_execute($stmt)) {
echo "Product saved.";
} else {
echo "Error: " . mysqli_error($conn);
}
Laravel:
// Validation and insertion in a controller — clean and safe by default
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'price' => 'required|numeric|min:0',
'status' => 'required|in:active,inactive',
]);
Product::create($validated);
return redirect('/products')->with('success', 'Product saved.');
}
Laravel validates the input, rejects bad data with proper error messages, and inserts safely — all in a few readable lines. The create() method uses mass assignment protection to prevent unwanted fields from being inserted.
4. Building a Login System
Core PHP:
// login.php — you build this entirely from scratch
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'];
$password = $_POST['password'];
$conn = mysqli_connect("localhost", "root", "", "myapp");
$stmt = mysqli_prepare($conn, "SELECT * FROM users WHERE email = ?");
mysqli_stmt_bind_param($stmt, "s", $email);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$user = mysqli_fetch_assoc($result);
if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['user_name'] = $user['name'];
header('Location: /dashboard.php');
exit;
} else {
$error = "Invalid email or password.";
}
}
This is around 20 lines just for the login check — and it does not include the registration page, password reset flow, remember me functionality, or email verification. Building all of that in Core PHP is several days of work.
Laravel:
# Install Laravel Breeze — complete auth system in one command composer require laravel/breeze --dev php artisan breeze:install php artisan migrate
Three commands. You now have login, registration, password reset, email verification, and a protected dashboard — all built, tested, and styled. What takes days in Core PHP takes minutes in Laravel.
5. Protecting a Page (Authorization)
Core PHP:
// You paste this check at the top of every protected page
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: /login.php');
exit;
}
// page content continues here...
If you forget to add this to even one file, that page is publicly accessible. In a large project with many pages, this is a real and common mistake.
Laravel:
// Apply auth middleware to an entire group of routes at once
Route::middleware('auth')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
Route::get('/profile', [ProfileController::class, 'show']);
Route::get('/orders', [OrderController::class, 'index']);
// Every route here is protected — impossible to forget
});
One middleware declaration protects every route in the group. You cannot accidentally forget to protect a page.
6. Displaying Dynamic HTML (Templating)
Core PHP:
// Mixing PHP and HTML — hard to read, easy to make XSS mistakes
<?php foreach ($products as $product): ?>
<div class="product">
<h2><?php echo $product['name']; ?></h2>
<p>Price: ₹<?php echo $product['price']; ?></p>
</div>
<?php endforeach; ?>
Notice that echo without escaping is an XSS vulnerability — if $product['name'] contains a script tag injected by a malicious user, it will execute in the browser. You must remember to use htmlspecialchars() everywhere, and developers often forget.
Laravel Blade:
@foreach ($products as $product)
<div class="product">
<h2>{{ $product->name }}</h2>
<p>Price: ₹{{ $product->price }}</p>
</div>
@endforeach
Blade's {{ }} automatically escapes output. XSS protection is the default, not something you have to remember to add.
Summary Comparison Table
AreaCore PHPLaravelRoutingManual URL checking with if/elseClean route definitions with full HTTP supportDatabaseManual connection + raw SQL every timeEloquent ORM — one-line queries, auto-injection protectionAuthenticationWrite from scratch — days of workFull system in 3 commands via BreezeSecurityMust implement manually — easy to missCSRF, XSS, SQL injection protected by defaultTemplatingPHP mixed in HTML — XSS riskBlade — auto-escaped, clean syntaxProject StructureNo rules — each developer decidesMVC enforced — consistent across all projectsValidationManual — must write all rules yourselfBuilt-in validation with 50+ rules availableCode ReuseCopy-paste common — easy to miss updatesMiddleware, models, components — write once, use everywhereDevelopment SpeedSlower — infrastructure takes significant timeFaster — infrastructure is already builtMaintenanceHard — no enforced conventionsEasier — consistent structure across every project
Where Core PHP Still Makes Sense
This is not a case where one is always better than the other. Core PHP has legitimate uses:
- Learning PHP fundamentals — Before using a framework, understanding how PHP actually works (sessions, headers, superglobals, database connections) makes you a better Laravel developer. You understand what the framework is doing for you rather than treating it as magic.
- Simple single-purpose scripts — A script that processes a CSV file and inserts rows into a database does not need a full framework. Core PHP handles it faster with less overhead.
- Shared hosting with limited PHP versions — Some very old hosting environments do not support the PHP version Laravel requires. Core PHP works on almost any hosting.
- Extremely performance-sensitive microservices — In rare cases where every millisecond matters and the application is very simple, the overhead of a framework (even though it is small) may be worth avoiding.
For everything else — any application a real user will interact with, any project that will grow over time, any codebase more than one developer will touch — Laravel is the better choice.
Does Learning Laravel Mean You Do Not Need to Know PHP?
No — and this is an important point. Laravel is written in PHP. When you write Laravel code, you are writing PHP. You use PHP arrays, PHP classes, PHP functions, and PHP logic throughout every Laravel application.
What Laravel removes is the need to build infrastructure from scratch. It does not remove PHP itself. A developer who skips PHP fundamentals and jumps straight to Laravel will struggle to understand why things work the way they do, how to debug problems, and how to write custom logic that goes beyond what the framework provides out of the box.
The ideal path: learn PHP fundamentals first, understand how things work at the base level, then bring those skills into Laravel where the framework handles the repetitive infrastructure and you focus on building features.