我已经开始在我的PHP应用程序中使用方法链了:
$object->do()->something();
特别是查询数据库:
$database->select()->from('mytable');
但是目前我需要调用一个函数来实际执行查询:
$database->select()->from('mytable')->perform();
这很烦人,因为通常每个链都会立即执行。有时它不会,但它会有9倍。我需要这个来处理任何对象,而不仅仅是数据库处理程序。
有没有办法判断我调用的最后一个方法是方法本身的最后一个方法,所以如果没有我告诉它会perform()
吗?
如果没有,我可能会尝试使用某些关键字,例如->now()
而不是->perform()
我有一些想法:
$object->do()->something(now);
答案 0 :(得分:1)
在Perl的DBIX :: Class中,它们在使用数据时触发查询。因此,每个查询链都不返回数据库对象,而是返回包装数据库表对象的DBIX :: Class对象。
您可以尝试实施类似的系统。所以,例如以下内容:
$resultSet = $database->select()->from('mytable');
实际上并不返回表,而是返回resultSet对象。只有当你尝试做的时候:
$resultSet->next();
库实际上会从数据库中获取数据。
基本上,所有访问者方法(如first()
,last()
,all()
和next()
都会获取并缓存数据。如果数据已被提取并缓存在内存中,那么对resultSet对象上的访问器方法的进一步调用应该只读取内存中的哈希值,而不是连接到数据库。
其他细节:
插入没有像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()
方法触发数据库查询。
答案 1 :(得分:0)
使用运算符重载extension,您可以指定一个用于提示执行的一元运算符
示例:
~$db->select()->from()->where();
如果您想避免安装扩展程序,我可以提出的一个建议是在最近的链调用中使用某种转义字符来提示执行。您应该从最终查询中省略它以避免语法错误。
示例:
$db->select()->from()->where("id = 1 ~"); //~ character implies automatic execution
答案 2 :(得分:0)
有没有办法判断我调用的最后一个方法是否是方法本身的最后一个方法
不,我相信没有这样的事情。那是因为“连锁电话”与“逐个电话”没有区别。这只是“call => return object => call => return object ...”chain的一种语法糖。
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);
您可以实现overloading __call()
method建议的效果。通过这种方式,您可以很好地抽象出参数检查逻辑。
但请注意,这种行为在构架方面并不是很明显,你可能应该考虑类似PDO的方法,即使用perform()
或do()
之类的“最终化”方法,我认为,你已经拥有。