← Articles

PHP Adapter: change a provider format without changing the client

Separate an external provider’s data format from application code: money conversion, adapter responsibilities and common mistakes.

Underlined terms have explanations. Copy the code and run it locally.

Contents and terms

Terms at hand

Select a term to see its definition.

Full glossary →

Problem: two units for the same price

A price provider returns the text 12.34. Your code uses integer , so it needs 1234. Scattering the conversion across controllers makes it easy to multiply twice or handle the same error differently in another .

An translates one into another. The price client should receive an agreed unit regardless of the provider's format.

Flow: provider text 12.34 → format → unit conversion → 1234 minor units → client.

A small runnable example

Save as adapter.php and run php adapter.php. No framework, or network is needed.

php
<?php
declare(strict_types=1);
function toMinor(string $major): int {
    if (!preg_match('/^[0-9]{1,4}\.[0-9]{2}$/D', $major)) {
        throw new InvalidArgumentException('Unsupported price format');
    }
    [$whole, $fraction] = explode('.', $major);
    return (int) $whole * 100 + (int) $fraction;
}
echo toMinor('12.34'), PHP_EOL;

The output is 1234. Four digits before the dot and two after it deliberately limit this small contract. This is not a general parser or rounding policy.

Trace the execution

preg_match rejects a format outside the contract. explode splits the text into 12 and 34. Only the whole part is multiplied by 100; the fraction already represents minor units. The calculation does not go through float.

12.345 throws an . Silently dropping the final digit would hide the missing rounding rule. For a second provider that already returns 1234 minor units, multiplying by 100 again would be a bug.

When does it help?

Separate translation when the external format differs from your contract or changes independently. A is enough for one short conversion. You do not immediately need a class hierarchy or plugin registry.

An Adapter does not verify reservation ownership or provide a . Those rules need their own boundaries and tests.

Check your understanding

Predict the result for 0.01, 10.00 and 12.345, then run them in a separate copy. Which case detects multiplying minor units twice?

Sources

CHECK YOUR INTUITION

Should the client know every provider’s money format?

NOW WRITE YOUR OWN CODE

Put your understanding into practice.

In the PHP workshop, write your own provider adapter and verify it with a test.

Open the learning material →