3

我已经开始在我的 PHP 应用程序中使用方法链:

$object->do()->something();

特别是查询数据库:

$database->select()->from('mytable');

但是目前我需要调用一个函数来在最后实际执行查询:

$database->select()->from('mytable')->perform();

这很烦人,因为通常每个链都会立即执行。有时不会,但十分之九会。我需要它来处理任何对象,而不仅仅是数据库处理程序。

有没有办法判断我调用的最后一个方法是否是方法本身的最后一个方法,所以perform()不需要我告诉它?

如果没有,我可能会尝试使用一些关键字,例如->now()而不是->perform()

我有几个想法:

  • 每个方法都有一个参数,如果设置它会让它知道它在最后(也许它可以遍历所有参数以查找是否传递了特殊常量?)例如$object->do()->something(now);
4

3 回答 3

1

在 Perl 的 DBIX::Class 中,它们在使用数据时触发查询。所以每个查询链都不会返回数据库对象,而是一个环绕数据库表对象的 DBIX::Class 对象。

您可以尝试实施类似的系统。因此,例如以下内容:

$resultSet = $database->select()->from('mytable');

实际上并不返回表,而是返回一个 resultSet 对象。只有当您尝试这样做时:

$resultSet->next();

图书馆是否会真正从数据库中获取数据。

基本上,所有访问器方法,如、first()和fetch和缓存数据。如果数据已经被提取并缓存在内存中,那么对 resultSet 对象的访问器方法的进一步调用应该只是读取内存中的哈希而不是连接到数据库。last()all()next()


附加细节:

插入没有像 select 这样的复杂子句。所以插入函数不需要是可链接的。因此,对于插入,您可以简单地让 API 执行以下操作:

$database->insert()->into('mytable')->values({
    foo => "hello",
    bar => "world"
});

其中该values()方法充当插入函数并触发数据库查询。

可以简单地对行对象进行更新。您可以让 API 执行以下操作:

$row = $database->select()->from('mytable')->first();
$row->foo('goodbye');
$row->update();

或者:

$row->update({
    foo => "goodbye"
});

并让update()方法触发数据库查询。

于 2013-10-09T04:39:48.690 回答
0

使用运算符重载扩展,您可以指定一元运算符之一来提示执行。

例子:

~$db->select()->from()->where();

如果您想避免安装扩展,我可以提出的一个建议是在您最新的链调用中使用某种转义字符来提示执行。您应该从最终查询中省略它以避免语法错误。

例子:

$db->select()->from()->where("id = 1 ~"); //~ character implies automatic execution
于 2013-10-09T03:14:31.933 回答
0

有没有办法判断我调用的最后一个方法是否是方法本身的最后一个方法

不,我相信没有这样的事情。那是因为“链式调用”与“一个接一个的调用”没有区别。这只是“call => return object => call => return object ...”链的一种语法糖。

I have a few idea(s):

 - each method has a parameter that if set will let it know it's at the end (maybe it can 
   loop through all parameters to find if a special constant was passed?) eg
   $object->do()->something(now);

您可以通过重载__call()方法来实现您建议的想法的效果。这样你就可以很好地抽象你的参数检查逻辑。

但是请注意,这种行为在架构方面并不是很明显,您可能应该考虑类似 PDO 的方法,即使用“最终确定”方法,perform()或者do()我认为您已经拥有的方法。

于 2013-10-09T03:20:54.717 回答