Closed trevrobwhite closed 3 years ago
The most likely reason this isn't working as expected is because your custom client isn't properly constructing the Response it returns from the call to request()
. $response->getContent()
calls json_decode
on the $content
member, which you're setting from the exploded response content parts. Have you verified that the element in the array being set to the body is indeed a JSON string?
@eshanholtz thanks for the hint your right, the issue was with the proxy script, I got the example from https://www.twilio.com/docs/libraries/php/custom-http-clients-php# under "Custom HTTP Client for PHP" but this code isn't written very well, using some help from https://www.php.net/manual/en/function.curl-exec.php#80442 I was able to rewrite my request function, and I share it below to help others (and maybe the Twilio documentation should be updated)
/**
* Class GeTwilioClient allows talking to the Twilio Endpoint through the proxy server
* @link https://www.twilio.com/docs/libraries/php/custom-http-clients-php
*/
class GeTwilioClient extends \Twilio\Http\CurlClient
{
protected $http = null;
protected $proxy = null;
/**
* GeTwilioClient constructor.
* @link https://www.twilio.com/docs/libraries/php/custom-http-clients-php
* @param null $proxy Proxy Server
* @param null $cainfo CA Info for the proxy
*/
public function __construct($proxy = null, $cainfo = null)
{
$this->proxy = $proxy;
$this->cainfo = $cainfo;
$this->http = new CurlClient();
}
public function request($method, $url, $params = array(), $data = array(),
$headers = array(), $user = null, $password = null,
$timeout = null): Response
{
$options = $this->options($method, $url, $params, $data, $headers,
$user, $password, $timeout);
{
// Here you can change the URL, headers and other request parameters
$options = $this->options($method, $url, $params, $data, $headers,
$user, $password, $timeout);
$curl = curl_init($url);
curl_setopt_array($curl, $options);
if (!empty($this->proxy))
curl_setopt($curl, CURLOPT_PROXY, $this->proxy);
if (!empty($this->cainfo))
curl_setopt($curl, CURLOPT_CAINFO, $this->cainfo);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_HTTPPROXYTUNNEL, true);
$response = curl_exec($curl);
// Updated using example: https://www.php.net/manual/en/function.curl-exec.php#80442
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$headerSize = curl_getinfo($curl,CURLINFO_HEADER_SIZE);
$head = substr($response, 0, $headerSize);
$body = substr( $response, $headerSize );
$responseHeaders = array();
$headerLines = preg_split("/\r?\n/", $head);
foreach ($headerLines as $line) {
if (! preg_match("/:/", $line)) continue;
list($key, $value) = explode(':', $line, 2);
$responseHeaders[trim($key)] = trim($value);
}
curl_close($curl);
if (isset($buffer) && is_resource($buffer)) {
fclose($buffer);
}
return new Response($statusCode, $body, $responseHeaders);
}
}
}
@trevrobwhite
I pass along your feedback to our docs team. They're going to work on getting that example updated, thank you for including your implementation. I'm glad the hint worked for you.
I'm going to go ahead and close this issue as there's no further work that needs to be done in this repo.
Issue Summary
When calling
$message = $client->account->messages->create($recipient, [ 'from' => $from, 'body' => $body, ]);
I get the error Twilio\Rest\Api\V2010\Account\MessageInstance::__construct() must be of the type array, null given
I'm using a proxy server so had to extend the class:
Using this function I call the Twilio Client:
Debugging the code, I can see MessageList.php (line 68) calls new MessageInstance, there the payload is null, the call before is calling $this->version->create.
Digging into this I can see that Version.php line 222 checks the status code, for me this returns 201 (and an SMS is sent to my phone), however $response->getContent() returns NULL which is what is being passed to MessageInstance without checking and causes the exception.
Exception/Log
Technical details: