Appearance
Getting started
Table of Contents
The best way to learn is by practicing. Let's create a basic CRUD using the query builder:
Create project
This guide assumes that you are using Visual Studio Code as your text editor and Ubuntu as your operating system. If you are a Windows user, it is recommended to use Ubuntu with WSL.
bash
composer create-project phenixphp/phenix phenix
// Go to root path
cd phenix
// Open VS Code
code .Edit the database configuration variables to establish a connection in the .env file. The default database connection is mysql.
bash
DB_CONNECTION=mysql
DB_DATABASE=phenix
DB_USERNAME=root
DB_PASSWORD=secretCreate migration
Open a new terminal using the shortcut Ctrl + `, and run a Phenix command.
bash
php phenix make:migration CreateUsersTableThe command will create a migration at the following path:
bash
database/migrations/20230930111521_create_users_table.phpCopy and paste the user table structure. It should look like this:
php
<?php
declare(strict_types=1);
use Phenix\Database\Migration;
class CreateUsersTable extends Migration
{
public function up(): void
{
$table = $this->table("users");
$table->string('name', 100);
$table->string('email', 124)->unique();
$table->create();
}
public function down(): void
{
$this->table('users')->drop()->save();
}
}Run the migrations with the following command:
bash
php phenix migrateOnce the migrations have been run, you will see output like the following:
bash
using migration paths
- /home/username/php/phenix/database/migrations
using seed paths
using environment default
using database phenix
ordering by creation time
== 20230930111521 CreateUsersTable: migrating
== 20230930111521 CreateUsersTable: migrated 0.0141s
All Done. Took 0.0381sCreate user seeder
We need some users created in the database. The command to create the seeder is the following:
bash
php phenix make:seeder UsersSeederCopy the seeder code. It should look like this:
php
<?php
declare(strict_types=1);
use Phenix\Database\Seed;
class UsersSeeder extends Seed
{
public function run(): void
{
$users = $this->table("users");
$users->insert([
[
'name' => 'Rasmus Ledford',
'email' => 'rasmus.ledford@php.net',
],
[
'name' => 'Nikita Popov',
'email' => 'nikita.popov@php.net',
],
])->saveData();
}
}Run the seeder to insert the data:
bash
php phenix seed:runWhen the data has been inserted, you will see a result like the following:
bash
using migration paths
- /home/username/php/phenix/database/migrations
using seed paths
- /home/username/php/phenix/database/seeds
warning no environment specified, defaulting to: default
using database phenix
== UsersSeeder: seeding
== UsersSeeder: seeded 0.0234s
All Done. Took 0.0240sCreate controller
Now let's create the user controller to create the CRUD:
bash
php phenix make:controller UserController -aThe controller will have the following content:
php
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use Phenix\Http\Controller;
use Phenix\Http\Constants\HttpStatus;
use Phenix\Http\Request;
use Phenix\Http\Response;
class UserController extends Controller
{
public function index(): Response
{
return response()->plain('Hello, world!' . PHP_EOL);
}
public function store(Request $request): Response
{
return response()->json([], HttpStatus::CREATED);
}
public function show(Request $request): Response
{
return response()->json([], HttpStatus::OK);
}
public function update(Request $request): Response
{
return response()->json([], HttpStatus::OK);
}
public function delete(Request $request): Response
{
return response()->json([], HttpStatus::OK);
}
}For a complete reference of controllers and request handling, see the Controllers guide.
The index method
This method allows us to obtain all the users created in the database. At this point, we have two options: the query brings all the data, or the most optimal and common, paginate the records. The first step will be to register the user index route in the routes/api.php file:
php
use App\Http\Controllers\UserController;
use Phenix\Facades\Route;
// ...
Route::get('/users', [UserController::class, 'index'])
->name('users.index');If you see any similarity with Laravel routes, it's not a coincidence; the elegant syntax inspires us all.
Now let's add code to the index method. The code should look like this:
php
use App\Models\User;
public function index(Request $request): Response
{
$users = User::query()->paginate($request->getUri());
return response()->json($users);
}The first thing to mention is that we inject the request into the index method, so the paginator has access to the URL variables to establish which page will be queried, and if there are query parameters, they will be loaded to the URLs that are generated in the response. To get all the data in the users table, just use the get method instead of the paginate method.
Open the terminal using the shortcut Ctrl + Shift + `, and run the server.
bash
php public/index.phpAt this point, you can use a client like Postman or Thunder integrated as a VS Code extension, and send a request to the URL http://127.0.0.1:1337/users. The server response should look like the following:
json
{
"path": "http://127.0.0.1:1337/users",
"current_page": 1,
"last_page": 1,
"per_page": 15,
"total": 2,
"first_page_url": "http://127.0.0.1:1337/users?page=1",
"last_page_url": "http://127.0.0.1:1337/users?page=1",
"prev_page_url": null,
"next_page_url": null,
"from": 1,
"to": 2,
"data": [
{
"id": 1,
"name": "Rasmus Ledford",
"email": "rasmus.ledford@php.net"
},
{
"id": 2,
"name": "Nikita Popov",
"email": "nikita.popov@php.net"
}
],
"links": [
{
"url": "http://127.0.0.1:1337/users?page=1",
"label": 1
}
]
}The store method
The store method will allow us to add new users. Let's write the code. Corresponding route:
php
Route::post('/users', [UserController::class, 'store'])
->name('users.store');Because we are using the query builder, first the insertion is executed and then a query to obtain the inserted record.
php
use App\Models\User;
public function store(Request $request): Response
{
$data = $request->body()->toArray();
$user = User::create($data);
return response()->json($user, HttpStatus::CREATED);
}Because the routes are loaded at server startup time, it is necessary to restart the server. Press Ctrl + C and run the server again:
bash
php public/index.phpAgain, use your favorite client and send the necessary data to create a user. The response will contain the data of the new record:
json
{
"id": 3,
"name": "John Doe",
"email": "john.doe@email.com"
}Note
Check hot reloading feature
The show method
This method will help us when we want to consult a record by its identifier:
php
Route::get('/users/{user}', [UserController::class, 'show'])
->name('users.show');Remember that every time we make changes to our code, we must restart the server.
php
use App\Models\User;
public function show(Request $request): Response
{
$user = User::query()
->whereEqual('id', $request->route()->integer('user'))
->first();
return response()->json($user, HttpStatus::OK);
}The JSON response:
json
{
"id": 3,
"name": "John Doe",
"email": "john.doe@email.com"
}The update method
Now let's update the existing records:
php
Route::patch('/users/{user}', [UserController::class, 'update'])
->name('users.update');We will only update the name for practical purposes.
php
use App\Models\User;
public function update(Request $request): Response
{
$user = User::query()
->whereEqual('id', $request->route()->integer('user'))
->first();
$user->name = $request->body('name');
$user->save();
return response()->json($user, HttpStatus::OK);
}The client will respond to us with updated data:
json
{
"id": 3,
"name": "John Edison Doe",
"email": "john.doe@email.com"
}The delete method
Finally, the method to delete records from the database:
php
Route::delete('/users/{user}', [UserController::class, 'delete'])
->name('users.delete');For advanced route features such as groups, middleware, and signatures, see the Routing guide.
The response will be a simple message:
php
use App\Models\User;
public function delete(Request $request): Response
{
User::query()
->whereEqual('id', $request->route()->integer('user'))
->delete();
return response()->json(['message' => 'Ok'], HttpStatus::OK);
}We have completed this short quick start guide to show fundamental concepts of the framework: routes and controllers, requests, and running the server. In the following sections, concepts about the architecture of the framework and its characteristics will be deepened.
Important
If you liked Phenix and you have seen the potential and the great opportunity we have in the PHP community, I invite you to give it a star on GitHub and contribute to the development of this powerful framework.