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.
Related
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.
I am currently busy with a PSR-7 project with responses and requests.
Currently we are setting up an application in our index.php by doing something like:
$app = new Application();
$app->loadConfiguration(
'../config/global.yml',
);
// Should return the response?
$app->run((new ServerRequestFactory())->createServerRequestFromGlobals());
Here the run method also calls an emit method that is responsible for sending the headers and printing the body of the response.
The request and respons are now linked together in one call which makes it hard to test since you don't want to send the response with the headers straight to PHPUnit.
I have removed the emit call in the chain of the run method and added this to the index after the run method call:
// Send the response.
$app->send();
This way they are decoupled but the downside is I now have to hold a instance of my response in a response property inside my Application.php($app) class.
I want to move the response instance to the response class itself but my co-workers thinks a class should never hold an instance of itself. Yet when I look at frameworks this happens quite a lot. Is he right about this?
What arguments can I make to decouple my request and response besides easier testing?
I am pretty new to unit testing, one of the arguments I have already heard is that I should not test the full application anyways but rather separate components and therefore should not be worried about de-coupling the request and response.
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.
I have spent the past few days integrating Slim API to handle some PHP web services. The first few services utilized GET which was straight forward and had no problems. However, when trying to integrate some POST methods, I am receiving no response from the service. I have tried even just a simple echo to see if the service is being called. In every case, there is no return. Code below, some of the methods have been removed for clarity.
Any reason the POST method is unresponsive? Thanks! viv
$app->get('/login/:un/:pw/:type','login');
$app->get('/browseMO/:prm1/:prm2', 'browseMedia');
$app->get('/usersReviews/:userID','usersReviews');
$app->get('/pubsReviews/:userID','pubsReviews');
$app->get('/productReviews/:productID','getProductReviews');
$app->get('/productAvg/:productID','averageReviewsByOProduct');
$app->post('/userUpd','updateUserInfo');
$app->run();
function averageReviewsByOProduct($productID){
reviews::getAvgReviewByProduct($productID);
}
function browseMedia($param1, $param2){
browseMediaObjects::getMedia($param1, $param2);
}
function updateUserInfo(){
// $request = Slim::getInstance()->request();
// $body = $request->getBody();
echo "UPDATE CALLED"; // never reached
}
Try creating an anonymous function in the slim post declaration and see if the function gets call. If it doesn't, it's something with slim. If it does, it's something with your code.
$app->post('/userUpd',function() use ($app) {
echo 'Test';
});
If that doesn't work, make sure you are returning your data correctly. For instance the above returns data correctly for an AJAX call that expects a text string response.
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);
}