This code initializes the curl 2 times and closes it, my goal is to start the curl once, and then make several curl_exec requests.

//config.php $c = [ 0 => class1::class, 1 => class2::class ]; //класс курла class Curl { protected $ch; function __construct() { $this->init(); } function request($method, $url, $options = []) { return 'parsed'; } function init() { $this->ch = curl_init(); var_dump('init'); } function __destruct() { curl_close($this->ch); } } //класс ответа сервера class Response { function get() { global $c; $arr = []; foreach ($c as $item) { $super = new $item(); /** * @var Superclass $super */ $arr[] = $super->request(); } return $arr; } } //класс родительский class Superclass { //общий функционал function request() { $c = new Curl(); return $c->request('GET', 'http://ya.ru'); } } //дочерние class class1 extends Superclass { //реализация метода request отличается от class2 } class class2 extends Superclass { //реализация метода request отличается от class1 } //контроллер $r = new Response(); var_dump($r->get()); 

The first thing that comes to mind is to move $c = new Curl() to the very top, for example, in Response, where there is a foreach loop, then you have to pass $ c as a parameter to the class1 / class2 constructor.

Maybe there is a more optimized version? Through static?

  • 2
    Singleton? Or the registry to store the created objects. - Visman
  • This is a classic example of a situation in which a singleton is one of the best solutions (and don’t listen to haters who call it antipattern - they just don’t know how to cook it :) - rjhdby
  • @Visman thanks for the kick, sort of figured out. - Jean-Claude
  • @rjhdby yes, everything is fine, he cried. - Jean-Claude

2 answers 2

Since PHP is essentially single-threaded (we don’t consider exoticism), Singleton is very simple for it:

 class Datasource{ private $instance = null; public static function getInstance(){ if(selsf::$instanse == null){ self::$instance = new Datasource(); } return self::$instanse; } public function doSomeStuff( ... ... } 

This design pattern is ideal for database connections and other resources, the connection and positioning within which should be the same for all code.

Is there also a more naive implementation? if you do not need a binding of user methods

 class Datasource{ private $connection; public static function getConnection(){ if(self::$connection === null){ self::$connection = new SomeClass(); } return self::$connection; } } 

    Understood, pile this:

     echo Singleton::getInstance()->url('http://php.net')->exec(); echo Singleton::getInstance()->url('https://ya.ru')->exec(); final class Singleton { /** * @var Singleton */ private static $instance = null; private $ch = null; /** * @return Singleton */ public static function getInstance() { if (null === static::$instance) { static::$instance = new static(); } return static::$instance; } private function __construct() { if (is_null($this->ch)) { $this->ch = curl_init(); var_dump('curl_init()'); } curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 30); curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0); } public function exec() { $exec = curl_exec($this->ch); return mb_strlen($exec) . ' '; } public function __destruct() { if (!is_null(static::$instance)) { curl_close($this->ch); var_dump('curl_close()'); } } public function url($url) { curl_setopt($this->ch, CURLOPT_URL, $url); return static::$instance; } private function __clone() { } private function __wakeup() { } } 

    Will output

     string 'curl_init()' (length=11) 10365 68121 string 'curl_close()' (length=12) 

    True, some errors were raised in the debager, and $ instance refers to itself recursively (this, as I understand it, should be the result of the reference to itself).

    enter image description here

    • 1. ch - NOT static. Read what is singleton. Only a class instance is static in it, nothing more. 2. Arrange access modifiers for methods - this is a good tone - rjhdby
    • @rjhdby corrected, but I had to remove getInstance ($ url), since during the second call to Singleton :: getInstance (), the constructor in which I installed CURLOPT_URL does not work. In access modifiers, I have no urgent need for this test code, copied from the github .. - Jean-Claude
    • Do I understand correctly that this is mainly necessary for the sake of keep-alive? If you specify cURL different hosts in the address, will it deal with the sockets encapsulated in itself? Is it then possible, for example, to close a keep-alive connection with one host and leave with the others? - user239133