پردازش داده های کارآمد با ژنراتورهای PHP

PHP مدرن شامل می شود ژنراتور، که به شما امکان می دهد بدون استفاده از حافظه زیاد با مجموعه داده های بزرگ کار کنید. به جای ساختن یک آرایه عظیم و سپس حلقه زدن از طریق آن ، یک ژنراتور از آن استفاده می کند yield
برای بازگشت یک مورد همزمان. این فقط مقدار فعلی را در حافظه نگه می دارد.
مثال: تولید اعداد
function getNumbersWithGenerator(int $max): Generator {
for ($i = 1; $i <= $max; $i++) {
yield $i;
}
}
// Only one number is in memory at once:
foreach (getNumbersWithGenerator(1_000_000) as $n) {
// Process $n…
}
اگر ابتدا سعی کردید مجموعه ای از یک میلیون شماره را بسازید ، PHP از حافظه زیادی استفاده می کند. با یک ژنراتور کوچک می ماند.
مثال: خواندن یک فایل بزرگ CSV
function readCsvLineByLine(string $filename): Generator {
if (!is_readable($filename)) {
throw new InvalidArgumentException("Cannot read: $filename");
}
$handle = fopen($filename, 'r');
if (!$handle) {
throw new RuntimeException("Failed to open: $filename");
}
// First row is the header:
$header = fgetcsv($handle);
while (($row = fgetcsv($handle)) !== false) {
yield array_combine($header, $row);
}
fclose($handle);
}
// Use it like this:
foreach (readCsvLineByLine(__DIR__ . '/large-data.csv') as $record) {
// Each $record is an associative array, e.g. ['id'=>'123', 'name'=>'Alice', …]
// Process $record without loading the entire file into memory.
}
چون fgetcsv()
یک خط را در یک زمان می خواند و yield
یک ردیف را برمی گرداند ، PHP هرگز کل پرونده را به طور همزمان بار نمی کند.
چه زمانی از ژنراتورها استفاده کنیم
- واکشی هزاران ردیف پایگاه داده:
yield
هر ردیف به جایfetchAll()
بشر - پردازش پرونده های بزرگ ورود به سیستم یا خط پرونده های متنی به صورت خط.
- هر شرایطی که در غیر این صورت می توانید یک آرایه عظیم بسازید.
ژنراتورها باعث می شوند کد PHP شما را “تنبل” اجرا کند: مقادیر بر اساس تقاضا تولید می شوند. این باعث می شود مصرف حافظه کم باشد و از کندی جلوگیری می کند. دفعه بعد که باید داده های بزرگ را در PHP انجام دهید ، یک عملکرد ژنراتور را امتحان کنید!