You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP中自动为类的公共属性生成类常量?(Laravel场景下优化硬编码问题)

Avoiding Redundant Constant & Property Definitions in Laravel Models

Great question—this exact boilerplate frustration hits every Laravel developer at some point! Duplicating column names as both class constants and public properties feels like unnecessary repetition, but there are several clean ways to eliminate it. Here are my go-to solutions:

1. Ditch the Public Properties Entirely (Quickest Win)

First, let’s clear up a common misconception: you don’t need to define public properties for Eloquent model attributes. Laravel’s Eloquent uses magic methods (__get and __set) to interact with the underlying $attributes array automatically.

So instead of writing:

class Car extends Model {
    const COLOR = 'color';
    const BRAND = 'brand';
    const COUNTRY_CODE = 'countryCode';
    
    public string $color;
    public string $brand;
    public string $countryCode;
}

You can safely omit the public properties entirely and still access attributes normally:

class Car extends Model {
    const COLOR = 'color';
    const BRAND = 'brand';
    const COUNTRY_CODE = 'countryCode';
}

// This still works perfectly!
$car = Car::first();
echo $car->color;
$car->brand = 'Toyota';

This cuts your boilerplate in half immediately, and you still get all the code completion benefits from the class constants when writing queries like Car::where(Car::COLOR, 'red')->get().

2. Auto-Generate Constants from Database Schema (No Manual Typing)

If you want to avoid even writing the constants manually, you can create a reusable trait that auto-generates them from your database table structure. Here’s how:

First, create a trait like app/Traits/HasColumnConstants.php:

<?php

namespace App\Traits;

use Illuminate\Support\Facades\Schema;

trait HasColumnConstants {
    public static function bootHasColumnConstants() {
        // Get the table name from the model
        $table = (new self())->getTable();
        // Fetch all column names from the table
        $columns = Schema::getColumnListing($table);
        
        foreach ($columns as $column) {
            // Convert snake_case column names to UPPER_SNAKE_CASE constants
            $constantName = strtoupper($column);
            // Define the constant if it doesn't already exist
            if (!defined(self::class . '::' . $constantName)) {
                define(self::class . '::' . $constantName, $column);
            }
        }
    }
}

Then use it in any model:

class Car extends Model {
    use HasColumnConstants;
}

Now, any column in your cars table (like color, brand, country_code) will automatically become a class constant (e.g., Car::COLOR, Car::BRAND, Car::COUNTRY_CODE).

Note: For IDE code completion, you might need to add a docblock to your model hinting the constants, or use a plugin like PHPStorm’s Laravel plugin which can detect dynamically generated constants.

3. Custom Artisan Command for Model Generation (New Projects)

If you’re starting a new project, you can create a custom Artisan command that generates models with pre-defined column constants right from the start.

Here’s a simplified example of how to build this:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;

class MakeModelWithConstants extends Command {
    protected $signature = 'make:model-with-constants {name} {table?}';
    protected $description = 'Create a new Eloquent model with auto-generated column constants';

    public function handle() {
        $modelName = $this->argument('name');
        $tableName = $this->argument('table') ?? Str::snake(Str::plural($modelName));
        
        // Get columns from the table
        $columns = Schema::getColumnListing($tableName);
        $constants = [];
        foreach ($columns as $column) {
            $constantName = strtoupper($column);
            $constants[] = "    const {$constantName} = '{$column}';";
        }
        
        // Generate model content
        $content = <<<EOT
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class {$modelName} extends Model {
    protected \$table = '{$tableName}';

{$this->indent(implode("\n", $constants), 4)}
}
EOT;
        
        // Save the model file
        $path = app_path("Models/{$modelName}.php");
        file_put_contents($path, $content);
        
        $this->info("Model {$modelName} created successfully with column constants!");
    }

    private function indent(string $content, int $spaces) {
        return implode("\n", array_map(fn($line) => str_repeat(' ', $spaces) . $line, explode("\n", $content)));
    }
}

Now run php artisan make:model-with-constants Car and it will generate a model with all your table’s columns as class constants—no manual typing required.

Final Thoughts

The simplest solution for most projects is option 1: skip the public properties entirely and rely on Eloquent’s magic methods. If you want to eliminate constant writing too, the trait approach (option 2) works seamlessly with existing projects. For new projects, the custom Artisan command keeps everything consistent from day one.

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:32:37