Освобождается ли память, используемая file_get_contents (), когда она не назначена переменной? - PullRequest
3 голосов
/ 02 февраля 2009

Когда я использую file_get_contents и передаю его как параметр другой функции, не назначая ее переменной, освобождается ли эта память до завершения выполнения скрипта?

Например:

preg_match($pattern, file_get_contents('http://domain.tld/path/to/file.ext'), $matches);

Будет ли освобождена память, используемая file_get_contents до завершения работы скрипта?

Ответы [ 4 ]

10 голосов
/ 02 февраля 2009

Временная строка, созданная для хранения содержимого файла, будет уничтожена. Не углубляясь в источники для подтверждения, вот несколько способов проверить, уничтожается ли временное значение, созданное в качестве параметра функции:

Метод 1: класс, который сообщает о своем уничтожении

Это демонстрирует время жизни с использованием класса, который сообщает о своей смерти:

class lifetime
{
    public function __construct()
    {
         echo "construct\n";
    }
    public function __destruct()
    {
         echo "destruct\n";
    }


}

function getTestObject()
{
   return new lifetime();
}


function foo($obj)
{
   echo "inside foo\n";
}




echo "Calling foo\n";
foo(getTestObject());
echo "foo complete\n";

Это выводит

Calling foo
construct
inside foo
destruct
foo complete

Что означает, что подразумеваемая временная переменная уничтожена сразу после вызова функции foo.

Метод 2: измерение использования памяти

Вот еще один метод, который предлагает дальнейшее подтверждение, используя memory_get_usage , чтобы измерить, сколько мы потребили.

function foo($str)
{
   $length=strlen($str);

   echo "in foo: data is $length, memory usage=".memory_get_usage()."\n";
}

echo "start: ".memory_get_usage()."\n";
foo(file_get_contents('/tmp/three_megabyte_file'));
echo "end: ".memory_get_usage()."\n";

Это выводит

start: 50672
in foo: data is 2999384, memory usage=3050884
end: 51544
0 голосов
/ 14 апреля 2015

Если вы считаете, что это поможет вам избежать ошибок памяти, вы ошибаетесь. Ваш код ( bytes_format ):

<?php
$url = 'http://speedtest.netcologne.de/test_10mb.bin';
echo 'Before: ' . bytes_format(memory_get_usage()) . PHP_EOL;
preg_match('~~', file_get_contents($url), $matches);
echo 'After: ' . bytes_format(memory_get_usage()) . PHP_EOL;
echo 'Peak: ' . bytes_format(memory_get_peak_usage(true)) . PHP_EOL;
?>

использует 10,5 МБ:

Before: 215.41 KB
After: 218.41 KB
Peak: 10.5 MB

и этот код:

<?php
$url = 'http://speedtest.netcologne.de/test_10mb.bin';
echo 'Before: ' . bytes_format(memory_get_usage()) . PHP_EOL;
$contents = file_get_contents($url);
preg_match('~~', $contents, $matches);
unset($contents);
echo 'After: ' . bytes_format(memory_get_usage()) . PHP_EOL;
echo 'Peak: ' . bytes_format(memory_get_peak_usage(true)) . PHP_EOL;
?>

также использует 10,5 МБ:

Before: 215.13 KB
After: 217.64 KB
Peak: 10.5 MB

Если вы хотите защитить свой скрипт, вам нужно использовать параметр $length или прочитать файл кусками .

0 голосов
/ 19 марта 2014

При следующем использовании памяти кода = 6493720

начало: 1050504

конец: 6492344

echo "start: ".memory_get_usage()."\n";
$data = file_get_contents("/six_megabyte_file");
echo "end: ".memory_get_usage()."\n";

но использование памяти в следующем коде = 1049680

start = 1050504

end = 1050976

echo "start: ".memory_get_usage()."\n";
file_get_contents("/six_megabyte_file");
echo "end: ".memory_get_usage()."\n";

Примечание: в первом файле кода хранится переменная.

0 голосов
/ 02 февраля 2009

В вашем примере память будет освобождена, когда $matches выйдет из области видимости.
Если вы не сохраните результат матча, память будет немедленно освобождена

...