Making functions from PHP work in Node.js - php

I am new here on stackoverflow and hoping to get some advice.
I am having an issue with calling 3rd party APIs successfully with node.js.
This is the full source code of node.js. I used a dummy API url for security purpose.
const express = require('express')
const app = express()
app.use(express.json())
const axios = require('axios')
const { HttpCookieAgent, HttpsCookieAgent } = require('http-cookie-agent/http')
const tough = require('tough-cookie')
const { wrapper } = require('axios-cookiejar-support');
// READ Request Handlers
app.get('/', (req, res) => {
res.send('Node.js REST API Test');
})
app.get('/api/v1/member', async (req,res)=> {
const start_ts = Date.now()
try {
const member = await findMember()
res.send({
'status': 'success',
'data': member.data
})
} catch(error) {
res.send({
'status': 'error',
'error': error
})
}
})
const findMember = async() => {
try {
const jar = new tough.CookieJar();
const client = wrapper(axios.create({ jar }));
client.post('https://example-api.com/session/start', {
Username: 'xxxxxx',
Password: 'xxxxxx'
}).then(res => {
if (res.status === 200) {
return client.get('https://example-api.com/members/find', {
params: {
emailAddress: 'user#example.com'
}
})
}
})
} catch(error) {
console.log(error)
}
}
// PORT ENVIRONMENT VARIABLE
const port = process.env.PORT || 8080
app.listen(port, () => console.log(`Listening on port ${port}..`))
The API /session/start should be called first to run the second API successfully. It's kind of a login. After first API succeeds, it get its session or cookie and reuses it for second API call, but I am not sure how to do achieve this and get it properly done.
I tried to use CookieJar, but it didn't work.
Second API will return 200 OK response if cookie or session is passed properly to second API.
But due to this, the second API response results in a 500 Internal server error.
And here is the PHP function that do the same thing. It works perfectly.
$cookie_url = dirname(__FILE__) . '/cookie.txt';
$postFields = [
'Username' => 'xxxxxx',
'Password' => 'xxxxxx'
];
$postData = json_encode($postFields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://example-api.com/session/start');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json'
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_url);
$response = curl_exec($ch);
curl_close($ch);
$respObj = json_decode($response);
$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, 'https://example-api.com/members/find?emailAddress=user#example.com');
curl_setopt($ch2, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json'
));
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_COOKIEFILE, $cookie_url);
curl_setopt($ch2, CURLOPT_COOKIEJAR, $cookie_url);
$response = curl_exec($ch2);
curl_close($ch2);
$respObj = json_decode($response);
if (!isset($respObj->Message)) {
return response()->json([
'status' => 'success',
'data' => $respObj
]);
} else {
return response()->json([
'status' => 'error',
'error' => $respObj
]);
}
As you can see from PHP code, I used a cookie file to store the session of the first API and used it again for the second API call.
Please help me how to implement the same action with node.js.
Thank you for your help.

Related

React Google Login not returning Refresh Token

First, I am using the package react-oauth/google which can be found HERE.
It's a very basic setup:
import {useGoogleLogin} from "#react-oauth/google";
And
const googleSignIn = useGoogleLogin({
onSuccess,
isSignedIn: true,
accessType: "offline", // Should this not insinuate refresh token?
scope: "https://www.googleapis.com/auth/business.manage",
responseType: "code",
prompt: "consent",
});
const onSuccess = (res) => {
console.log (res);
api.post(apiUrl() + "api/v2/gmb/success/",
{access_token: res.access_token})
.then(response => {
console.log(response.data);
// ... Do something
});
};
The response from console is:
{
access_token: 'ya29.xxxx',
token_type: 'Bearer',
expires_in: 3599,
scope: 'email profile openid https://www.googleapis.com/ ... ',
authuser: '0',
promp: 'consent',
}
I then pass to my api/v2/gmb/success/ where I store the access token, and store information gethered with said token:
$url = 'https://www.googleapis.com/oauth2/v2/userinfo?fields=name,email,id,picture,verified_email';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $access_token));
$data = json_decode(curl_exec($ch), true);
I am successful in using the access token returned in getting/setting information in Google My Business using my own API (built in PHP) api/v2/gmb/success/... But the access token expires after one hour. Should there not be a refresh token supplied from google during the initial interaction? According to This Google Doc You need a refresh token to GET a refresh token. I feel like I am missing something obvious here.
For anyone coming in on this in the future .. To get your Refresh token, once Auth has happened, you can use the following. You need to add flow: "auth-code" to the initial login in the JS ..
const googleSignIn = useGoogleLogin({
onSuccess,
onFailure,
isSignedIn: true,
accessType: "offline",
scope: "https://www.googleapis.com/auth/business.manage",
responseType: "code",
prompt: "consent",
flow: 'auth-code'
});
This will return the following:
authuser: "0"
code: "4/0AWgavdcxxxxxxxx"
prompt: "consent"
scope: "email profile https://www. ...
You then pass that code to your backend:
const onSuccess = (res) => {
console.log (res);
api.post(apiUrl() + "api/v2/gmb/success/",
{code: res.code})
.then(response => {
console.log(response.data);
// .. Do Stuff
});
};
Once there you can just use a simple CURL statement. This is written in PHP, but can be written in any back end language.
$code = $_POST['code']
$url = 'https://www.googleapis.com/oauth2/v4/token';
$curlPost = 'client_id=' . $client_id . '&redirect_uri=postmessage&client_secret=' . $client_secret . '&code=' . $code . '&grant_type=authorization_code';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code != 200)
throw new Exception('Error : Failed to receive access token -->' . print_r($data, true));
print_r($data);
Your response should come back:
Array
(
[access_token] => ya29.a0AX9G****
[expires_in] => 3599
[refresh_token] => 1//01BzUAp_l****
[scope] => https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/ ....
[token_type] => Bearer
[id_token] => eyJhbGciOiJSUzI1NiIsImtp...
)
Then you are free to grab access tokens with your refresh token as often as you'd like with the user only needing to consent a single time.

How do I send this CURL in PHP [duplicate]

Can anyone show me how to do a PHP cURL with an HTTP POST?
I want to send data like this:
username=user1, password=passuser1, gender=1
To www.example.com
I expect the cURL to return a response like result=OK. Are there any examples?
<?php
//
// A very simple PHP example that sends a HTTP POST to a remote site
//
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://www.example.com/tester.phtml");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"postvar1=value1&postvar2=value2&postvar3=value3");
// In real life you should use something like:
// curl_setopt($ch, CURLOPT_POSTFIELDS,
// http_build_query(array('postvar1' => 'value1')));
// Receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close($ch);
// Further processing ...
if ($server_output == "OK") { ... } else { ... }
?>
Procedural
// set post fields
$post = [
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
];
$ch = curl_init('http://www.example.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
// do anything you want with your response
var_dump($response);
Object oriented
<?php
// mutatis mutandis
namespace MyApp\Http;
class CurlPost
{
private $url;
private $options;
/**
* #param string $url Request URL
* #param array $options cURL options
*/
public function __construct($url, array $options = [])
{
$this->url = $url;
$this->options = $options;
}
/**
* Get the response
* #return string
* #throws \RuntimeException On cURL error
*/
public function __invoke(array $post)
{
$ch = \curl_init($this->url);
foreach ($this->options as $key => $val) {
\curl_setopt($ch, $key, $val);
}
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, \CURLOPT_POSTFIELDS, $post);
$response = \curl_exec($ch);
$error = \curl_error($ch);
$errno = \curl_errno($ch);
if (\is_resource($ch)) {
\curl_close($ch);
}
if (0 !== $errno) {
throw new \RuntimeException($error, $errno);
}
return $response;
}
}
Usage
// create curl object
$curl = new \MyApp\Http\CurlPost('http://www.example.com');
try {
// execute the request
echo $curl([
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
]);
} catch (\RuntimeException $ex) {
// catch errors
die(sprintf('Http error %s with code %d', $ex->getMessage(), $ex->getCode()));
}
Side note here: it would be best to create some kind of interface called AdapterInterface for example with getResponse() method and let the class above implement it. Then you can always swap this implementation with another adapter of your like, without any side effects to your application.
Using HTTPS / encrypting traffic
Usually there's a problem with cURL in PHP under the Windows operating system. While trying to connect to a https protected endpoint, you will get an error telling you that certificate verify failed.
What most people do here is to tell the cURL library to simply ignore certificate errors and continue (curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);). As this will make your code work, you introduce huge security hole and enable malicious users to perform various attacks on your app like Man In The Middle attack or such.
Never, ever do that. Instead, you simply need to modify your php.ini and tell PHP where your CA Certificate file is to let it verify certificates correctly:
; modify the absolute path to the cacert.pem file
curl.cainfo=c:\php\cacert.pem
The latest cacert.pem can be downloaded from the Internet or extracted from your favorite browser. When changing any php.ini related settings remember to restart your webserver.
A live example of using php curl_exec to do an HTTP post:
Put this in a file called foobar.php:
<?php
$ch = curl_init();
$skipper = "luxury assault recreational vehicle";
$fields = array( 'penguins'=>$skipper, 'bestpony'=>'rainbowdash');
$postvars = '';
foreach($fields as $key=>$value) {
$postvars .= $key . "=" . $value . "&";
}
$url = "http://www.google.com";
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST, 1); //0 for a get request
curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT ,3);
curl_setopt($ch,CURLOPT_TIMEOUT, 20);
$response = curl_exec($ch);
print "curl response is:" . $response;
curl_close ($ch);
?>
Then run it with the command php foobar.php, it dumps this kind of output to screen:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Title</title>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<body>
A mountain of content...
</body>
</html>
So you did a PHP POST to www.google.com and sent it some data.
Had the server been programmed to read in the post variables, it could decide to do something different based upon that.
It's can be easily reached with:
<?php
$post = [
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.domain.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$response = curl_exec($ch);
var_export($response);
1.Step by step
Initialize the cURL session:
$url = "www.domain.com";
$ch = curl_init($url);
If your request has headers like bearer token or defining JSON contents you have to set HTTPHEADER options to cURL:
$token = "generated token code";
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // for define content type that is json
'bearer: '.$token, // send token in header request
'Content-length: 100' // content length for example 100 characters (can add by strlen($fields))
)
);
If you want to include the header in the output set CURLOPT_HEADER to true:
curl_setopt($ch, CURLOPT_HEADER, false);
Set RETURNTRANSFER option to true to return the transfer as a string instead of outputting it directly:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
To check the existence of a common name in the SSL peer certificate can be set to 0(to not check the names), 1(not supported in cURL 7.28.1), 2(default value and for production mode):
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
For posting fields as an array by cURL:
$fields = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
Execute cURL and return the string. depending on your resource this returns output like result=OK:
$result = curl_exec($ch);
Close cURL resource, and free up system resources:
curl_close($ch);
2.Use as a class
The whole call_cURL class that can be extended:
class class_name_for_call_cURL {
protected function getUrl() {
return "www.domain.com";
}
public function call_cURL() {
$token = "generated token code";
$fields = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
$url = $this->getUrl();
$output = $this->_execute($fields, $url, $token);
// if you want to get json data
// $output = json_decode($output);
if ($output == "OK") {
return true;
} else {
return false;
}
}
private function _execute($postData, $url, $token) {
// for sending data as json type
$fields = json_encode($postData);
$ch = curl_init($url);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // if the content type is json
'bearer: '.$token // if you need token in header
)
);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
}
Using the class and call cURL:
$class = new class_name_for_call_cURL();
var_dump($class->call_cURL()); // output is true/false
3.One function
A function for using anywhere that needed:
function get_cURL() {
$url = "www.domain.com";
$token = "generated token code";
$postData = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
// for sending data as json type
$fields = json_encode($postData);
$ch = curl_init($url);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // if the content type is json
'bearer: '.$token // if you need token in header
)
);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
This function is usable just by:
var_dump(get_cURL());
Curl Post + Error Handling + Set Headers [thanks to #mantas-d]:
function curlPost($url, $data=NULL, $headers = NULL) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if(!empty($data)){
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$response = curl_exec($ch);
if (curl_error($ch)) {
trigger_error('Curl Error:' . curl_error($ch));
}
curl_close($ch);
return $response;
}
curlPost('google.com', [
'username' => 'admin',
'password' => '12345',
]);
curlPost('google.com', [
'username' => 'admin',
'password' => '12345',
]);
function curlPost($url, $data) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error !== '') {
throw new \Exception($error);
}
return $response;
}
I'm surprised nobody suggested file_get_contents:
$url = "http://www.example.com";
$parameters = array('username' => 'user1', 'password' => 'passuser1', 'gender' => '1');
$options = array('http' => array(
'header' => 'Content-Type: application/x-www-form-urlencoded\r\n',
'method' => 'POST',
'content' => http_build_query($parameters)
));
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
it's simple, it works; I use it in an environment where I control the code at both ends.
even better, use json_decode (and set up your code to return JSON)
$result = json_decode(file_get_contents($url, false, $context), TRUE);
this approach invokes curl behind the scenes, but you don't jump through as many hoops.
Answer refined from this original answer elsewhere on Stack Overflow:
PHP sending variables to file_get_contents()
If the form is using redirects, authentication, cookies, SSL (https), or anything else other than a totally open script expecting POST variables, you are going to start gnashing your teeth really quick. Take a look at Snoopy, which does exactly what you have in mind while removing the need to set up a lot of the overhead.
A simpler answer IF you are passing information to your own website is to use a SESSION variable. Begin php page with:
session_start();
If at some point there is information you want to generate in PHP and pass to the next page in the session, instead of using a POST variable, assign it to a SESSION variable. Example:
$_SESSION['message']='www.'.$_GET['school'].'.edu was not found. Please try again.'
Then on the next page you simply reference this SESSION variable. NOTE: after you use it, be sure you destroy it, so it doesn't persist after it is used:
if (isset($_SESSION['message'])) {echo $_SESSION['message']; unset($_SESSION['message']);}
Here are some boilerplate code for PHP + curl
http://www.webbotsspidersscreenscrapers.com/DSP_download.php
include in these library will simplify development
<?php
# Initialization
include("LIB_http.php");
include("LIB_parse.php");
$product_array=array();
$product_count=0;
# Download the target (store) web page
$target = "http://www.tellmewhenitchanges.com/buyair";
$web_page = http_get($target, "");
...
?>
Examples of sending form and raw data:
$curlHandler = curl_init();
curl_setopt_array($curlHandler, [
CURLOPT_URL => 'https://postman-echo.com/post',
CURLOPT_RETURNTRANSFER => true,
/**
* Specify POST method
*/
CURLOPT_POST => true,
/**
* Specify array of form fields
*/
CURLOPT_POSTFIELDS => [
'foo' => 'bar',
'baz' => 'biz',
],
]);
$response = curl_exec($curlHandler);
curl_close($curlHandler);
echo($response);
If you try to login on site with cookies.
This code:
if ($server_output == "OK") { ... } else { ... }
It May not works if you try to login, because many sites return status 200, but the post is not successful.
The easy way to check if the login post is successful is to check if it setting cookies again. If in output have a Set-Cookies string, this means the posts are not successful and it starts a new session.
Also, the post can be successful, but the status can redirect instead of 200.
To be sure the post is successful try this:
Follow location after the post, so it will go to the page where the post does redirect to:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
And than check if new cookies existing in the request:
if (!preg_match('/^Set-Cookie:\s*([^;]*)/mi', $server_output))
{echo 'post successful'; }
else { echo 'not successful'; }
Easiest is to send data as application/json. This will take an array as input and properly encodes it into a json string:
$data = array(
'field1' => 'field1value',
'field2' => 'field2value',
)
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type:application/json',
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resultStr = curl_exec($ch);
return json_decode($resultStr, true);

aspnet core app strange request type

I am building a asp.net core app with the debfault aspnetidentitycore plugedin, the only change is i added an action by modified the regiester method to a api, which means can be called by another app.
[HttpPost]
[AllowAnonymous]
public async Task<EngineResult<object>> RegisterByApi([FromBody]RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new IdentityUser
{
DisplayName = model.Name,
UserName = model.Email,
Email = model.Email,
PhoneNumber = model.PhoneNumber,
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(3, "User created a new account with password.");
return new EngineResult<object>(true) { Entity = new { sub = user.Id, name = user.DisplayName } };
}
return new EngineResult<object>(false) { Entity = string.Join(";", result.Errors?.Select(e => e.Description)) };
}
return new EngineResult<object>(false) { Entity = string.Join(";", ModelState.Values.SelectMany(m => m.Errors).Select(e => e.ErrorMessage)) };
}
but when a php calls this api, i get a strange content-type, which is
application/json; boundary=------------------------e3f0ef0cc3e74f25
here is the php code
<?php
$data = [
"Name"=>"testname",
"Email"=>"123#testdomain.com",
"Password"=>"123qwe!#QWE",
"ConfirmPassword"=>"123qwe!##QWE",
"PhoneNumber"=>"12312321321",
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://xxxx/Account/RegisterByApi");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
header_remove();
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json'
)
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
curl_close($ch);
echo $output;
anyone know what's happening here?
finally, it is a my php code issue, that not use a json data, replace the post data with a convert to josn will resolve this issue:
$payload = json_encode($data);

GuzzleHttps - How to send async. data via POST (using Pool)

I'm trying to send POST data via POOL in Guzzle Library. But, at the address where the data is sending POST is completely empty - I don't get it.
$client = new Client();
$requests = function ()
{
foreach($this->urls as $url)
{
yield new Request('POST', $url, [
'body' => '...'
]);
}
};
I tried also form_params and multiparts, does not working again (POST is empty again also $_REQUEST & $_GET).
And of course this piece of code (for completeness):
$pool = new Pool($client, $requests(), [
'concurrency' => count($this->urls),
'fulfilled' => function ($response) {},
'rejected' => function ($reason) {},
});
$promise = $pool->promise();
$promise->wait();
Guzzle sends the request correctly (enter on the second server), but in itself does not have any data.
What am I doing wrong? Thanks!
EDIT:
I'm just trying replace this code with Guzzle (is repeated in a cycle now):
$ch = curl_init();
$url = 'https://example.cop';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'mehehe_net');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 59000);
curl_setopt($ch, CURLOPT_POST, true);
$dt = ["data" => json_encode($queue)];
curl_setopt($ch, CURLOPT_POSTFIELDS, $dt);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$cont = curl_exec($ch);
curl_close($ch);
This solution working GREAT! :-)
$pss = [];
$client = new Client();
$uri = "https://example.com";
foreach($data as $alarm)
{
$pss[] = $client->postAsync($uri, ['form_params' => ["alarms" => json_encode($alarm)]])->then(function ($response) use ($alarm)
{
// $response->getBody();
});
}
\GuzzleHttp\Promise\unwrap($permis);
Do not forget use unwrap (wait) after the loop! :-)
Here is the solution I used.
$requests = function ($endpoints, $data) {
foreach ($endpoints as $endpoint) {
yield new Psr7\Request(
'POST',
$endpoint,
['Content-Type' => 'application/x-www-form-urlencoded'],
http_build_query($data, null, '&'));
}
echo "\n";
};
Additional information to your solution: consider to use each_limit() with a generator instead of unwrap.
It will allow you to control concurrency level (amount of parallel queries). It's useful when you have big amount of requests and some restrictions on the server side (usually there are some restrictions about number of simultaneous requests from a client).
$generator = function () {
return $client->postAsync($uri, ['form_params' => ["alarms" => json_encode($alarm)]])->then(function ($response) {
// ...
});
}
// Allow only 10 simultaneous requests.
each_limit($generator(), 10)->wait();
Read this article for more details.

Send Post request to Node.js with PHP cURL

I am trying to send a post request through PHP cURL to my node.js server to then emit a message to the client. The server is working and setup as follows:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
, qs = require('querystring')
app.listen(8000);
function handler(req, res) {
// set up some routes
switch(req.url) {
case '/push':
if (req.method == 'POST') {
console.log("[200] " + req.method + " to " + req.url);
var fullBody = '';
req.on('data', function(chunk) {
fullBody += chunk.toString();
if (fullBody.length > 1e6) {
// FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUEST
req.connection.destroy();
}
});
req.on('end', function() {
// Send the notification!
var json = qs.stringify(fullBody);
console.log(json.message);
io.sockets.emit('push', { message: json.message });
// empty 200 OK response for now
res.writeHead(200, "OK", {'Content-Type': 'text/html'});
res.end();
});
}
break;
default:
// Null
};
}
and my PHP is as follows:
$curl = curl_init();
$data = array('message' => 'simple message!');
curl_setopt($curl, CURLOPT_URL, "http://localhost:8000/push");
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_exec($curl);
The console says that json.message is undefined. Why is it undefined?
You're using querystring.stringify() incorrectly. See the documentation on querystring's methods here:
http://nodejs.org/docs/v0.4.12/api/querystring.html
I believe what you want is something like JSON.stringify() or querystring.parse(), as opposed to querystring.stringify() which is supposed to serialize an existing object into a query string; which is the opposite of what you are trying to do.
What you want is something that will convert your fullBody string into a JSON object.
If your body simply contains a stringified version of the JSON blob, then replace
var json = qs.stringify(fullBody);
With
var json = JSON.parse(fullBody);
try this code
<?php
$data = array(
'username' => 'tecadmin',
'password' => '012345678'
);
$payload = json_encode($data);
// Prepare new cURL resource
$ch = curl_init('https://api.example.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
// Set HTTP Header for POST request
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($payload))
);
// Submit the POST request
$result = curl_exec($ch);
// Close cURL session handle
curl_close($ch);

Categories