次のように定義されたモデルがあります。
class User extends ActiveRecord\Model {
function get_name() {
return $this->first_name . " " . $this->surname;
}
}
ただし、表示$item->attributes();
すると名前は表示されません。ここで私はばかですか?その場合、カスタム属性をモデルに取り込むにはどうすればよいですか?
ありがとう、ガレス
次のように定義されたモデルがあります。
class User extends ActiveRecord\Model {
function get_name() {
return $this->first_name . " " . $this->surname;
}
}
ただし、表示$item->attributes();
すると名前は表示されません。ここで私はばかですか?その場合、カスタム属性をモデルに取り込むにはどうすればよいですか?
ありがとう、ガレス
attributes() メソッドは実際、モデルのテーブル列の値のみを返します (エイリアスはありません)。
しかし $item->name
、期待される結果が得られるはずです。セッターを追加することもできます。
すべての属性の配列を取得するには、このメソッドをモデルに追加できます。
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();
}
(Getter を $getters 配列に追加することを忘れないでください。ActiveRecord モデルがそれを使用します)
これが私の簡単な解決策です。属性メソッドをオーバーライドし、「get_attribute_」で始まるメソッドを追加して、シリアル化中に使用できるようにしました。
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;
}
}
これを使用した結果のモデルは次のようになります。
class User extends BaseModel
{
public $loginSessionId;
function get_attribute_loginSessionId(){
return $this->loginSessionId;
}
}
このようにして、loginSessionId (またはその他の必要なもの) を手動で追加して、シリアル化された値に表示させることができます。
私はこれを次のように解決しました:
この関数から派生しActiveRecord\Model
、この関数を含むクラスを作成します。
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;
}
これにより、モデルを適切なクラス(ではなく)から派生させている限り、カスタムまたはその他のすべての属性が返されますActiveRecord\Model
。
実際には、次のように簡単に実装できます @ これを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;
}
しかし、私はこのようにすることを好みます(よりクリーン/最適化されたコード):
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 "";
}
}
これを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;
}
$item をどのように作成したか教えていただけますか? PHPActiveRecord では、コンストラクター呼び出し ( new User($attributes)
) で属性を設定するか、プロパティで直接( ) 属性を設定する必要があります$user->first_name = 'Gareth'
。
編集
attributes() メソッドがカスタムゲッターを取得するかどうかはわかりません。モデルの属性プロパティを返すだけのようです。
https://github.com/kla/php-activerecord/blob/master/lib/Model.php#L566
属性関数の機能を確認する必要があります。カスタム属性を考慮してオーバーライドする必要がある場合や、祖先の一部の _properties プロパティにカスタム属性を追加する必要がある場合があります。