我在Propel中配置了一些表,并生成了Peer静态类。
我的问题是,我需要对不同但相似的表执行相同的搜索操作。这些表具有不同的Peer类,因为Propel就是这样工作的。这种情况会导致与在这些表上执行的查询相关的代码重复。
我想知道在这种情况下是否有一些结构(避免使用函数eval
)可以帮助我;我真的希望避免编写重复的代码,这些代码只对不同的静态Peer类执行相同的调用。
我正在写的一个类的(很长的)方法的示例代码片段:
$criteria = new Criteria();
$criteria->add(FoobarPeer::CONTRACTNR,$data['contractnr']);
$result = FoobarPeer::doSelect($criteria);
if(count($result) > 1){
throw new FoobarException("status: more than one row with the specified contractnr.");
}
if(count($result) == 0){
// no object with given contractnr. Create new one.
$obj = $this->factory->createORM("foobar");
$obj->setCreatedAt(time());
} else {
// use and update existing object.
$obj = $result[0];
}
正如您所看到的,我设法为行对象编写了一个工厂方法,但我找不到对静态类执行同样操作的方法。换句话说,我希望能够动态地访问静态类,而不是以一种丑陋的解决方法。
有什么想法吗?
谢谢:)
我真的不确定我是否完全理解你的要求,但以下是我认为你在问的问题的解决方案:
function orm_for($type) {
return strtolower($type);
}
function peer_for($type) {
return ucfirst($type)."Peer";
}
function exception_for($type) {
return ucfirst($type)."Exception";
}
function query($type, $data) {
$peer = $peer_for($type);
$exception = $exception_for($type);
$obj = null;
$criteria = new Criteria();
$criteria->add($peer::CONTRACTNR, $data["contractnr"]);
$result = $peer::doSelect($criteria);
if(count($result) > 1) {
throw new $exception("status: more than one row with the specified contractnr.");
} else if(count($result) == 0) {
$obj = $this->factory->createORM(orm_for($type));
$obj->setCreatedAt(time());
} else {
$obj = $result[0];
}
}
我认为代码是不言自明的。让我知道我是否正确地解释了你的问题。
一个实际的例子(只是一个POC)可以在这里找到
您应该能够使用行为来实现您想要做的事情。您可以使用行为向生成的对等对象添加自定义代码。请参见此处。
除其他外,您的行为可以实现以下方法:
staticAttributes() // add static attributes to the peer class
staticMethods() // add static methods to the peer class
您应该能够使用这些来向对等体添加您想要的代码。您只需要担心编写一次代码。Propel会在代码生成过程中复制代码,但这不应该太令人担忧,因为生成的很多代码都是重复的。至少,复制只是通过自动化过程引入的。