SilverStripe:控制器索引被调用两次
SilverStripe: Controller index is called twice
我在使用 Dutch psp Mollie 进行结帐测试时遇到问题。问题与 Mollie 无关。发生的情况是下面的索引函数有时会被调用两次,导致我的销售额 table 中有两条记录。我有点不知所措,为什么会这样。下面我粘贴了导致奇怪行为的测试代码。我已经尝试过更改路线,但无济于事。即使我将代码移动到路由 /test/send
,或者当我 link 将 /test
存根移动到另一个函数时,也会发生同样的情况,例如 '' => 'send'
.
数据对象"Sale"除了默认的$db和$has_something等没有额外的代码
更新:我删除了所有与 Mollie 相关的代码,应用程序仍然在做同样的事情。我认为重定向与它有关,因为当我删除它时,问题并没有浮出水面(它只在我删除它后第一次重新加载时发生,之后,重新加载只会导致数据库中的一行)。当重新加载到位时,它会更频繁地发生(但我仍然无法真正预测何时或为什么)。
更新2:我尝试了全新安装,但仍然是同样的问题。由于网站托管在 LEMP 堆栈上,我还尝试在 LAMP 堆栈上进行全新安装。还是一样的问题...
更新 3:我制作了一个仍然显示相同行为的最小代码示例,并相应地更新了下面的代码
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'
我认为您不需要 url_handlers
静态中的 index
引用。如果请求到达控制器而没有在 allowed_actions
中输入,index
会自动调用。
另一个提示是,您可能会在访问当前的 SS_HTTPRequest
实例时遇到问题。在 index()
中添加 $request
arg 而不是 $this->request->getVar('foo')
。 SS 自动将 SS_HTTPRequest
的当前实例作为第一个参数传递给所有控制器方法。
无论如何,根据 actual URL 转储 payment->getPaymentUrl()
时的结果,我也怀疑这一点。您是否跟踪了您的网络服务器的访问日志以查看每当发生第二个/双重请求时 URL 是什么样子?
我认为您的主要问题是您从 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
}
}
我找到问题所在了。它与 Silverstripe 无关,但我注意到我的 Chrome 浏览器正在调用我在按回车键之前在地址栏中输入的站点。当我切换标签时它也会这样做。所以是的,这将导致不止一次调用,并且数据库中不止一行......
这是 google chrome 的预取功能的结果,它会在您导航到页面之前尝试缓存页面。我认为这是一个愚蠢的功能,会导致大量不必要的流量,但我确实需要考虑到这一点。
奇怪的是,当没有重定向时,问题不会发生,所以这表明在这些情况下,chrome 显示缓存页面而不执行新请求。重定向可能会使该缓存无效,从而强制两次点击 url...
此外,在生产环境中这可能不是问题,因为重定向只会在表单 post 之后调用,而不会在导航栏中输入。但还是...
谢谢大家的帮助!不胜感激:)
我在使用 Dutch psp Mollie 进行结帐测试时遇到问题。问题与 Mollie 无关。发生的情况是下面的索引函数有时会被调用两次,导致我的销售额 table 中有两条记录。我有点不知所措,为什么会这样。下面我粘贴了导致奇怪行为的测试代码。我已经尝试过更改路线,但无济于事。即使我将代码移动到路由 /test/send
,或者当我 link 将 /test
存根移动到另一个函数时,也会发生同样的情况,例如 '' => 'send'
.
数据对象"Sale"除了默认的$db和$has_something等没有额外的代码
更新:我删除了所有与 Mollie 相关的代码,应用程序仍然在做同样的事情。我认为重定向与它有关,因为当我删除它时,问题并没有浮出水面(它只在我删除它后第一次重新加载时发生,之后,重新加载只会导致数据库中的一行)。当重新加载到位时,它会更频繁地发生(但我仍然无法真正预测何时或为什么)。
更新2:我尝试了全新安装,但仍然是同样的问题。由于网站托管在 LEMP 堆栈上,我还尝试在 LAMP 堆栈上进行全新安装。还是一样的问题...
更新 3:我制作了一个仍然显示相同行为的最小代码示例,并相应地更新了下面的代码
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'
我认为您不需要 url_handlers
静态中的 index
引用。如果请求到达控制器而没有在 allowed_actions
中输入,index
会自动调用。
另一个提示是,您可能会在访问当前的 SS_HTTPRequest
实例时遇到问题。在 index()
中添加 $request
arg 而不是 $this->request->getVar('foo')
。 SS 自动将 SS_HTTPRequest
的当前实例作为第一个参数传递给所有控制器方法。
无论如何,根据 actual URL 转储 payment->getPaymentUrl()
时的结果,我也怀疑这一点。您是否跟踪了您的网络服务器的访问日志以查看每当发生第二个/双重请求时 URL 是什么样子?
我认为您的主要问题是您从 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
}
}
我找到问题所在了。它与 Silverstripe 无关,但我注意到我的 Chrome 浏览器正在调用我在按回车键之前在地址栏中输入的站点。当我切换标签时它也会这样做。所以是的,这将导致不止一次调用,并且数据库中不止一行......
这是 google chrome 的预取功能的结果,它会在您导航到页面之前尝试缓存页面。我认为这是一个愚蠢的功能,会导致大量不必要的流量,但我确实需要考虑到这一点。
奇怪的是,当没有重定向时,问题不会发生,所以这表明在这些情况下,chrome 显示缓存页面而不执行新请求。重定向可能会使该缓存无效,从而强制两次点击 url...
此外,在生产环境中这可能不是问题,因为重定向只会在表单 post 之后调用,而不会在导航栏中输入。但还是...
谢谢大家的帮助!不胜感激:)