Непонятно, о чем ты просишь. Но в целом, что я настоятельно рекомендую, это избегать запросов в цикле:
Так что все, что ваш фрагмент кода:
$properties = Property::where('status', 'Active');
foreach($properties as $property) { // 100+ times
$bookings = Booking::where('status', 'Approved')->where('checked_in', 1)->where('propId', $property->id)->get();
$commission = 0.0; // commissions owed to us
$commissionOta = 0.0; // any commissions owed to OTA's
foreach($bookings as $booking) { // 2000+ times
$commission += $booking->commission;
$commissionOta += $booking->commissionOta;
}
$totalReceived = PaymentReceived::where('propId', $property->id)->sum('amount'); // any amounts paid by the property owner
$property->payable = ($commission + $commissionOta) - $totalReceived;
}
Кажется, равны только этому запросу:
SELECT p.id,
SUM(b.commission) s_comm,
SUM(b.commissionOta) s_commOta,
SUM(b.commission) + SUM(b.commissionOta) - pr.amount payable
FROM Property p
INNER JOIN Booking b
ON b.propOd = p.id
AND b.status = 'Approved'
AND checked_in = 1
LEFT JOIN (
SELECT pr.propId, SUM(pr.amount) amount
FROM PaymentReceived pr
GROUP BY pr.propId
) pr
ON pr.propId = p.id
WHERE p.status = 'Active'
GROUP BY p.id
Попробуйте выполнить этот запрос. Проверьте набор результатов и производительность и попробуйте адаптировать свой код для использования одного запроса вместо циклических запросов к БД.
Для Laravel это должно быть что-то вроде:
$result = DB::select('SELECT p.id,
SUM(b.commission) s_comm,
SUM(b.commissionOta) s_commOta,
SUM(b.commission) + SUM(b.commissionOta) - pr.amount payable
FROM Property p
INNER JOIN Booking b
ON b.propOd = p.id
AND b.status = \'Approved\'
AND checked_in = 1
LEFT JOIN (
SELECT pr.propId, SUM(pr.amount) amount
FROM PaymentReceived pr
GROUP BY pr.propId
) pr
ON pr.propId = p.id
WHERE p.status = \'Active\'
GROUP BY p.id');
foreach($result as $r){
echo 'Property id: '.$r->id.' Commission: '.$r->s_comm. ' Commission Ota: '.$r->commissionOta .' Payable: '.$r->payable ;
}
Другая идея, которую вы должны попытаться реализовать, - сократить / закрыть период . Прямо сейчас, если я правильно понимаю, вы пересчитываете все данные с самого начала каждого месяца или какого-либо другого периода. Но, как правило, вам следует сохранять некоторые сбалансированные результаты за предыдущий период и пересчитывать только разницу на основе данных за последний период.
Достаточно странно заголовок к Вашему вопросу является в основном ответом на него. Вы хотите сделать что-то вроде этого, с помощью mysqli параметризированные запросы:
$db = new mysqli(<database connection info here>);
$name = "michael";
$age = 20;
$stmt = $db->prepare("SELECT $fields FROm $table WHERE name = ? AND age = ?");
$stmt->bind_param("si", $name, $age);
$stmt->execute();
$stmt->close();
Больше информации в mysqli разделе руководства, конкретно функции, связанные с MySQLi_STMT.
Обратите внимание, что я лично предпочитаю использовать PDO по mysqli, мне не нравится весь bind_param
/ bind_result
материал, который делает mysqli. Если я должен использовать его, я пишу обертку вокруг этого, чтобы заставить его работать больше как PDO.