bhylu.com

Advertisements

PHP Loan Request Project

Build a small in-memory lending operation with one clear invariant: successful reservations reduce available stock, while rejected requests leave it unchanged.

Your brief

Write the rule and its tests before adding a form or database. This model is deliberately single-process and has no durable storage, so it cannot coordinate real concurrent borrowers. Returning a boolean separates a normal capacity rejection from an invalid-input exception. A later database implementation should preserve the observable contract through an authorised transactional operation rather than sharing this object between web requests.

Run it locally

Run this complete source locally with PHP 8.2 or newer. Save it using the filename shown and run the command below. PHP is not currently available in Bhylu’s browser playground. Apache and MySQL are not needed for an ordinary CLI example.

php -l loan-project.php
php loan-project.php

Download this source as a local PHP lab file. Keep lab files separate from the Bhylu project and production data.

Worked solution

Show the worked solution
PHP 8.2+ · loan-project.php

<?php
declare(strict_types=1);

class LendingDesk {
    public function __construct(private int $available) { if ($available<0) throw new InvalidArgumentException("Negative stock"); }
    public function request(int $count): bool {
        if ($count<=0) throw new InvalidArgumentException("Positive request required");
        if ($count>$this->available) return false;
        $this->available-=$count; return true;
    }
    public function remaining(): int { return $this->available; }
}
$desk = new LendingDesk(6);
if (!$desk->request(4)) throw new RuntimeException("First request failed");
if ($desk->request(3)) throw new RuntimeException("Overdraw accepted");
if ($desk->remaining()!==2) throw new RuntimeException("Rejection changed stock");
echo "Reservation contract passed; 2 remain\n";

Expected result

Reservation contract passed; 2 remain

The three explicit checks cover acceptance, rejection and unchanged state. They fail the run even when PHP assertions are disabled. The remaining count belongs only to this object. Before turning it into a real endpoint, add parsed input, authentication/authorisation, CSRF where applicable and a database consistency boundary.

Extend and test

Add returnUnits with a capacity invariant and test repeated or invalid returns.

Check the official PHP manual for detailed version and API contracts.