Welcome Guest, Not a member yet? Register   Sign In
CI4 error run curl
#1

I've been working with CI since 2017 and I use it for several projects and I think it's a very flexible framework.
I want to implement a Curl that consumes a stream type API that now runs in pure PHP on codeigniter 4.

Example:
I've reduced a lot of the code for simplicity.

PHP Code:
public function executor() {
 
 
$ch1 curl_init();
 
$host1 parse_url("http://192.168.21.110/cgi-bin/snapManager.cgi?action=attachFileProc&Flags[0]=Event&heartbeat=5&Events=[TrafficJunction]"PHP_URL_HOST);
 
$this->temp[$host1] = array("temp" => """delimeter" => "--myboundary""delimeterLength" => 12);
 
curl_setopt($ch1CURLOPT_URL,"http://192.168.21.110/cgi-bin/snapManager.cgi?action=attachFileProc&Flags[0]=Event&heartbeat=5&Events=[TrafficJunction]");
 
curl_setopt($ch1CURLOPT_HEADER0);
 
curl_setopt($ch1CURLOPT_HTTPAUTHCURLAUTH_DIGEST);
 
curl_setopt($ch1CURLOPT_USERPWD"admin:orus8007");
 
curl_setopt($ch1CURLOPT_RETURNTRANSFERtrue);
 
curl_setopt($ch1CURLOPT_BINARYTRANSFERtrue);
 
curl_setopt($ch1CURLOPT_CRLFtrue);
 
curl_setopt($ch1CURLOPT_TIMEOUT0);
 
curl_setopt($ch1CURLOPT_WRITEFUNCTION, array($this"callback"));

 
$ch2 curl_init();
 
$host2 parse_url("http://192.168.18.106/cgi-bin/snapManager.cgi?action=attachFileProc&Flags[0]=Event&heartbeat=5&Events=[TrafficJunction]"PHP_URL_HOST);
 
$this->temp[$host2] = array("temp" => """delimeter" => "--myboundary""delimeterLength" => 12);
 
curl_setopt($ch2CURLOPT_URL,"http://192.168.18.106/cgi-bin/snapManager.cgi?action=attachFileProc&Flags[0]=Event&heartbeat=5&Events=[TrafficJunction]");
 
curl_setopt($ch2CURLOPT_HEADER0);
 
curl_setopt($ch2CURLOPT_HTTPAUTHCURLAUTH_DIGEST);
 
curl_setopt($ch2CURLOPT_USERPWD"admin:orus8007");
 
curl_setopt($ch2CURLOPT_RETURNTRANSFERtrue);
 
curl_setopt($ch2CURLOPT_BINARYTRANSFERtrue);
 
curl_setopt($ch2CURLOPT_CRLFtrue);
 
curl_setopt($ch2CURLOPT_TIMEOUT0);
 
curl_setopt($ch2CURLOPT_WRITEFUNCTION, array($this"callback"));

 
$mh curl_multi_init();
 
curl_multi_add_handle($mh,$ch1);
 
curl_multi_add_handle($mh,$ch2);

 
$active null;
 do {
 
$mrc curl_multi_exec($mh$active);
 } while (
$mrc == CURLM_CALL_MULTI_PERFORM);

 while (
$active && $mrc == CURLM_OK) {
 if (
curl_multi_select($mh) != -1) {
 do {
 
$mrc curl_multi_exec($mh$active);
 } while (
$mrc == CURLM_CALL_MULTI_PERFORM);
 }
 }

 
curl_multi_remove_handle($mh$ch1);
 
curl_multi_remove_handle($mh$ch2);
 
 
curl_multi_close($mh);
 }
 
 private function 
callback($ch$str) {
 
$headers $this->handleResponse($ch$str);
 if(
array_key_exists(2$headers)){
 
$infoEvent $this->handleInfoEvent($headers);
 
$imagebinary $this->handleImageBinary($headers);
 
print_r($infoEvent);
 }

 
ob_flush();
 
flush();
 return 
strlen($str);
 }
 
 private function 
handleResponse($ch$str) {
 
$strDelimeter str_replace("\r\n"""$str);
 
$host parse_url(curl_getinfo($chCURLINFO_EFFECTIVE_URL), PHP_URL_HOST);
 
$strDelimeter substr($strDelimeter0$this->temp[$host]["delimeterLength"]);
 if(
$strDelimeter == $this->temp[$host]["delimeter"]){
 
$headers = array();
 
$headers explode($this->temp[$host]["delimeter"], $this->temp[$host]["temp"]);
 
$this->temp[$host]["temp"] = "";
 
$this->temp[$host]["temp"] = $str;
 return 
array_filter($headers);
 }else{
 
$this->temp[$host]["temp"] .= $str;
 return array();
 }
 }

 private function 
handleInfoEvent($headers) {
 
$cContLenText strlen($headers[1]);
 
$cHeadLenText strlen("\r\nContent-Type: text/plain\r\nContent-Length: $cContLenText\r\n\r\n");
 
$stringFinalText substr($headers[1], $cHeadLenText);
 
$stringFinalText explode("\r\n"$stringFinalText);
 foreach (
$stringFinalText as $value) {
 echo 
$value."<br>";
 if(
false != ($matches explode('='$value2))) {
 if(
array_key_exists(1$matches)){
 
$headers_arr["{$matches[0]}"] = trim($matches[1]);
 }else{
 
$headers_arr["{$matches[0]}"] = null;
 }
 }
                
 
}
 return 
$headers_arr;
 }

 private function 
handleImageBinary($headers) {
 
$cContLenImage strlen($headers[2]);
 
$cHeadLenImage strlen("\r\nContent-Type: image/jpeg\r\nContent-Length: $cContLenImage\r\n\r\n");
 
$stringFinalImage substr($headers[2], $cHeadLenImage);
 
$now DateTime::createFromFormat('U.u'microtime(true));
 
$fp fopen($now->format("d-m-Y H.i.s.u").".jpg""w");
 
fwrite($fp$stringFinalImage);
 
fclose($fp);
 return 
null;
 } 


I'm trying to use this script in controller.
This script will run and it's endless until a BD flag returns to finish, but that's not the problem.

I don't need it to return anything to the client. Just work in the backend and do your job like saving the image and saving the information in the db.

This API returns data as if it were a stream, hence the use of curl's OPT WRITEFUNCTION.

The problem is that whenever I try to run I get the following error:
Code:
Fatal error: Uncaught ErrorException: Cannot modify header information - headers already sent in C:\xampp\htdocs\vendor\codeigniter4\framework\system\Debug\Exceptions.php:137 Stack trace: #0 [internal function]: CodeIgniter\Debug\Exceptions->errorHandler(2, 'Cannot modify h...', 'C:\\xampp\\htdocs...', 137) #1 C:\xampp\htdocs\vendor\codeigniter4\framework\system\Debug\Exceptions.php(137): header('HTTP/1.1 500 In...', true, 500) #2 [internal function]: CodeIgniter\Debug\Exceptions->exceptionHandler(Object(Error)) #3 {main} thrown in C:\xampp\htdocs\vendor\codeigniter4\framework\system\Debug\Exceptions.php on line 137
Reply
#2

Test to replace this lines:

PHP Code:
ob_flush();
flush(); 

To something like:

PHP Code:
$this->response->setBody(ob_get_clean()); 


It will lose the stream capability...
I think stream is not possible without terminate the script before CodeIgniter send the Response.



Reply
#3

(This post was last modified: 08-30-2021, 02:23 AM by kokero.)

Thanks @natanfelles, didn't solve your answer directly, nas indirectly haha.

The problem was related that as it prints information and right after an error related to Datetime formatting it tried to return the error and changed the header. His answer helped to visualize this problem.

But right after the fix I realize that I'm blocked from having stream type information. The CI4 will only print information on the screen after completing the method. Is it possible for me to escape the rendering of views?
Reply
#4

Ci4 has made this very easy. Read up on the CURLRequest Class.

https://codeigniter.com/user_guide/libra...light=curl
Reply




Theme © iAndrew 2016 - Forum software by © MyBB