I'm trying to simply read the Philips Hue lights information from my home with the following code:
$fp = fopen(dirname(__FILE__).'/errorlog.txt', 'a');
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://119.119.20.20:2827/api/Js82jH2lao-pAiws89S9A-k9hHsukw72/lights',
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => $fp
));
$resp = curl_exec($ch);
curl_close($ch);
print_r($resp);
It returns nothing. Looking at errorlog.txt it says:
* About to connect() to 119.119.20.20 port 2827 (#0)
* Trying 119.119.20.20... * Connection refused
* couldn't connect to host
* Closing connection #0
I'm able to read the data and change light settings through a site like hurl.it which tells me I've setup my router correctly. allow_url_fopen on my server is on. I'm using curl because I want to do a PUT request as well. I don't want to use a library for simply turning on and off an light.
How can I make this work?
Edit to clarify: I'm using an external server to host the php, which communicates to my Philips Hue bridge at home. You can assume I forwarded my port correctly. No VPN.
My guess is it's a users/permissions issue.
Does www-data/http user have permission to use curl on your server? All php scripts will be executed as that user so without correct permissions curl will fail giving this error.
Which user created the php script? Have you changed file permissions to allow other users correct privileges?
Having said all that, you stated that you don't want to use a library for something so simple, why even bother with curl? file_get_contents can PUT, POST etc out of the box.
Get status from bridge as associative array:
$result = json_decode(file_get_contents('http://119.119.20.20:2827/api/Js82jH2lao-pAiws89S9A-k9hHsukw72/lights'), true);
Turn off all lights with a PUT request:
$data = '{"on":false}';
$result = file_get_contents('http://119.119.20.20:2827/api/Js82jH2lao-pAiws89S9A-k9hHsukw72/groups/0/action', null, stream_context_create(array(
'http' => array(
'method' => 'PUT',
'header' => 'Content-Type: application/json' . "\r\n"
. 'Content-Length: ' . strlen($data) . "\r\n",
'content' => $data
),
)));
Just tried it on my Hue setup. Works for me.
Related
I know there's questions about this but so far none has helped me solve my problem.
I have a PHP script whose job is to send scheduled e-mails. It does this by calling a web service, which I control, via cURL.
Run in the browser, it works fine. Run via CRON, the cURL response is empty. It never reaches the web service; I know this because I had the WS write a text file when it's contacted. It does if you access via browser, not via CRON.
I know CRON runs in a different environment and I'm not relying on any environmental vars e.g. $_SERVER. The path to require() isn't the problem, either, as it's successfully getting data out of that file to connect to the DB.
This question suggested adding the following cURL opts, which I've done, but no dice:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
Here's my PHP script:
//prep
define('WS_URL', 'http://mywebservicedomain.com/index.php/web_service');
require '../application/config/database.php';
$db = new mysqli($db['default']['hostname'], $db['default']['username'], $db['default']['password'], $db['default']['database']) or die('failed to connect to DB');
//get scheduled e-mails
$res = $db->query('SELECT * FROM _cron_emails WHERE send_when < NOW()');
//process each...
while ($email_arr = $res->fetch_assoc()) {
//...get API connection info
$api_accnt = $db->query($sql = 'SELECT id, secret FROM _api_accounts WHERE project = "'.$email_arr['project'].'"');
$api_accnt = $api_accnt->fetch_assoc();
//...recreate $_POST env
$tmp = json_decode($email_arr['post_vars'], 1);
$_POST = array();
foreach($tmp as $key => $val) $_POST[$key] = !is_array($val) ? $val : implode(',', $val);
//...call API to send e-mail
$ch = curl_init($url = WS_URL.'/send_scheduled_email/'.$email_arr['email_id'].'/'.$email_arr['store_id'].'/'.$email_arr['item_id']);
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_SAFE_UPLOAD => true,
CURLOPT_SSL_VERIFYHOST => 1, //<-- tried adding this
CURLOPT_SSL_VERIFYPEER => 1, //<-- ditto
CURLOPT_POSTFIELDS => array_merge($_POST, array(
'api_key' => $api_accnt['id'],
'api_secret' => $api_accnt['secret'],
))
));
$resp = curl_exec($ch); //<-- empty when CRON
//if e-mail was sent OK, or decider script said it was ineligible, delete it from the queue
if (($resp == 'ok' || $resp == 'ineligible'))
$db->query('DELETE FROM _cron_emails WHERE id = '.$email_arr['id'].' LIMIT 1');
}
Does anyone have any idea why it fails to connect to my web service via cURL only when run in CRON?
Here's the CRON job:
/usr/bin/php /home/desyn/public_html/cron/send_scheduled_emails.php
In the end this turned out to be a very particular, and I imagine uncommon, problem. I doubt it'll prove too much help to others, but I leave it here in case.
Essentially, my server didn't like cURL'ing itself, via a domain.
The server being called by cURL in the CRON script was the same server that the CRON task was running on (but a different account and website.)
This has not proved to be a problem via a browser; only via CRON.
Changing the cURL request to use the server's local IP, rather than using the domain, solved this.
I have a link from the via which I can send sms. It works when I put it in the address bar and fill the required get params and press enter. But how can I load it in the middle of controller action (the framework is Yii2 if that matters) ? I tried with mail() but couldn't reach any result.
The link is like below:
http://sms.***********.com/httpApi/Send.aspx?phone=359.........&body=message&username=xxx&password=xxx
Can I make it with plain php or I have to it via javascript ? Thank you in advance!
cURL allows transfer of data across a wide variety of protocols, and is a very powerful system. It's widely used as a way to send data across websites, including things like API interaction and oAuth. cURL is unrestricted in what it can do, from the basic HTTP request, to the more complex FTP upload or interaction with an authentication enclosed HTTPS site. We'll be looking at the simple difference between sending a GET and POST request and dealing with the returned response, as well as highlighting some useful parameters.
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'YOUR API URL',
CURLOPT_USERAGENT => 'cURL Request'
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
The basic idea behind the cURL functions is that you initialize a cURL session using the curl_init(), then you can set all your options for the transfer via the curl_setopt(), then you can execute the session with the curl_exec() and then you finish off your session using the curl_close().
You should use сURL.
$query = http_build_query([
'phone' => '359.........',
'body' => 'message',
'username' => 'xxx',
'password' => 'xxx'
]);
$c = curl_init();
curl_setopt($c , CURLOPT_URL , 'http://sms.***********.com/httpApi/Send.aspx/?' . $query);
curl_exec($c);
curl_close($c);
I am developing a WordPress plugin for a client to interact with Rightmove's Realtime Data API. I have been sent example PHP code from Rightmove to use. In order to interact with Rightmove's API, you need to have been generated and given a security certificate from Rightmove. I have been sent that and have the password for it. Before executing the curl, the code uses the stat() function on the certificate. Below is the code (with the password crossed out for obvious reasons).
$url = 'https://adfapi.adftest.rightmove.com/';
$ch = curl_init();
$cert = plugins_url("safetech-righmove-realtime-data-feed-realhomes/safetech.pem");
if (!stat($cert)){
die('No cert');
}
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_VERBOSE => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSLVERSION => 5,
CURLOPT_SSLCERT => $cert,
CURLOPT_SSLCERTPASSWD => 'xxxxxxxx'
));
if(!curl_exec($ch)) {
echo 'Curl error: ' . curl_error($ch);
}
curl_close($ch);
As you can if the stat fails, it stops the code and prints "No cert". This exactly what is happening. I have uploaded the certificate into the plugins folder and can access it by manually going to the URL in the browser. So the file clearly exists.
If I comment out the if statement and just execute the curl, Rightmove returns an authentication error, implying the certificate is not being used? I have tried using the file_exists() function but that still returns the "No cert" error.
The .pem file has read permissions.
Any idea what is causing the issue? I've been trying various things for hours with no result.
I have a working 3rd party php codes verify the receipt sent from ipad.
but it seems https://sandbox.itunes.apple.com/verifyReceipt no long response to my php code.
there's not even an error stat like {"status":21000} if I visite the url directly.
I've tried different ways on server side, like curl_exec($ch); or file_get_contents
even the simple test get nothing returned at all.
$result = file_get_contents('https://sandbox.itunes.apple.com/verifyReceipt');
echo $result;
I wonder if this is caused by heartbleed and what can I do?
my original working php code:
if ($isSandbox) {
$endpoint = 'https://sandbox.itunes.apple.com/verifyReceipt';
}
else {
$endpoint = 'https://buy.itunes.apple.com/verifyReceipt';
}
// Connect to Apple server and validate.
$postData = json_encode(array("receipt-data" => $receipt));
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded",
'method' => 'POST',
'content' => $postData
),
);
$context = stream_context_create($options);
$result = file_get_contents($endpoint, false, $context);
Well, after hours searching and checking, I finally figure this out, here's what happened:
I upload the test file to another server, turns out it's working so
not a php source problem.
I added
error_reporting(E_ALL);
ini_set('display_errors', '1');
to the php file got the error code is file-get-contents Couldn't
resolve host name
so I remember I yum update all the server software yesterday to
deal with heartbleed. and seems some update modified the
resolv.conf.
I changed the resolv.conf added google nameserver
8.8.8.8 but still not working
restart the nginx and php-fpm, problem solved
I am trying to perform a Bing Search by using the Windows Azure Marketplace API, I have downloaded their guide and sample code. The code prepares a HTTPS request with basic authentication, however I am constantly getting the following error:
Warning: file_get_contents(https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/Web?Query=%27washburn%27&Adult=%27Off%27&$top=50&$format=Atom): failed to open stream: Connection refused
The php code (from Microsoft's document):
$context = stream_context_create(array(
'http' => array(
'proxy' => 'tcp://127.0.0.1:8888',
'request_fulluri' => true,
'header' => "Authorization: Basic " . base64_encode($accountKey.":".$accountKey)
)
));
Does anyone know what is causing the error please? I have correctly set the $accountKey and I tested it in a browser. What puzzles me a little is 127.0.0.1:8888 and also base64_encode($accountKey.":".$accountKey) , how come you need the $accountKey both before and after the : while when using a browser you are supposed to leave the username blank and just input the account key into the password field?
I have solved it and here is what I have found for future people that would be doing the same thing:
I commented out the line where it says:
'proxy' => 'tcp://127.0.0.1:8888',
'request_fulluri' => true,
and also set base64_encode("ignored:".$accountKey) instead
Base on what I read on MSDN, the username part is said to be ignored, so it shouldn't matter what value it is. I was thinking perhaps the length or the special characters in the key screwed things up so I replaces it with ignored (or anything really).
That did the trick and I can parse the returned JSON data. Good luck!