Ernes
October 1, 2019, 1:35pm
1
I made a function to update the password of an user in my DB like this:
public function updatePatientPassword($email, $old_password, $new_password){
$dbPassword = $this->readPasswordByEmail($email);
if($dbPassword == $old_password){
$stmt = $this->conn->prepare("UPDATE usersSET password = ? WHERE email = ?");
$stmt->bind_param("ss", $new_password, $email);
if($stmt->execute()){
return PASSWORD_CHANGED;
}
else{
return PASSWORD_NOT_CHANGED;
}
}
else{
return PASSWORD_DONT_MATCH;
}
}
And in the index.php I made a PUT request like this:
$app->put('/updateUserPassword', function(Request $request, Response $response) {
$request_data = $request->getParsedBody();
if(!emptyParameters(array('email', 'old_password', 'new_password'), $request, $response)){
$request_data = $request->getParsedBody();
$email = $request_data['email'];
$old_password = $request_data['old_password'];
$new_password = $request_data['new_password'];
$db = new DbOperations;
$result = $db->updateUserPassword($email, $old_password, $new_password);
if($result == PASSWORD_CHANGED){
$message = array();
$message['Error'] = false;
$message['Result'] = 'Password changed';
$response->getBody()->write(json_encode($message));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(200);
}
elseif($result == PASSWORD_NOT_CHANGED){
$message = array();
$message['Error'] = true;
$message['Result'] = 'Password not changed';
$response->getBody()->write(json_encode($message));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(200);
}
elseif($result == PASSWORD_DONT_MATCH){
$message = array();
$message['Error'] = true;
$message['Result'] = 'Password incorrect';
$response->getBody()->write(json_encode($message));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(200);
}
}
else{
return $response
->withHeader('Content-type', 'application/json')
->withStatus(422);
}
});
The problem is when I try the request using postman cuz it tells me that there are empty parameters but if instead of $app->put I use $app->post there are no erros.
Would you know why this is happening?
Thx
odan
October 2, 2019, 7:52am
2
Hi @Ernes
I think you need $app->addBodyParsingMiddleware();
for PUT with JSON or XML payload.
Ernes
October 2, 2019, 1:50pm
3
So instead of $app->post I have to write $app->addBodyParsingMiddleware();
?
odan
October 2, 2019, 2:36pm
4
I mean you have to add the BodyParsingMiddleware
in your bootstrap file.
Example:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
$app->addBodyParsingMiddleware(); // <<<---- here
$app->addRoutingMiddleware();
$app->addErrorMiddleware(true, true, true);
$app->put('/users/password', function (Request $request, Response $response, $args): Response {
$data = $request->getParsedBody();
$html = var_export($data, true);
$response->getBody()->write($html);
return $response;
});
$app->run();
Read more: https://akrabat.com/receiving-input-into-a-slim-4-application/
Ernes
October 2, 2019, 3:02pm
5
Nope, It’s still telling that the parameters are empty, but when I make a GET or a POST with parameters there are no errors
odan
October 2, 2019, 6:54pm
6
The BodyParsingMiddleware will only parse the body if the request header Content-Type
contains a supported value. Supported values are:
application/json
application/x-www-form-urlencoded
application/xml
text/xml
What Content-Type
do you use in your PUT request?
Can you show us an example request?
Edit : I have testet the PUT
method succesfully without the MethodOverrideMiddleware
.
Here is the code:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
//$app->setBasePath('/slim4-hello-world');
$app->addBodyParsingMiddleware(); // <<<--- add this middleware!
$app->addRoutingMiddleware();
$app->addErrorMiddleware(true, true, true);
$app->get('/', function (Request $request, Response $response, $args): Response {
$response->getBody()->write('Hello, World');
return $response;
});
$app->put('/users/password', function (Request $request, Response $response, $args): Response {
$data = $request->getParsedBody();
$response = $response->withHeader('Content-Type', 'application/json');
$response->getBody()->write(json_encode($data));
return $response;
});
$app->run();
Make sure that you set the correct Content-Type and JSON Request body in postman:
rryyyk
October 10, 2019, 3:14am
8
I had some PUT urls in a rest api i wrote a while ago in slim 3 and I got bored of trying to make it work…
So I just parsed the body myself, I have a few guys around that know mime stuff so we stitched this together, not sure how good the implementation is but it certainly worked for what i needed it to do
function parseMultipartFormBody($data)
{
$return = ;
//all data up to first \r\n is mime boundary
$boundary = substr($data, 0, (strpos($data, "\r\n")));
//split based on boundary and filter out garbage
$sections = array_filter(explode($boundary, $data));
foreach ($sections as $section)
{
$name;
$value;
$matches;
if (preg_match('#\r\nContent-Disposition:\s+form-data;\s+name="(.+)"\r\n\r\n#', $section, $matches))
{
//name is capture group second match
$name = $matches[1];
//start of value is index of name match + length of name match
$start = strpos($section, $matches[0]) + strlen($matches[0]);
//take the rest of string from end of name to boundary as data could have valid \r\n
$value = substr($section, $start, strlen($section));
//strip the trailing feed
$value = preg_replace('#\r\n$#', '', $value);
$return[$name] = $value;
}
}
return $return;
}