0

我对 PHP 魔术方法并没有真正的经验,我正在尝试创建与 Laravel 框架交互的隐式 getter 和 setter。现在,我知道有 accessors 和 mutators ,但必须明确声明它们。我想做的是某种隐式函数,而不是声明它们。我看到这是在 Zend 框架中完成的,类似于

public function __call ($method, $params) {

    $property = strtolower($this->_getCamelCaseToUnderscoreFilter()->filter(substr($method, 3)));

    if (!property_exists($this, $property))
        return null;
    // Getters
    elseif (substr($method, 0, 3) == 'get')
    {
        return $this->$property;
    }
    // Setters
    elseif (substr($method, 0, 3) == 'set')
    {
        $this->$property = $params[0];
        return $this;
    }
    else
        return null;
}

现在,如果我有一个具有此功能的模型,我将能够执行$model->getProperty()or $model->setProperty($property)。但我不确定如何将其应用于 Laravel。任何想法?

4

1 回答 1

0

我为我的所有模型创建了一个名为“Moam”的父类(作为所有模型的母亲)。在这个 Moam 中,我实现了那些古老的 Zend 框架众所周知的魔法方法。

/app/Models/Moam.php 是:

<?php

namespace App\Models;

use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;

/* Mother of all models*/
class Moam extends Model
{   
    /* Implementation of magical get and set method for manipulation model properties
     * i.e. setFirstName('xxx') sets property first_name to 'xxx'
     *      getFirstName() returns value of property first_name
     *
     * So Capitals replaced underscores (_) in property name
     */

    public function __call($methodName, $args) {
        if (preg_match('~^(set|get)([A-Z])(.*)$~', $methodName, $matches)) {

            $split = preg_split('/(?=[A-Z])/',$methodName);
            $property = strtolower (implode("_",array_slice($split,1)));

            $attributes = $this->getAttributes();
            if (!array_key_exists($property,$attributes)){
                Log::error(get_class($this) . ' has no attribute named "' . $property . '"');
                throw new Exception(get_class($this) . ' has no attribute named "' . $property . '"');
            } else {

                switch($matches[1]) {
                case 'set':
                    return $this->setAttribute($property, $args[0]);
                case 'get':
                    return ($attributes[$property]);
                }
            }
        }

        return parent::__call($methodName, $args);
    }
}

在其他模型中,您必须像这样声明模型:

use App\Models\Moam;
...

class yourModelextends Moam{
   ...
}

最后,您可以按以下形式调用 setter 和 getter:

$modelVariable->getAPropertyName();
$modelVariable->setAPropertyName(propertyValue);

例如:

$desc = $event->getDescription();
$event->setDescription("This is a blah blah blah...");
于 2019-09-11T10:38:18.890 回答