---
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).