我在使用Dutch psp Mollie进行结帐的测试实施时遇到问题。问题不在于Mollie的相关问题。发生的事情是下面的索引函数有时被调用两次,导致我的sales表中有两条记录。我有点不知道为什么会发生这种情况。下面我粘贴了我的测试代码,导致了奇怪的行为。我已经尝试改变路线,但无济于事。即使我将代码移到路由/test/send
,或者将/test
存根链接到另一个函数,例如'' => 'send'
,也会发生同样的情况。
数据对象"销售"除了默认的$ db和$ has_something等之外没有额外的代码。
更新:我删除了所有与Mollie相关的代码,应用程序仍在执行相同的操作。我认为重定向与它有关,因为当我删除它时,问题不会浮出水面(它只会在我删除之后首次重新加载,之后,重新加载只会导致数据库中的一行)。当重新加载到位时,它会更频繁地发生(但我仍然无法预测何时或为什么)。
Update2:我尝试了全新安装,但问题仍然存在。由于站点托管在LEMP堆栈上,我还尝试在LAMP堆栈上进行全新安装。还是同样的问题......
Update3:我做了一个仍然显示相同行为的代码的最小示例,并相应地更新了以下代码
class TestController extends Controller {
public function index() {
$sale = Sale::create();
$sale->TicketName = "test ".date("Y-m-d H:i:s");
$sale->write();
return $this->redirect("http://other.site");
}
}
销售数据对象
class Sale extends DataObject {
private static $db = array(
"TicketName" => "Varchar(255)",
);
}
class SaleAdmin extends ModelAdmin {
private static $managed_models = array('Sale');
private static $url_segment = 'Sales';
private static $menu_title = 'Sales';
}
这就是route.yml
---
Name: myroutes
After: framework/routes#coreroutes
---
Director:
rules:
'test' : 'TestController'
答案 0 :(得分:3)
我认为您不需要index
静态中的url_handlers
引用。如果请求在index
没有条目的情况下到达控制器,则会自动调用allowed_actions
。
另一个提示是,您可能会在访问当前SS_HTTPRequest
实例的问题时遇到问题。而不是$this->request->getVar('foo')
向$request
添加index()
arg。 SS会自动将SS_HTTPRequest
的当前实例作为第一个arg传递给所有控制器方法。
无论如何,取决于转储payment->getPaymentUrl()
时实际 URL的结果,我也怀疑它。您是否已将网络服务器的访问日志保留在第二次/双重请求发生时查看URL的样子?
答案 1 :(得分:3)
我发现了问题所在。它与Silverstripe无关,但我注意到我的Chrome浏览器正在调用我在按Enter键之前在位置栏中输入的网站。当我切换标签时也会这样做。所以,是的,这将导致多个调用,以及数据库中的多个行...
这是谷歌浏览器的预取功能的结果,它试图在导航到页面之前缓存页面。我认为这是一个愚蠢的功能,导致了大量不必要的流量,但我确实需要考虑它。
奇怪的是,当没有重定向时问题不会发生,因此这表明在这些情况下,chrome正在显示缓存页面而不执行新请求。重定向可能会使该缓存无效,从而强制对该URL进行两次点击...
此外,它可能不是生产环境中的问题,因为重定向只会在表单发布后调用,而不会在导航栏中输入。但还是......
谢谢大家的帮助!值得赞赏的是:)
答案 2 :(得分:2)
我认为您的主要问题是您从Page_Controller
继承了子类。如果您的控制器不是页面控制器(例如,链接到SiteTree实例的控制器),则应该从Controller
继承。
这样的东西对我有用,并且不会产生任何重复的条目:
class TestController extends Controller
{
private static $allowed_actions = array(
'result',
);
private static $url_handlers = array(
'result/$Code' => 'result',
);
public function index() {
// process request and write DataObject
}
public function result() {
$code = $this->request->param('Code');
// do soemthing with the result code
}
}