DopparWhere Performance Meets Aristocratic Syntax
Unlock the Full Potential of Your PHP Applications with Modern Syntax and Uncompromising Performance
Unlock the Full Potential of Your PHP Applications with Modern Syntax and Uncompromising Performance
With Doppar, a single line route definition gives you full routing power — HTTP method restriction, route naming, and middleware support — all declaratively, elegantly, and without boilerplate.
#[Mapper(prefix: 'user', middleware: ['auth'])]
class UserController extends Controller
{
#[Route(
uri: '/{user}', // Route URL; {user} is the route parameter
methods: ['GET'], // Allowed HTTP method
name: 'user', // Named route
middleware: ['is_admin'], // Middleware applied
rateLimit: 10, // Max requests allowed
rateLimitDecay: 1 // Decay period in minutes
)]
public function show(#[Model] ?User $user)
{
// Example endpoint: http://example.com/user/aliba@doppar.com
// `$user` is automatically resolved by email (route-model binding)
return $user; // Returns the User model instance
}
}Doppar allows you to inject dependencies directly at the method signature. By simply decorating a parameter, it immediately clear which concrete implementation is being used:
class PostController extends Controller
{
public function __construct(
#[Bind(PostRepository::class)] readonly private PostRepositoryInterface $postRepository
) {}
#[Route('/')]
public function __invoke(
#[Bind(AnotherConcrete::class)] AnotherAbstract $anotherRepository
)
{
//
}
}Doppar allows you to automatically wrap a method (like __invoke) in a database transaction. By decorating the method with
#[Transaction]attribute. This removes the traditional transaction boilerplate and collapses transaction management into a declarative, single line in your method signature:
class PaymentController extends Controller
{
#[Transaction]
#[Route('payment', methods: ['POST'])]
public function payment()
{
// Automatically wraps the payment method in a DB transaction
}
}Doppar’s Model Hooks provide an elegant way to tap into your models’ lifecycle events, allowing you to execute custom logic automatically during creation, updates, deletion, or booting.
class User extends Model
{
protected $hooks = [
'after_updated' => [
'handler' => App\Hooks\UserUpdatedHook::class,
'when' => [self::class, 'isAdmin']
],
];
public static function isAdmin(Model $model): bool
{
return (int) $model->role === 'admin';
}
}
class UserUpdatedHook
{
public function handle(Model $model): void
{
if ($model->isDirtyAttr('name')) {
info("Name changed from {$model->getOriginal('name')} to {$model->name}");
}
}
}Doppar’s request handling system combines dependency injection, data pipelines, and contextual transformations into a concise and expressive syntax
public function store(PostRequst $request)
{
$data = $request
->pipeInputs([
'title' => fn($v) => ucfirst(trim($v)),
'tags' => fn($v) => is_string($v) ? explode(',', $v) : $v
])
->contextual(fn($data) => [
'slug' => Str::slug($data['title'])
])
->ensure('slug', fn($slug) => strlen($slug) > 0)
->only('title','slug');
Post::create($data);
}Traditionally, a controller action receiving a POST request to create a user. With Doppar’s #[BindPayload], this entire setup collapses into a declarative, single line in your method signature:
public function store(Request $request) {
// 1. Validate the request data.
// 2. Extract the data.
// 3. Create a new User object and fill it manually.
$user = new User();
$user->name = $request->input('name');
// ... many more lines of mapping
$user->save();
}
// With #[BindPayload] Attribute
public function store(
#[BindPayload] User $user // The $user object is fully ready!
) {
return User::createFromModel($user);
}Doppar Entity ORM functionality with expressive reusable query, selective fields, and embedded relationships, all while keeping code clean and readable delivering pure, high-performance data handling with zero external overhead.
public function __active(Builder $query): Builder
{
return $query->whereStatus(true);
}
Post::active()
->present('comments.reply', function ($query) {
$query->where('approved', true);
})
->search(
attributes: [
'title',
'user.name',
'category.name',
'tags.name',
'comments.body',
'comments.reply.body',
],
searchTerm: $request->search
)
->embed(
relations: [
'category:id,name',
'user:id,name',
'tags',
]
)
->embedCount([
'tags',
'comments.reply' => fn($q) => $q->where('approved', true),
])
->paginate(perPage: 10);Doppar is engineered for speed — every repeated execution is intelligently memoized, ensuring results are delivered instantly without unnecessary reprocessing.
Doppar’s highly optimized core is engineered for maximum speed—delivering near-instant response times, low latency, and seamless execution even under heavy load.
Doppar brings advanced Just-in-Time (JIT) compilation to the Blade template engine — a performance-focused feature that transforms how views are compiled and rendered at runtime.
Crafted entirely within Doppar's core, this ORM eliminates all third-party dependencies—delivering pure, high-performance data handling with zero external overhead.
Doppar’s model hooks goes beyond and a cleaner, more flexible lifecycle API with support for inline, class-based, and conditional hooks directly in the ORM core.
Doppar offers a rich set of features out of the box — from a fast, core-powered ORM to built-in routing, validation, and concurrency controls. Everything you need to build modern, high-performance applications with zero unnecessary dependencies.