Php Activerecord关联:创建新对象(查找类)
我有一个带有关系的模型,我想实例化一个关系类型的新对象 示例:一个人有一个公司,我有一个人对象:现在我 要创建公司对象 companyobject的类是在关系中定义的,因此我认为我不需要“知道”该类,但我应该能够要求person对象为我提供company类型的新实例?但我不知道怎么做 我认为,这是与相同的问题,但我使用的是,而不是rubyPhp Activerecord关联:创建新对象(查找类),php,phpactiverecord,Php,Phpactiverecord,我有一个带有关系的模型,我想实例化一个关系类型的新对象 示例:一个人有一个公司,我有一个人对象:现在我 要创建公司对象 companyobject的类是在关系中定义的,因此我认为我不需要“知道”该类,但我应该能够要求person对象为我提供company类型的新实例?但我不知道怎么做 我认为,这是与相同的问题,但我使用的是,而不是ruby 这背后的原因是:我有一个抽象的超类person,两个孩子与一种类型的公司对象有他们自己的关系。我需要能够在抽象的person中实例化正确的类 解决方法是直接
这背后的原因是:我有一个抽象的超类
person
,两个孩子与一种类型的公司对象有他们自己的关系。我需要能够在抽象的person中实例化正确的类
解决方法是直接从static$has\u one
数组中获取它:
$class = $this::$has_one[1]['class_name'];
$company = new $class;
当然,通过在数组中搜索关联名称可以消除硬编码的数字,但这仍然非常难看
如果有人知道这是如何在Ruby中实现的,以及phpactiverecord实现的不同之处,我可能会从中得到一些想法
一些测试表明,尽管“在数组中搜索我的类名”看起来有点奇怪,但它对性能没有任何影响,而且在使用中它的功能已经足够了 我目前正在使用下面的解决方案。相反,这是一个实际的解决方案 我在问题中提到的
$has_one[1]
黑客。如果有
phpactiverecord中的方法我会觉得非常愚蠢
叶利夫女士。但请证明我很傻,这样我就不用用这个了
解决方案:D
我很傻。下面的功能是通过create_associationname调用实现的,由@Bogdan_D回答
增加了两个功能。您可能应该将它们添加到
\ActiveRecord\Model
类中。在我的例子中,在我们的类和那个模型之间有一个类,它包含像这样的额外功能,所以我把它放在那里
这是两个功能:
公共函数findClassByAssociation($associationName)
- 使用您要查找的关联的名称调用
- 检查关联的三个静态变量(
,有多个
,属于
)有一个
- 如果找到关联,则调用findClassFromArray
- 从个人/公司示例:
$person->findClassByAssociation('company')代码>
私有函数findClassFromArray($associationName,$associationArray)
- 只是一个尝试匹配名称的辅助函数
/**
* Find the classname of an explicitly defined
* association (has_one, has_many, belongs_to).
* Unsure if this works for standard associations
* without specific mention of the class_name, but I suppose it doesn't!
* @todo Check if works without an explicitly set 'class_name', if not: is this even possible (namespacing?)
* @todo Support for 'through' associations.
* @param String $associationName the association you want to find the class for
* @return mixed String|false if an association is found, return the class name (with namespace!), else return false
* @see findClassFromArray
*/
public function findClassByAssociation($associationName){
//$class = $this::$has_one[1]['class_name'];
$that = get_called_class();
if(isset($that::$has_many)){
$cl = $this->findClassFromArray($associationName,$that::$has_many);
if($cl){return $cl;}
}
if(isset($that::$belongs_to)){
$cl = $this->findClassFromArray($associationName,$that::$belongs_to);
if($cl){return $cl;}
}
if(isset($that::$has_one)){
$cl = $this->findClassFromArray($associationName,$that::$has_one);
if($cl){return $cl;}
}
return false;
}
/**
* Find a class in a php-activerecord "association-array". It probably should have a specifically defined class name!
* @todo check if works without explicitly set 'class_name', and if not find it like standard
* @param String $associationName
* @param Array[] $associationArray phpactiverecord array with associations (like has_many)
* @return mixed String|false if an association is found, return the class name, else return false
* @see findClassFromArray
*/
private function findClassFromArray($associationName,$associationArray){
if(is_array($associationArray)){
foreach($associationArray as $association){
if($association['0'] === $associationName){
return $association['class_name'];
}
}
}
return false;
}
我目前正在使用下面的解决方案。相反,这是一个实际的解决方案
我在问题中提到的$has_one[1]
黑客。如果有
phpactiverecord中的方法我会觉得非常愚蠢
叶利夫女士。但请证明我很傻,这样我就不用用这个了
解决方案:D
我很傻。下面的功能是通过create_associationname调用实现的,由@Bogdan_D回答
增加了两个功能。您可能应该将它们添加到
\ActiveRecord\Model
类中。在我的例子中,在我们的类和那个模型之间有一个类,它包含像这样的额外功能,所以我把它放在那里
这是两个功能:
公共函数findClassByAssociation($associationName)
- 使用您要查找的关联的名称调用
- 检查关联的三个静态变量(
,有多个
,属于
)有一个
- 如果找到关联,则调用findClassFromArray
- 从个人/公司示例:
$person->findClassByAssociation('company')代码>
私有函数findClassFromArray($associationName,$associationArray)
- 只是一个尝试匹配名称的辅助函数
/**
* Find the classname of an explicitly defined
* association (has_one, has_many, belongs_to).
* Unsure if this works for standard associations
* without specific mention of the class_name, but I suppose it doesn't!
* @todo Check if works without an explicitly set 'class_name', if not: is this even possible (namespacing?)
* @todo Support for 'through' associations.
* @param String $associationName the association you want to find the class for
* @return mixed String|false if an association is found, return the class name (with namespace!), else return false
* @see findClassFromArray
*/
public function findClassByAssociation($associationName){
//$class = $this::$has_one[1]['class_name'];
$that = get_called_class();
if(isset($that::$has_many)){
$cl = $this->findClassFromArray($associationName,$that::$has_many);
if($cl){return $cl;}
}
if(isset($that::$belongs_to)){
$cl = $this->findClassFromArray($associationName,$that::$belongs_to);
if($cl){return $cl;}
}
if(isset($that::$has_one)){
$cl = $this->findClassFromArray($associationName,$that::$has_one);
if($cl){return $cl;}
}
return false;
}
/**
* Find a class in a php-activerecord "association-array". It probably should have a specifically defined class name!
* @todo check if works without explicitly set 'class_name', and if not find it like standard
* @param String $associationName
* @param Array[] $associationArray phpactiverecord array with associations (like has_many)
* @return mixed String|false if an association is found, return the class name, else return false
* @see findClassFromArray
*/
private function findClassFromArray($associationName,$associationArray){
if(is_array($associationArray)){
foreach($associationArray as $association){
if($association['0'] === $associationName){
return $association['class_name'];
}
}
}
return false;
}
在PHPActiveRecord中,您可以访问关系数组。关系应该有一个名称,您需要知道您想要的关系/关联的名称。它不需要是类名,但是您要关联的模型的类名应该在关系中明确指出。这只是一个基本示例,没有错误检查或关系数据库详细信息,如链接表或外键列名:
class Person extends ActiveRecord\Model {
static $belongs_to = array(
array('company',
'class_name' => 'SomeCompanyClass')
);
//general function get a classname from a relationship
public static function getClassNameFromRelationship($relationshipName)
foreach(self::$belongs_to as $relationship){
//the first element in all relationships is it's name
if($relationship[0] == $relationshipName){
$className = null;
if(isset($relationship['class_name'])){
$className = $relationship['class_name'];
}else{
// if no classname specified explicitly,
// assume the clasename is the relationship name
// with first letter capitalized
$className = ucfirst($relationship);
}
return $className
}
}
return null;
}
}
要使用此函数,如果您有一个person对象,并且希望使用“company”关系定义的对象,请使用:
$className = $person::getClassNameFromRelationship('company');
$company = new $className();
在PHPActiveRecord中,您可以访问关系数组。关系应该有一个名称,您需要知道您想要的关系/关联的名称。它不需要是类名,但是您要关联的模型的类名应该在关系中明确指出。这只是一个基本示例,没有错误检查或关系数据库详细信息,如链接表或外键列名:
class Person extends ActiveRecord\Model {
static $belongs_to = array(
array('company',
'class_name' => 'SomeCompanyClass')
);
//general function get a classname from a relationship
public static function getClassNameFromRelationship($relationshipName)
foreach(self::$belongs_to as $relationship){
//the first element in all relationships is it's name
if($relationship[0] == $relationshipName){
$className = null;
if(isset($relationship['class_name'])){
$className = $relationship['class_name'];
}else{
// if no classname specified explicitly,
// assume the clasename is the relationship name
// with first letter capitalized
$className = ucfirst($relationship);
}
return $className
}
}
return null;
}
}
要使用此函数,如果您有一个person对象,并且希望使用“company”关系定义的对象,请使用:
$className = $person::getClassNameFromRelationship('company');
$company = new $className();
您还可以在关系类中使用
build\u association()
最简单的使用方法是通过模型的u调用,即如果您的关系类似于
$person->company
,那么您可以使用$company=$person->build_ucompany()实例化该公司
请注意,这也不会在对象之间建立“连接”($person->company
将不会被设置)
或者,您可以使用create_company()
,而不是build_company()
,这将保存新记录并将其链接到$person您还可以在关系类中使用build_association()
最简单的使用方法是通过模型的调用,即