PHP MySQLi Functions

Функція PHP mysqli_free_result()

Матеріал представлений на сторінці за w3schools та php.net ресурсами.

Загальна інформація

1. Основи

Документація php free result

PHP mysqli_free_result() очищує пам'ять, що була задіяна в результуючій вибірці даних з таблиці Бази Даних.

Синтаксис

Функція mysqli_free_result() може бути виконана, як в об'єктно-орієнтовному стилі програмування, так і в процедурному стилі програмування.

Наприклад, застосуємо скрипт в ООП:

// створюємо обєкт зєднання з БД
$db = new mysqli("host", "user", "pass", "DB");
//SQL-запит
$query = "SELECT * FROM My_Test";
// виконуємо запит до БД
$results = $db->query($query);
  // виконуємо операції з даними $results
// очищаємо память
$results->free();
// закриваємо зєднання з БД
$db->close();

Або зразок процедурного стилю:

// створюємо обєкт зєднання з БД
$db = mysqli_connect("host", "user", "pass", "DB");
//SQL-запит
$query = "SELECT * FROM My_test";
// виконуємо запит до БД
$results=mysqli_query($db,$query);
  // виконуємо операції з даними $results
// очищаємо память
mysqli_free_result($results);
// закриваємо зєднання з БД
mysqli_close($db);

Суттєво! Як стверджує офіційна документація:

(Note:
You should always free your result with mysqli_free_result(), when your result object is not needed anymore.)

бажано завжди очищувати память, якщо результати вибірки з таблиці Бази Даних більше не потрібні.

2. Тест функції free result()

Ціль: розглянути роботу функції free result() в різних ситуаціях вибору даних із таблиці Бази Даних.

Для перевірки використаємо функцію:
- memory_get_usage, що вказує обєм задієної памяті php-скриптом.
- var_dump, що виводить значення типу змінної та значення змінної.
- print_r, виводить значення змінної.
- та звичайний echo .

Зробимо вибірку:
- одного значення данного з таблиці,
- асоціативного рядка,
- асоціативний масив значень із таблиці БД;

Тестова таблиця "My_Test" з даними на зразок:

id Name Proffesion
1 Sasha Operator
2 Kolya Operator
3 Olya Secretary
4 Max Student


Тест 1.
Вибір одного значення з таблиці.

Реалізуємо тест, що вибирає кількість записів в таблиці.

Загальна структура скипту в обєктно-орієнтовному стилі програмування для аналізу матиме вигляд на зразок цього:

//1. Обєм памяті скрипту до підключення до БД
echo memory_get_usage();

// створюємо обєкт зєднання з БД
$db = new mysqli ("host", "user", "pass", "DB");

//2. Обєм памяті після підключення до БД
echo memory_get_usage();

$query = "SELECT * FROM My_Тest";
$results = $db->query($query);
Примітка!Функція free_result() очищає вибірку $results

//3. Обєм памяті після вибору даних
echo memory_get_usage();

// рахуємо кількість рядків у вибірці
$row_cnt = $results->num_rows;

// Кількість рядків
echo $row_cnt;

//4. Обєм:
echo memory_get_usage();
//4.1.
var_dump( $results );
//4.2.
print_r( $results );

// Звільняємо память 
$results->free_result();

// Обєм:
echo memory_get_usage();
//5.1.
var_dump ( $results );
//5.2.
print_r ( $results );

$db->close();

//6. Обєм після закриття зєднанння
echo memory_get_usage();


Перевіряємо роботу функції free_result()

1. Обєм памяті скрипту до підключення до БД: 680.13 кБ
2. Обєм памяті після підключення до БД: 680.38 кБ
3. Обєм памяті після вибору даних із таблиці БД: 681.51 кБ

Отримали дані з БД:

Кількість рядків: 4

Аналізуємо результати:

4. Загалом памяті у нас зайняло: 681.65 кБ

4.1. Значення обєкту results за допомогою var_dump():
object(mysqli_result)#1 (5) {
  ["current_field"]=>
  int(0)
  ["field_count"]=>
  int(4)
  ["lengths"]=>
  NULL
  ["num_rows"]=>
  int(4)
  ["type"]=>
  int(0)
}


4.2. Значення обєкту results за допомогою print_r:
mysqli_result Object
(
    [current_field] => 0
    [field_count] => 4
    [lengths] => 
    [num_rows] => 4
    [type] => 0
)

Застосували free_result() аналізуємо:

5. Задіяна память: 681.61кБ
5.1. Значення обєкту results після застосування free_result():
Warning: var_dump(): Couldnt fetch mysqli_result in ...
Warning: var_dump(): Couldnt fetch mysqli_result in ...
Warning: var_dump(): Property access is not allowed yet in ...
Warning: var_dump(): Couldn't fetch mysqli_result in ...
Warning: var_dump(): Property access is not allowed yet in ...

object(mysqli_result)#1 (5) {
  ['current_field']=> NULL
  ['field_count']=> NULL
  ['lengths']=>  NULL
  ['num_rows']=>  NULL
  ['type']=>  NULL
}

5.2. Print_r:
mysqli_result Object
Warning: print_r(): Couldnt fetch mysqli_result in ...
Warning: print_r(): Couldnt fetch mysqli_result in ...
Warning: print_r(): Property access is not allowed ...
Warning: print_r(): Couldnt fetch mysqli_result in ...
Warning: print_r(): Property access is not allowed ...

(   [current_field] => 
    [field_count] => 
    [lengths] => 
    [num_rows] => 
    [type] => 
)


6. Закрили зєднання з БД, память: 681.52 кБ


Тест 2.
Вибираємо один асоціативний рядок даних:

Скрипт майже ідентичний попередньому, єдина вибірка даних з таблиці лише для одного рядка


$query = "SELECT * FROM My_Test";
$results_02 = $db_02->query($query);
$results_02->data_seek(2);
$row_02 = $results_02->fetch_assoc();
echo  $row_02['id']." ".$row_02['Name']." ".$row_02['proffesion'];
// код аналізу до очищення
$results_02->free_result();
// код аналізу після free_result

Результат роботи php-скрипту та аналіз роботи функції free_result():

1. Обєм памяті скрипту до підключення до БД: 681.52 кБ
2. Обєм памяті після підключення до БД: 684.79 кБ

3. Обєм памяті після вибору даних із таблиці БД: 685.93 кБ

Отримали дані з БД (наприклад, третій рядок):

3 Olya Secretary

Аналізуємо результати


4. Загалом памяті у нас зайняло: 686.93 кБ

4.1. Що ж до var_dump обєкту results_02:
object(mysqli_result)#5 (5) {
  ["current_field"]=>
  int(0)
  ["field_count"]=>
  int(4)
  ["lengths"]=>
  array(4) {
    [0]=>
    int(1)
    [1]=>
    int(4)
    [2]=>
    int(9)
    [3]=>
    int(2)
  }
  ["num_rows"]=>
  int(4)
  ["type"]=>
  int(0)
}


4.2. Що ж до print_r обєкту results_02:
mysqli_result Object
(
    [current_field] => 0
    [field_count] => 4
    [lengths] => Array
        (
            [0] => 1
            [1] => 4
            [2] => 9
            [3] => 2
        )

    [num_rows] => 4
    [type] => 0
)


Застосували free result() аналізуємо:

5 Наразі задіяна память: 686.89кБ
5.1. Що ж до var_dump після очищення?:
Warning: var_dump(): Couldnt fetch mysqli_result in ...
Warning: var_dump(): Couldnt fetch mysqli_result in ...
Warning: var_dump(): Property access is not allowed yet in ...
Warning: var_dump(): Couldnt fetch mysqli_result in ...
Warning: var_dump(): Property access is not allowed yet in ...

object(mysqli_result)#5 (5) {
  ['current_field']=> NULL
  ['field_count']=> NULL
  ['lengths']=> NULL
  ['num_rows']=> NULL
  ['type']=>  NULL
}


5.2. Що ж до print_r?
mysqli_result Object
Warning:  print_r(): Couldnt fetch mysqli_result in ...
Warning:  print_r(): Couldnt fetch mysqli_result in ...
Warning:  print_r(): Property access is not allowed yet in ...
Warning:  print_r(): Couldnt fetch mysqli_result in ...
Warning:  print_r(): Property access is not allowed yet in ...

(   [current_field] => 
    [field_count] => 
    [lengths] => 
    [num_rows] => 
    [type] => 
)


6 Закрили зєднання з БД, память: 686.8 кБ


Тест 3.
Вибираємо асоціативний масив даних:

Виберемо асоціативний масив даних із таблиці БД:


$query = "SELECT * FROM My_Test";
$results_03 = $db_03->query($query);
while ($row_03 = $results_03->fetch_assoc()){
  echo $row_03['id']." ".$row_03['Name']. " ".$row_03['proffesion'];
};
// код аналізу до очищення
$results_03->free_result();
// код аналізу після free_result

1. Обєм памяті скрипту до підключення до БД: 686.8 кБ
2. Обєм памяті після підключення: 690.07 кБ

3. Обєм памяті після вибору даних із таблиці БД: 691.2 кБ

Отримали дані з БД:

1 Sasha Operator
2 Kolya Operator
3 Olya Secretary
4 Max Student

Аналізуємо результати:

4 Використана память: 691.34 кБ

4 1 Що ж стверджує Var_dump по обєкту $results_03:
object(mysqli_result)#7 (5) {
  ["current_field"]=>
  int(0)
  ["field_count"]=>
  int(4)
  ["lengths"]=>
  NULL
  ["num_rows"]=>
  int(4)
  ["type"]=>
  int(0)
}


4 2 Що ж до print_r?
mysqli_result Object
(
    [current_field] => 0
    [field_count] => 4
    [lengths] => 
    [num_rows] => 4
    [type] => 0
)

Застосували free result() аналізуємо:

5 Память: 691.3кБ
5.1. var_dump обєкту:
Warning: var_dump(): Couldn't fetch mysqli_result in...
Warning: var_dump(): Couldn't fetch mysqli_result in...
Warning: var_dump(): Property access is not allowed yet in...
Warning: var_dump(): Couldn't fetch mysqli_result in...
Warning: var_dump(): Property access is not allowed yet in...

object(mysqli_result)#7 (5) {
  ['current_field']=> NULL
  ['field_count']=> NULL
  ['lengths']=> NULL
  ['num_rows']=> NULL
  ['type']=> NULL
}
6. Закрили зєднання з БД, память: 691.2 кБ


Супутні питання стосовно free result

- Що краще використовувати close() чи free()?

Відповідь на ресурсі stackoverflow.com MySQLi query results: Best approach, do you close, free, both?

Процитую доречний коментар:

As has already been pointed out, PHPs execution pattern means that everything will eventually be cleaned up behind you, and thus, you dont necessarily need to worry about releasing memory. However, if youre allocating a lot of result objects, or if you are allocating particularly big result objects (e.g., fetching a large amount of data), then you should probably free the memory when you are done to prevent problems further down the path of execution. This becomes especially important as your application starts to get more traffic, where the total amount of memory tied up across sessions can quickly become significant.

Що має приблизно такий зміст:

Патерн PHP скриптів виконується таким чином, що все буде очищено по завершенні,- тому немає необхідності турбуватись за очищення памяті. Тим не менш, якщо ви маєте багато результуючих вибірок з бази, чи маєте досить здоровий один обєкт ( наприклад дістали велику кількість даних), то вам бажано було б почистити память таким чином упереджуючи проблеми в подальшому під час вашої роботи. Це може бути особливо важливим коли ваші додатки беруть багато ресурсів(трафіку), та де загальний обєм памяті зменшується під час сесій.




- На цьому розгляд функції free_result() завершу, найкращого в програмуванні та й просто в житті :)

Анатолій. Березень 2016