PHP ActiveRecord doesn't seem to use my custom attribute

僤鯓⒐⒋嵵緔 提交于 2019-12-04 17:24:11

Here's my simple solution. I've overriding the attributes method and adding any methods that start with "get_attribute_" so I can use them during serialization:

class BaseModel extends ActiveRecord\Model
{
    public function attributes()
    {
        $attrs = parent::attributes();
        $modelReflector = new ReflectionClass(get_class($this));
        $methods = $modelReflector->getMethods(~ReflectionMethod::IS_STATIC & ReflectionMethod::IS_PUBLIC);
        foreach ($methods as $method)
        {
            if (preg_match("/^get_attribute_/", $method->getName()))
            {
                $attrs[str_replace('get_attribute_', '', $method->getName())] = $method->invoke($this);
            }   
        }
        return $attrs;
    }
}

The resulting models that use this would look like this:

class User extends BaseModel
{
    public $loginSessionId;

    function get_attribute_loginSessionId(){
        return $this->loginSessionId;
    }
}

This way I can manually tack on the loginSessionId (or whatever else I want) and have it show up in the serialized values.

The attributes() method will indeed return only the values for your model's table columns (not aliased).

But $item->name should give you the expected result. You can also add the setter.

To get an array of all the attributes, you can add this method to your model:

public function all_attributes() {
    $custom_attr = [];
    foreach (static::$getters as $getter) {
        $key = substr($getter, 4);
        $custom_attr[$key] = $this->$key;
    }
    return $custom_attr + $this->attributes();
}

(don't forget to add your getters to the $getters array, the ActiveRecord model will use it)

You have to check what the attributes function does. You might need to override it to take into account your custom attributes, or you might have to add your custom attributes to some _properties property in the ancestor

Can you show us how you created $item? PHPActiveRecord needs you to set the attributes in the constructor call (new User($attributes)) or directly on the properties ($user->first_name = 'Gareth').


EDIT

I'm not sure the attributes() method would pick up the custom getter. It seems that it just returns the attributes property of the model.

https://github.com/kla/php-activerecord/blob/master/lib/Model.php#L566

I solved this as follows:

Create a class that derives from ActiveRecord\Model and include this function:

public function properties()
{
  $attrs = $this->attributes();
  $modelReflector = new ReflectionClass(get_class($this));
  $methods = $modelReflector->getMethods(~ReflectionMethod::IS_STATIC & ReflectionMethod::IS_PUBLIC);
  foreach ($methods as $method)
  {
    if (preg_match("/^get_/", $method->getName()))
    {
      $attrs[str_replace('get_', '', $method->getName())] = $method->invoke($this);
    }
  }
  return $attrs;
}

This returns all of the attributes, custom or otherwise, as long as I derive my models from the right class (not ActiveRecord\Model).

Actually, it is easily implemented like this @ add this to https://github.com/kla/php-activerecord/blob/master/lib/Model.php#L520:

// check for attribute as getter
if ( method_exists( $this, "get_{$name}" ) ){
  $method = "get_{$name}";
  $var = $this->$method();
  return $var;
}

But I prefer to do it like this (cleaner/optimized code) :

SomeModel.php:

  /** 
   * gets templatefile of outputplugin, wrapper function for template comfortability 
   * 
   * NOTE 2: never implement functions in model, try redirecting
   * to manager class (=lowmemory footprint, imagine xxxxx models with xxxx similar functions)
   *
   * @param string $varname variable description 
   * @return string 
   */ 
  public function get( $varname )
  { 
    switch( $varname ){
      case "foo" : return SomeModel::getManager()->getFoo(); break;
      default: return "";
    }
  }

add this to https://github.com/kla/php-activerecord/blob/master/lib/Model.php#L520:

// check for attribute as getter
if ( method_exists( $this, "get" ) && $this->get( $name ) ){ 
  $var = $this->get( $name );
  return $var;
} 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!