Laravel中扩展访问器与修改器的技术实现问询
Hey there! Let's tackle this encryption setup for your Laravel 5.5 models. Since you already have an abstract base model and custom models extending it, we can build reusable encryption logic directly into the abstract class—so all your child models can leverage it without redundant code.
We'll override Eloquent's core attribute handling methods to automatically encrypt/decrypt specified fields, while keeping your existing fillable and database connection settings intact.
1. Update Your Abstract Base Model
Add the encryption/decryption logic to your abstract model. We'll define a configurable list of fields to encrypt, then hook into Eloquent's attribute get/set processes:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Crypt; abstract class AbstractBaseModel extends Model { // Child models will override this array to specify encrypted fields protected $encryptedFields = []; /** * Automatically decrypt fields when retrieving them */ public function getAttribute($key) { $value = parent::getAttribute($key); // Decrypt if the field is in our encrypted list and has a value if (in_array($key, $this->encryptedFields) && !is_null($value)) { try { return Crypt::decrypt($value); } catch (\Exception $e) { // Fallback to raw value if decryption fails (adjust this as needed) return $value; } } return $value; } /** * Automatically encrypt fields when setting them */ public function setAttribute($key, $value) { // Encrypt if the field is in our encrypted list and has a value if (in_array($key, $this->encryptedFields) && !is_null($value)) { $value = Crypt::encrypt($value); } return parent::setAttribute($key, $value); } }
2. Enable Encryption in Your Custom Model
In your child model, just override the $encryptedFields array to specify which fields need encryption. This works seamlessly with your existing fillable and connection settings:
<?php namespace App\Models; class YourCustomModel extends AbstractBaseModel { // Keep your existing database connection protected $connection = 'mysql'; // Keep your existing fillable fields (include encrypted fields here too!) protected $fillable = ['name', 'email', 'secret_details', 'confidential_note']; // List fields that should be encrypted protected $encryptedFields = ['secret_details', 'confidential_note']; }
3. Test the Workflow
Now you can use your model exactly as before—encryption/decryption happens automatically:
- When you set
$model->secret_details = 'My sensitive info';, the value gets encrypted before saving to the database - When you retrieve
$model->secret_details, it's automatically decrypted back to the original value - Mass assignment works too:
YourCustomModel::create(['name' => 'Jane Doe', 'secret_details' => 'Private data']);
Key Notes
- Ensure Your App Key is Set: Laravel 5.5 generates an
APP_KEYduring installation, but if you don't have one, runphp artisan key:generateto create it (this is required for encryption) - Decryption Failures: The example returns the raw value if decryption fails, but you can modify this to throw a
DecryptExceptionif that makes more sense for your use case - Legacy Data: If you have existing unencrypted data, write an Artisan command to batch-encrypt those records to avoid mixed data issues
内容的提问来源于stack exchange,提问作者Nitish Kumar

