--- tags: dev, php --- # PHP, cURL and Memory Management About [cURL](https://www.php.net/manual/en/book.curl.php) (for Client URL): > PHP supports libcurl, a library created by Daniel Stenberg, that allows you to connect and communicate to many different types of servers with many different types of protocols. *Source: <https://www.php.net/manual/en/intro.curl.php>.* Any cURL session must be: 1. **Initialized** by a call to [`curl_init()`](https://www.php.net/manual/en/function.curl-init.php). 2. **Closed** by a call to [`curl_close()`](https://www.php.net/manual/en/function.curl-close.php) in order to free up system resources. What is the impact of not explicitly calling `curl_close()`? Will it generate memory leaks? TL;DR: PHP memory management will properly clean unclosed sessions at process exit. The following is the result of some investigations in PHP internals. *PHP version used at time of writing is **7.4.2**.* ## Destructor Registration When cURL package functions are registered (using [PHP_MINIT_FUNCTION](https://www.php.net/manual/en/internals2.pdo.implementing.php) extension function), a destructor [`_php_curl_close()`](https://github.com/php/php-src/blob/b9c157726bf4229d694ec840daf4dc6ccb1c3898/ext/curl/interface.c#L3352) associated to resource type "curl" is [registered](https://github.com/php/php-src/blob/b9c157726bf4229d694ec840daf4dc6ccb1c3898/ext/curl/interface.c#L407), using function `zend_register_list_destructors_ex()`: ```c le_curl = zend_register_list_destructors_ex(_php_curl_close, NULL, "curl", module_number); ``` *More information at page [Playing with resources](http://www.phpinternalsbook.com/php7/internal_types/zend_resources.html#playing-with-resources).* ## Curl Session Workflow Basic workflow of a cURL session: 1. **Initialize** cURL session by [calling](https://github.com/php/php-src/blob/b9c157726bf4229d694ec840daf4dc6ccb1c3898/ext/curl/interface.c#L1786) `curl_init()`. *Many sub-functions calls will be made:* 1. [Call](https://github.com/php/php-src/blob/b9c157726bf4229d694ec840daf4dc6ccb1c3898/ext/curl/interface.c#L1797) to `curl_easy_init()`. 2. [Call](https://github.com/php/php-src/blob/b9c157726bf4229d694ec840daf4dc6ccb1c3898/ext/curl/interface.c#L1803) to [`alloc_curl_handle()`](https://github.com/php/php-src/blob/b9c157726bf4229d694ec840daf4dc6ccb1c3898/ext/curl/interface.c#L1687). ```c ch = alloc_curl_handle(); ``` 3. [Call](https://github.com/php/php-src/blob/b9c157726bf4229d694ec840daf4dc6ccb1c3898/ext/curl/interface.c#L1820) to `zend_register_resource()`. *This will allow [destruction](#Destructor-Registration) of handle `ch` at the end of the process.* ```c ZVAL_RES(return_value, zend_register_resource(ch, le_curl)); ``` 2. Subsequent calls to cURL functions using handle returned at step 1. 3. **Close** cURL session by [calling](https://github.com/php/php-src/blob/b9c157726bf4229d694ec840daf4dc6ccb1c3898/ext/curl/interface.c#L3254) `curl_close()`. ## Memory Management If `curl_close()` function is not called, the session handle will stay in the [list of resource types](https://www.php.net/manual/en/resource.php) (as registered at step 1.3). At the end of the process, items of this list will be fetched by PHP interpreter and deleted using their related [destructors](#Destructor-Registration). ## Resources - [PHP: Basic memory management - Manual](https://www.php.net/manual/en/internals2.memory.management.php). - [The Resource type: zend_resource — PHP Internals Book](http://www.phpinternalsbook.com/php7/internal_types/zend_resources.html). - [Zend Memory Manager — PHP Internals Book](http://www.phpinternalsbook.com/php7/memory_management/zend_memory_manager.html). - [PHP: Zend API: Hacking the Core of PHP - Manual](https://www.php.net/manual/en/internals2.ze1.zendapi.php).