Zend _forward() does not work in preDispatch()? - php

Im currently building a controller from my Zend MVC application which would only be used as json service to populate the page. I want to restrict the users to use only GET method to access this end point(for some security reasons).
I followed this post _forward() in Zend does not work? but could not get working.
I am using the preDispatch to detect the non-get requests and would like to forward to errorAction in the same controller. My code looks likes this,
public function preDispatch(){
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender();
//Restrict this Controller access to Http GET method
if(!($this->getRequest()->isGet())){
return $this->_forward('error');
}
}
public function errorAction(){
$this->getResponse()->setHttpResponseCode(501);
echo "Requested Method is not Implemented";
}
When I test the page with a post request, it throws
PHP Fatal error: Maximum execution time of 30 seconds exceeded
I got it working with
$this->_redirect("service/error");
Wondering if it is the only/best way to handle this situation.
Any help would be really appreciated. Thanks in advance.

The reason that calling _forward doesn't work is because the request method doesn't change so you end up in an infinite loop trying to forward to the error action since the request is always POST.
_forward works by modifying the module, controller, and action that will be called when the request is dispatched, _redirect actually returns a 302 redirect and results in an additional HTTP request by the browser.
Either method is okay, but I'd prefer to go with _forward since it won't require an additional HTTP request (but you still guarantee the POST request is denied).
This code should work for you:
if(!($this->getRequest()->isGet())){
// change the request method - this only changes internally
$_SERVER['REQUEST_METHOD'] = 'GET';
// forward the request to the error action - preDispatch is called again
$this->_forward('error');
// This is an alternate to using _forward, but is virtually the same
// You still need to override $_SERVER['REQUEST_METHOD'] to do this
$this->getRequest()
->setActionName('error')
->setDispatched(false);
}

Related

Phpo create endpoint and intercept methods

Hi i'm pretty new on create endpoints in php.
Now i have to create a little endpoint to intercept some updates from electronic invoice service.
From admin panel of the service i can specify endpoint url where my application is located.
For example I indicate: www.example.com/api/endpoint/index.php
NOte: If I set only www.example.com/api/endpoint/, panel admin tell me there is an error - page not found
Now in the admin panel I see I can intercept these POST methods:
/createInvoice
/createNotification
But i don't undertand HOW to differentiate there 2 methods...
Actually in my index.php i've:
<?php
function call_create_invoice(
...
);
function call_create_notification(
...
);
header('Content-Type: application/json; charset=utf-8');
var_dump($_POST);
If I use POSTMAN to do some test using POST call, i can correctly see $_POST parameters sent.... but i don't understand how to:
call call_create_invoice function if /createInvoice is called
call call_create_notification function if /createNotification is called
If you would stick to vanilla PHP, you need to parse the request URI to call the desired function like:
$path = $SERVER['REQUEST_URI'];
switch($path) {
case('/createInvoice'):
call_create_invoice();
break;
case('/createNotification'):
call_create_notification();
break;
}
As requirements grow, it may make sense to use a minimal PHP framework with routing functionality, such as Laravel Lumen.

Zend Framework Call to undefined method Zend\Http\Request::getServer()

I have a controller, that when request is Post, it gets the request, and from there I get REMOTE_ADDR, and REQUEST_TIME. The code works just fine, I get that information that I need.
However, I am writing an integration test for the entire flow of my web app, and when I send the request, I get Call to undefined method Zend\Http\Request::getServer() when it gets to that point of my action in the controller.
$server = $this->getRequest()->getServer();
$remoteAddr = $server['REMOTE_ADDR'];
$timestamp = $server['REQUEST_TIME'];
When I do
$request = $this->getRequest();
and look at $request, it has method, uri, queryParams, postParams, fileParams, version, headers, metadata and content.
postData has everything I'm sending via my test, but it crashes when it gets to the point of getting the server.
Any ideas?
Thank you.
The request class your application is using is Zend\Http\PhpEnvironment\Request, which extends Zend\Http\Request with some PHP-specific stuff like getServer(). Change your test to use that and it should work fine.

Correct ZF2 Redirect behaviour

I have been using ZF2 for a few months now and I am confused about how the controller redirect is supposed to work. Is it supposed to immediately stop processing the current action, and send the redirect request? Or is it supposed to complete processing of the current action, then perform the redirect?
Pretty fundamental question, huh?
Back in ZF1, I am pretty sure the redirection took place immediately (unlike forward(), which was stored up until the current action was completed). I assumed it was the same case in ZF2 and so far that has been my experience, however today suddenly I find that controllers are storing the redirect up, and sending it at the end of the current action.
Here's an example:
public function testAction()
{
$this->redirect()->toUrl('/info');
echo 'Hello';
die();
}
In this case, the action will echo 'Hello' and then die.
I think that this is probably the normal course of events and that I have just (by sheer fluke) not noticed it before today. I just want to be sure though, before I go back and alter all my controllers. (The alternative explanation is that somewhere in my config I am destroying/overriding the redirect plugin).
In Zend Framework 2.*, execution is never halted (except for a particular upload progress handler and some locations in the console component).
Therefore, you have to stop your controller from dispatching manually:
public function testAction()
{
return $this->redirect()->toUrl('/info');
echo 'Hello'; // will never be executed
}
To be more precise, as of this callback (used when triggering a Zend\Mvc\MvcEvent::EVENT_DISPATCH), any listener to the dispatch event of an application that returns a ResponseInterface causes a "short-circuit" to the application finish event.
Short-circuiting (in the Zend\Mvc\Application) basically causes subsequent events to be skipped and forces the application to directly trigger the Zend\Mvc\MvcEvent::EVENT_FINISH event, therefore echoing the response (happens in a listener of the finish event).
In this particular controller action, the call to the $this->redirect()->toUrl('...') helper produces a Zend\Http\Response, and since we directly return it, the short-circuit is triggered.

Phil Sturgeon’s REST API always returning: status:0, error:Unknown method

I am always getting the this error.
{"status":false,"error":"Unknown method."}
But all syntax are correct from my side. because everything is working fine on the browser but same URL integration on the devices gives the 'unknown method error'.
I am using this 'get' method. Sample URL
SITEURL/api/login/test?req_type=custom
Am I missing something while integrating? Perhaps a setting? I have just included the library and rest config file.
I think your problem is the name of controller is the same with the name of method try to make a test:
if the name of your controller is:
class Test extends REST_Controller{
//your method name is different from the name of controller class
public function testget_get(){
echo $this->response(array('test'=> 'test'), 200);
}
}
I have experienced this problem on hmvc structure.
You also need to check that from device which method your are getting means they are sending 'POST' or 'GET' so you can update your function name accordingly.
In my case I have done the function name as _get to the methods but from device methods of sending parameter is 'POST' which I am trying to access as 'GET'.
So please cross check this once.
When you create a method with the library, you need to append the type of request you are going to make to it.
So, if your method is test, and you are making a GET request to it, it needs to look like this:
function test_get(){
...
}
Same with POST requests
function test_post(){
...
}
Same with PUT, and DELETE as well.
NB This is only a guess since you didn't include any of your code for some reason.

In Kohana/PHP, how can send execution to a new controller/action?

In PHP/Kohana, I have controller action method which does some processing. When it is finished, I want to send it to another controller, e.g.:
public function action_import_csv()
{
Kohana_Import_Driver_Csv::process_files_from_csv_to_mysql($this->import_directory);
//url::redirect(Route::get('backend_application')->uri()); //undefined method URL::redirect()
//redirect(Route::get('backend_application')->uri(), null); //undefined function
}
According to this documentation at least the first redirect should work. I'm using Kohana 3.
How can I send execution from this controller action method to a new controller/action?
Addendum
For some reason, url::redirect is not available, here is the code completion I get for url:::
#bharath, I tried url::current() and got this error:
The problem is that you are looking at the Kohana 2 docs. Go to the kohana homepage and find the correct docs. Also, for some reason, everyone is giving you Kohana 2 answers even though you stated you're working with 3.
To redirect, do this from the context of a controller:
$this->request->redirect($something);
$something could be:
controller
controller/action
http://url.com
Here are the api docs for the redirect method (note that this uses url::site to parse the url; you may want to look at the source of that method too.
i am not very sure but i think you can simple use the redirect() function passing in the other controller you want to send to with any parameters
example
redirect(controllername/method)
Shouldn't that be :
url::redirect('controller/method');
And if it doesn't work, you probably had some output before calling the redirect (you'll probably get the "Headers already sent" error when that is the case).

Categories