Laravel Zero
A micro-framework for console application development. Brings Laravel's elegance to CLI applications.
Framework
Laravel Zero
Overview
Laravel Zero is a micro-framework for console application development. It brings Laravel's elegance to CLI applications and is popular among Laravel developers for developing standalone CLI tools leveraging Laravel features. You can build lightweight and fast CLI applications while utilizing the rich Laravel ecosystem.
Details
Laravel Zero is a framework optimized for CLI applications while leveraging Laravel framework's core features. You can use Laravel's powerful features like Eloquent ORM, Collection, Queue, Schedule, and testing in command-line applications.
Key Features
- Laravel Ecosystem: Utilize features like Eloquent, Collection, Queue
- Artisan Commands: Laravel-style Artisan command-line tools
- Configuration Management: Laravel-style configuration file management
- Service Providers: Dependency injection and service container
- Scheduling: cron-style task scheduling
- Testing Features: Comprehensive testing features based on PHPUnit
- Logging: Flexible logging based on Monolog
- Auto-update: Self-update functionality
Pros and Cons
Pros
- Laravel Developer Friendly: Very familiar to Laravel developers
- Rich Features: Benefits from the Laravel ecosystem
- High Quality Code: Design based on Laravel quality standards
- Comprehensive Documentation: Detailed and clear official documentation
- Community: Support from the Laravel community
- Test Friendly: Built-in testing capabilities
- Package Distribution: Can be distributed as Phar files
Cons
- Learning Curve: Takes time to master for non-Laravel developers
- Dependencies: Depends on many Laravel components
- File Size: May be heavy for lightweight CLI tools
- PHP Requirements: Requires PHP 8.0 or higher
Key Links
Usage Examples
Project Creation
composer create-project --prefer-dist laravel-zero/laravel-zero my-cli-app
cd my-cli-app
php application --version
Basic Command Creation
<?php
// app/Commands/HelloCommand.php
namespace App\Commands;
use Illuminate\Console\Scheduling\Schedule;
use LaravelZero\Framework\Commands\Command;
class HelloCommand extends Command
{
/**
* Command name and argument definition
*/
protected $signature = 'hello {name : Your name} {--times=1 : Number of repetitions}';
/**
* Command description
*/
protected $description = 'Display greetings';
/**
* Execute the command
*/
public function handle(): int
{
$name = $this->argument('name');
$times = $this->option('times');
for ($i = 0; $i < $times; $i++) {
$this->info("Hello, {$name}!");
}
return self::SUCCESS;
}
/**
* Schedule definition
*/
public function schedule(Schedule $schedule): void
{
// $schedule->command(static::class)->daily();
}
}
Complex Command Example
<?php
// app/Commands/DataProcessCommand.php
namespace App\Commands;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;
use LaravelZero\Framework\Commands\Command;
class DataProcessCommand extends Command
{
protected $signature = 'data:process
{--source=api : Data source (api|file)}
{--format=json : Output format (json|csv|table)}
{--output= : Output file path}
{--limit=10 : Processing limit}';
protected $description = 'Fetch, process, and output data';
public function handle(): int
{
$source = $this->option('source');
$format = $this->option('format');
$output = $this->option('output');
$limit = (int) $this->option('limit');
$this->info('Starting data processing...');
// Fetch data
$data = $this->fetchData($source, $limit);
if ($data->isEmpty()) {
$this->error('Could not fetch data');
return self::FAILURE;
}
$this->info("Fetched: {$data->count()} items");
// Process data
$processedData = $this->processData($data);
// Output
$this->outputData($processedData, $format, $output);
$this->info('Data processing completed');
return self::SUCCESS;
}
protected function fetchData(string $source, int $limit): Collection
{
$this->task('Fetching data', function () use ($source, $limit) {
sleep(1); // Simulate processing
});
switch ($source) {
case 'api':
return $this->fetchFromApi($limit);
case 'file':
return $this->fetchFromFile($limit);
default:
return collect();
}
}
protected function fetchFromApi(int $limit): Collection
{
try {
$response = Http::get('https://jsonplaceholder.typicode.com/posts', [
'_limit' => $limit
]);
return collect($response->json());
} catch (\Exception $e) {
$this->error("API fetch error: {$e->getMessage()}");
return collect();
}
}
protected function fetchFromFile(int $limit): Collection
{
// Generate sample data
return collect(range(1, $limit))->map(function ($i) {
return [
'id' => $i,
'title' => "Sample Title {$i}",
'body' => "Sample Body {$i}",
'userId' => rand(1, 10)
];
});
}
protected function processData(Collection $data): Collection
{
return $data->map(function ($item) {
return [
'id' => $item['id'],
'title' => str($item['title'])->title(),
'body' => str($item['body'])->limit(50),
'user_id' => $item['userId'],
'processed_at' => now()->toDateTimeString()
];
});
}
protected function outputData(Collection $data, string $format, ?string $output): void
{
switch ($format) {
case 'json':
$content = $data->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
break;
case 'csv':
$content = $this->toCsv($data);
break;
case 'table':
$this->table(
['ID', 'Title', 'Body', 'User ID', 'Processed At'],
$data->map(fn($item) => array_values($item))->toArray()
);
return;
default:
$this->error("Unsupported format: {$format}");
return;
}
if ($output) {
file_put_contents($output, $content);
$this->info("Output to file: {$output}");
} else {
$this->line($content);
}
}
protected function toCsv(Collection $data): string
{
if ($data->isEmpty()) {
return '';
}
$headers = array_keys($data->first());
$csv = implode(',', $headers) . "\n";
foreach ($data as $row) {
$csv .= implode(',', array_map(fn($value) => '"' . str_replace('"', '""', $value) . '"', array_values($row))) . "\n";
}
return $csv;
}
}
Build and Compile
# Create Phar file
php application app:build my-app
# Create executable
php application app:build my-app --build-version=1.0.0
# Release build
php application app:build my-app --optimize