php Zend 框架,$this->_forward 在做什么

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1647594/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:23:31  来源:igfitidea点击:

Zend Framework, what $this->_forward is doing

phpzend-framework

提问by RageZ

I would like someone to explain me what _forward is exactly doing, I cannot see if _forward is also rendering the attached view to the action or just executing the action.

我希望有人向我解释 _forward 到底在做什么,我看不到 _forward 是否也在将附加视图渲染到操作或只是执行操作。

Also is it possible to pass argument to $this->action in a view script ?

是否可以在视图脚本中将参数传递给 $this->action ?

More generally my problem is how to code a confirmation page, let's say the user input some stuff and you want to show him confirmation, is forward is mean for that case ?

更一般地说,我的问题是如何编写确认页面,假设用户输入了一些东西,你想向他展示确认,转发是否意味着这种情况?

回答by smack0007

_forward is an internal redirect. Where as _redirect sends a header that tells the client's browser to go to some other URL, _forward tells the Dispatcher to internally redirect the request somewhere else.

_forward 是内部重定向。当 _redirect 发送一个标头,告诉客户端的浏览器转到某个其他 URL 时,_forward 告诉 Dispatcher 在内部将请求重定向到其他地方。

If you consider the normal dispatch order of:

如果您考虑以下正常发货顺序:

 preDispatch()
 someAction()
 postDispatch()

Calling _forward at any point in that progression will cause the following steps to not be executed. So if you call _forward in preDispatch(), someAction() will not be called and so on. If you _forward() in someAction() and you are using the viewRenderer action helper to render your views (you are letting the framework choose what view script to render), then no view script will be rendered in someAction().

在该进程中的任何一点调用 _forward 将导致以下步骤无法执行。因此,如果您在 preDispatch() 中调用 _forward,则不会调用 someAction() 等等。如果您在 someAction() 中使用 _forward() 并且您正在使用 viewRenderer 操作助手来呈现您的视图(您让框架选择要呈现的视图脚本),那么在 someAction() 中将不会呈现任何视图脚本。

When the request is forwarded to the new Controller / Module the entire dispatch process will be repeated there.

当请求被转发到新的控制器/模块时,整个调度过程将在那里重复。

You can find out what action is being dispatched by using:

您可以使用以下命令找出正在调度的操作:

 $action = $this->getRequest()->getParam('action');

$action will be the url form of the action so if the method is name 'someKindOfAction', $action will contain 'some-kind-of'. You can do this as well for controllers and modules.

$action 将是动作的 url 形式,因此如果方法名称为“someKindOfAction”,则 $action 将包含“some-kind-of”。您也可以对控制器和模块执行此操作。

回答by Karim

My experience with Zend is limited and I hope I'm not showing you something you've already seen but according to the docs(12.7.6. Utility Methods):

我对 Zend 的经验是有限的,我希望我不会向您展示您已经看过的东西,但根据文档(12.7.6. Utility Methods):

_forward($action, $controller = null, $module = null, array $params = null): perform another action. If called in preDispatch(), the currently requested action will be skipped in favor of the new one. Otherwise, after the current action is processed, the action requested in _forward() will be executed.

_forward($action, $controller = null, $module = null, array $params = null):执行另一个动作。如果在 preDispatch() 中调用,当前请求的操作将被跳过以支持新的操作。否则,在处理完当前动作后,将执行 _forward() 中请求的动作。

So it sounds like the context of when it's called matters. In the latter case it will first execute the action from which it's been called thenexecute the forwarded action. The exception is when it's being called from the preDispatchhandler

所以这听起来像是什么时候被称为重要的上下文。在后一种情况下,它将首先执行从中调用它的操作,然后执行转发的操作。例外是从preDispatch处理程序调用它时

回答by Dan

I think it's important to note that _forward is very inefficient, and you should always call your method directly. When you do a _forward, the init(), pre and post dispatch run again. Depending on what you have in your init, you can run (and insert) the same database record twice.

我认为需要注意的是 _forward 非常低效,您应该始终直接调用您的方法。当您执行 _forward 时,init()、pre 和 post 调度将再次运行。根据您在 init 中的内容,您可以运行(并插入)相同的数据库记录两次。

It is easy to use but wasteful. If you profile your code, and are banging your head to why everything is being called twice, _forward is the reason. If your like me and you instantiate a few objects in the init() for use throughout the class, you wind up instantiating everything twice! I did load testing on my code and I got better performance by calling the action name directly, like foo(), instead of _forward('foo');

它易于使用但很浪费。如果您分析您的代码,并且正在思考为什么所有东西都被调用两次,那么 _forward 就是原因。如果您像我一样在 init() 中实例化了一些对象以在整个类中使用,那么您最终会将所有东西实例化两次!我对我的代码进行了负载测试,通过直接调用操作名称(例如 foo() 而不是 _forward('foo');)获得了更好的性能;

Another off topic tip I think most people know, is it use single quotes wherever possible, sine the PHP parser has to check a string for embedded variables. I don't know how much real world performance this will give, especially if you are using an opcode cache, but it's a best practice.

我认为大多数人都知道的另一个题外话是它尽可能使用单引号,因为 PHP 解析器必须检查字符串中的嵌入变量。我不知道这会带来多少现实世界的性能,特别是如果您使用操作码缓存,但这是最佳实践。

回答by Tomá? Fejfar

Forward is ment to be used when external redirect is not the right options. Use case (bit ankward, but best i can make up): You have a form that can add your pet (either dog or cat). You have different models for each. You include a select in your form to select dog / cat. Then in your action you do:

当外部重定向不是正确的选项时,要使用转发。用例(有点尴尬,但最好我能弥补):你有一个可以添加你的宠物(狗或猫)的表格。你有不同的模型。您在表单中包含一个选择以选择狗/猫。然后在你的行动中:

if($form->isValid($_POST)){  
  switch($form->select->getValue()){
    case "dog":
      $this->_forward('add-dog','pets','default');
      break;
    case "cat":
      $this->_forward('add-cat','pets','default');
      break;    
  }
}

And you handle different things for cats and dogs in separate actions. The advantage of this is that ALL the parameters are sent along. In constrast when you'd used $this->_redirect() the POST parameters will be lost. That is in some cases intended behaviour (for example after adding a comment you make a redirect to comments list page to avoid double posts and the message "page needs to send data again...".

你在不同的动作中为猫和狗处理不同的事情。这样做的好处是所有参数都会一起发送。相反,当您使用 $this->_redirect() 时,POST 参数将丢失。这在某些情况下是预期的行为(例如,在添加评论后,您重定向到评论列表页面以避免重复发布和消息“页面需要再次发送数据......”。

回答by Justin

A part of the Framework docs I swear used to be there explained the dispatch workflow at a general level. Theres this diagram, but its awefully complicated to explain what _forward does.

我发誓曾经在那里发誓的框架文档的一部分在一般级别解释了调度工作流程。有这个图,但解释 _forward 的作用非常复杂。

When in an action _forward will set $request->isDispatched = false, and set up the request to call the controller/action specified in _forward. During postDispatch, the isDispatched is checked - if its false, the whole thing runs again using the new request.

在动作中 _forward 将设置$request->isDispatched = false,并设置请求以调用 _forward 中指定的控制器/动作。在 postDispatch 期间,检查 isDispatched - 如果它为 false,则使用新请求再次运行整个过程。

So... If in your action you're manually rendering views, they'll still get rendered. Everything in the action will still happen, its just another action will ALSO happen afterwards.

所以......如果在你的操作中你手动渲染视图,它们仍然会被渲染。动作中的一切仍然会发生,它只是另一个动作也会在之后发生。

[edit after question edit]

[问题编辑后编辑]

Forward is not meant for the response/confirm-after-post - use a redirect for that. $this->_helper->redirector->gotoUrl()etc.

转发不适用于响应/确认后发布 - 为此使用重定向。 $this->_helper->redirector->gotoUrl()等等。