I'm trying to rebuild my PHP API with SlimPHP v3 + PDO. The problem is I'm stuck with retrieving attributes passed in POST method. Here is part of my index.php file, I decided just to echo the variable to test if it's working.
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require '../vendor/autoload.php';
require_once '../includes/UserOperation.php';
require_once '../includes/TweetOperation.php';
$app = new \Slim\App([
'settings' => [
'displayErrorDetails' => true
]
]);
//---UserOperation.php---//
//registering a new user
$app->post('/register', function (Request $request, Response $response) {
if (isTheseParametersAvailable(array('name', 'email', 'password', 'picture_path'))) {
$requestData = $request->getParsedBody();
$name = $request->getParsedBody()['name'];
$email = $requestData['email'];
$password = $requestData['password'];
$picture_path = $requestData['picture_path'];
echo "Hello " .$name;
}
});
//function to check parameters
function isTheseParametersAvailable($required_fields)
{
$error = false;
$error_fields = "";
$request_params = $_REQUEST;
foreach ($required_fields as $field) {
if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) {
$error = true;
$error_fields .= $field . ', ';
}
}
if ($error) {
$response = array();
$response["error"] = true;
$response["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty';
echo json_encode($response);
return false;
}
return true;
}
$app->run();
The link for my website looks for example like below,but $name variable that I'm trying to echo remains empty.
https://myweblink/register?name=test&email=test#mail.com&password=pass&picture_path=lolololo
Related
I have already work this in php. Here is my working code:
$request = array(
'DomainNames' => $domain_names
);
$response = dreamScapeAPI('DomainCheck', $request);
$available = false;
$alt_domains = array(); // Alternative to user's expected domain names
if (!is_soap_fault($response)) {
// Successfully checked the availability of the domains
if (isset($response->APIResponse->AvailabilityList)) {
$availabilityList = $response->APIResponse->AvailabilityList;
foreach ($availabilityList as $list) {
if ($list->Available){
if ($domain == $list->Item) {
$available = true; // user prefered domain found
}
else {
$alt_domains[] = $list->Item;
}
}
}
}
else {
$error = $response->APIResponse->Errors;
foreach ($error as $e) {
$api_error = $e->Message;
//echo $e->Item . ' - ' . $e->Message . '<br />';
}
}
}
function dreamScapeAPI($method, $data = null) {
$reseller_api_soap_client = "";
$soap_location = 'http://soap.secureapi.com.au/API-2.1';
$wsdl_location = 'http://soap.secureapi.com.au/wsdl/API-2.1.wsdl';
$authenticate = array();
$authenticate['AuthenticateRequest'] = array();
$authenticate['AuthenticateRequest']['ResellerID'] = '**';
$authenticate['AuthenticateRequest']['APIKey'] = '**';
//convert $authenticate to a soap variable
$authenticate['AuthenticateRequest'] = new SoapVar($authenticate['AuthenticateRequest'], SOAP_ENC_OBJECT);
$authenticate = new SoapVar($authenticate, SOAP_ENC_OBJECT);
$header = new SoapHeader($soap_location, 'Authenticate', $authenticate, false);
$reseller_api_soap_client = new SoapClient($wsdl_location, array('soap_version' => SOAP_1_2, 'cache_wsdl' => WSDL_CACHE_NONE));
$reseller_api_soap_client->__setSoapHeaders(array($header));
$prepared_data = $data != null ? array($data) : array();
try {
$response = $reseller_api_soap_client->__soapCall($method, $prepared_data);
} catch (SoapFault $response) { }
return $response;
}
I tried with this : https://github.com/dan-power/node-dreamscape
But domain search can not work properly. Mainly, I want it on nodejs using nodejs dreamscape api but this method is not available on nodejs.
Here is my working demo: click here
I'm trying to make php get, but it always seems to call haveEmptyParameters.
The call is to getInformation() and that works fine. Just the parameters never seem to go through? Or maybe there is another error?
$app->get('/getinformation', function(Request $request, Response $response){
if(!haveEmptyParameters(array('field', 'username'), $request, $response)){
$request_data = $request->getParsedBody();
$field = $request_data['field'];
$username = $request_data['username'];
$db = new DbOperations;
$result = $db->getInformation($field,$username);
$response_data = array();
$response_data['error'] = false;
$response_data['users'] = $result;
$response->write(json_encode($response_data));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(200);
}
});
function haveEmptyParameters($required_params, $request, $response){
$error = false;
$error_params = '';
$request_params = $request->getParsedBody();
foreach($required_params as $param){
if(!isset($request_params[$param]) || strlen($request_params[$param])<=0){
$error = true;
$error_params .= $param . ', ';
}
}
if($error){
$error_detail = array();
$error_detail['error'] = true;
$error_detail['message'] = 'Required parameters ' . substr($error_params, 0, -2) . ' are missing or empty';
$response->write(json_encode($error_detail));
}
return $error;
}
$app->run();
-----Postman Output of error-------
{"error":true,"message":"Required parameters field, username are missing or empty"}
I have Yii2 project. And there I also have api written by Symfony.
In Symfony part I have method in the class which send request to Yii controller.
$buzz = $this->container->get('buzz');
$buzz->getClient()->setVerifyHost(false);
$buzz->getClient()->setVerifyPeer(false);
$buzz->getClient()->setTimeOut(false);
$url = $this->container->getParameter('integra_sync_prices');
$sendResult = $buzz->post($url, array('authorization' => $this->container->getParameter('load_token')), array('products' =>
json_encode($productPrices)));
$resultJson = json_decode($sendResult->getContent(), true);
if (isset($resultJson['error']))
throw new \Exception('Site: '.$resultJson['error'], 500);
class IntegraController extends Controller{
public function actionIndex()
{
Yii::$app->response->format = Response::FORMAT_JSON;
$headers = Yii::$app->request->getHeaders();
foreach ($headers as $key => $value) {
if(strtolower(trim($key)) == 'authorization') {
$token = trim($value[0]);
break;
}
}
$products = json_decode(Yii::$app->request->post('products'));
$post_products = Yii::$app->request->post('products');
if('111' == $token) {
if(isset($post_products) && $products) {
foreach ($products as $product) {
echo $product->price." = ".$product->productId."<br>";
Yii::$app->db->createCommand("UPDATE oc_product SET quantity = '" . (int)$product->quantity . "', price = '" . (float)$product->price . "' WHERE product_id = '" . (int)$product->productId . "'")->execute();
}
$json['success'] = 'complete';
} else {
$json['error'] = 'empty data';
}
} else {
$json['error'] = 'authorization error';
}
Yii::$app->controller->enableCsrfValidation = false;
echo json_encode($json);
}
I expect that data in my database will be updated by this controller. But there in nothing changes.
What do I do wrong? Maybe I should send some another headers? Thanks a lot )
I want to create an API using Slim for my android application. The API is very simple, i just want to save in my database data for an article. My code is shown below
<?php
error_reporting(-1);
ini_set('display_errors', 'On');
require_once '../include/DbHandler.php';
require '.././libs/Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
/**
* Verifying required params posted or not
*/
function verifyRequiredParams($required_fields) {
$error = false;
$error_fields = "";
$request_params = array();
$request_params = $_REQUEST;
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
$app = \Slim\Slim::getInstance();
parse_str($app->request()->getBody(), $request_params);
}
foreach ($required_fields as $field) {
if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) {
$error = true;
$error_fields .= $field . ', ';
}
}
if ($error) {
$response = array();
$app = \Slim\Slim::getInstance();
$response["error"] = true;
$response["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty';
echoRespnse(400, $response);
$app->stop();
}
}
/**
* Echoing json response to client
* #param String $status_code Http response code
* #param Int $response Json response
*/
function echoRespnse($status_code, $response) {
$app = \Slim\Slim::getInstance();
$app->status($status_code);
$app->contentType('application/json');
echo json_encode($response);
}
/**
* Creating new task in db
* method POST
* params - name
* url - /articles/
*
* {"error": false,
"message": "Task created successfully",
"task_id": 1}
*/
$app->post('/articles', 'authenticate', function() use ($app) {
//verifyRequiredParams(array('article'));
$response = array();
$article_image = $app->request->post('article_image');
$article_video = $app->request->post('article_video');
$article_title = $app->request->post('article_title');
$article_main_body = $app->request->post('article_main_body');
$article_tags = $app->request->post('article_tags');
$db = new DbHandler();
// creating new article
$article_id = $db->createTask($article_image,$article_video,$article_title,$article_main_body,$article_tags);
if ($article_id != NULL) {
$response["error"] = false;
$response["message"] = "Article created successfully";
$response["article_id"] = $article_id;
} else {
$response["error"] = true;
$response["message"] = "Failed to create article. Please try again";
}
echoRespnse(201, $response);
});
/**
* Listing all articles
* method GET
* url /articles
* {
"error": false,
"tasks": [
{
"id": 1,
"task": "Complete REST article by Sunday",
"status": 0,
"createdAt": "2014-01-08 23:35:45"
},
{
"id": 2,
"task": "Book bus tickets!",
"status": 0,
"createdAt": "2014-01-08 23:56:52"
}
]
}
*/
$app->get('/articles', 'authenticate', function() {
$response = array();
$db = new DbHandler();
$result = $db->getAllTasks();
$response["error"] = false;
$response["articles"] = array();
// looping through result and preparing articles array
while ($article = $result->fetch_assoc()) {
$tmp = array();
$tmp["id"] = $task["id"];
$tmp["article_image"] = $article["article_image"];
$tmp["article_video"] = $article["article_video"];
$tmp["article_title"] = $article["article_title"];
$tmp["article_main_body"] = $article["article_main_body"];
$tmp["article_tags"] = $article["article_tags"];
$tmp["created_at"] = $article["created_at"];
array_push($response["articles"], $tmp);
}
echoRespnse(200, $response);
});
/**
* Listing single task of particual user
* method GET
* url /articles/:id
* Will return 404 if the task doesn't belongs to user
*
* {
"error": false,
"id": 2,
"task": "Book bus tickets!",
"status": 0,
"createdAt": "2014-01-08 23:56:52"
}
*/
$app->get('/articles/:id', 'authenticate', function($article_id) {
$response = array();
$db = new DbHandler();
// fetch article
$result = $db->getArticle($article_id);
if ($result != NULL) {
$response["error"] = false;
$response["id"] = $result["id"];
$response["article_image"] = $result["article_image"];
$response["article_video"] = $result["article_video"];
$response["article_title"] = $result["article_title"];
$response["article_main_body"] = $result["article_main_body"];
$response["article_tags"] = $result["article_tags"];
$response["created_at"] = $result["created_at"];
echoRespnse(200, $response);
} else {
$response["error"] = true;
$response["message"] = "The requested resource doesn't exists";
echoRespnse(404, $response);
}
});
$app->run();
?>
The above, is my index.php while my .htaccess is the below
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]
The structure of my project is
include
|
-Config.php
-DbConnect.php
-DbHandler.php
libs
|
-Slim
v1
|
-.htaccess
-index.php
I have uploaded my project in an Ubuntu Droplet i created in DigitalOcean, however when i run my project i get the exception below
Uncaught exception 'InvalidArgumentException' All Route middleware must be callable'
Is there anything i should change in my servers config docs?
Slim is trying to call a function that doesn't exist.
In every route definition you have a second parameter with the value 'authenticate' (for example in your $app->post('/articles', 'authenticate', function() use ($app) {});
You have to define the authenticate function somewhere before:
function authenticate() {
echo "My authenticate logic!";
}
Take a look to the documentation.
I am using this function to check all required parameters are available or not in request before processing user request.
function verifyRequiredParams($required_fields) {
$error = false;
$error_fields = "";
$request_params = array();
$request_params = $_REQUEST;
// Handling PUT request params
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
$app = \Slim\Slim::getInstance();
parse_str($app->request()->getBody(), $request_params);
}
foreach ($required_fields as $field) {
if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) {
$error = true;
$error_fields .= $field . ', ';
}
}
if ($error) {
// Required field(s) are missing or empty
// echo error json and stop the app
$response = array();
$app = \Slim\Slim::getInstance();
$response["error"] = true;
$response["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty';
echoRespnse(400, $response);
$app->stop();
}
}
Usage is like this:
$app->post('/tasks', function() use ($app) {
// check for required params
verifyRequiredParams(array('task'));
// if OK process request.
});
function works fine if post data is of form type. like this: mobile=1234567880&otp=123456
Now i am changing the code to accept form data of JSOn type. like this: {"mobile":"0000000000","otp":"970996", "items":[{"pid":"12", "vid":"20", "pname":"amul"},{"pid":"13", "vid":"2", "pname":"dmul"}]}
This is how i am getting data.
$app->post('/tasks', function() use ($app) {
$data = json_decode(file_get_contents('php://input'), true);
$mobile = $data["mobile"];
// check for required params
verifyRequiredParams(array('task'));
// if OK process request.
});
What changes should i do now in verifyRequiredParams() to check for required params in case of JSON post data?
I suggest you don't access PHP superglobals (like $_REQUEST) in your verify method. The verifyRequiredParams should not really interfere in your application flow, but just verify the parameters and return an appropriate response. Something like this:
function verifyRequiredParams($required_fields, $request_params) {
$error = false;
$error_fields = array();
foreach ($required_fields as $field) {
if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) {
$error = true;
$error_fields[] = $field;
}
}
if ($error) {
// Required field(s) are missing or empty
return array(
'error' => true,
'message' => 'Required field(s) ' . implode(', ', $error_fields) . ' is missing or empty'
);
}
// return appropriate response when successful?
return array(
'success' => true
);
}
Depending on how your data is being submitted, you pass the appropriate array into the verify method. Here are some examples:
// directly pass in the request superglobal (for GET, POST)
$response = verifyRequiredParams(array('task'), $_REQUEST);
// or deal with PUT data
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
$app = \Slim\Slim::getInstance();
parse_str($app->request()->getBody(), $request_params);
$response = verifyRequiredParams(array('task'), $request_params);
}
// or deal with json encoded data
$data = json_decode(file_get_contents('php://input'), true);
$response = verifyRequiredParams(array('task'), $data);
Since the verifyRequiredParams now returns a response, you'll have to deal with this externally, for example:
$response = verifyRequiredParams(array('task'), $request_params);
if(isset($response['error'])){
$app = \Slim\Slim::getInstance();
echoResponse(400, $response);
$app->stop();
}
Removing superglobals and logic that ties into your application-flow from the validating method will make it easier to reuse.