> For the complete documentation index, see [llms.txt](https://quantumphp.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://quantumphp.gitbook.io/docs/packages/hasher/contracts.md).

# Contracts

The Hasher package has no interfaces, but its runtime behavior is still shaped by a few important contracts.

## Bcrypt cost validation happens only for bcrypt

`setCost()` enforces the bcrypt cost range only when the current algorithm is exactly `PASSWORD_BCRYPT`.

Accepted bcrypt range:

* minimum: `4`
* maximum: `31`

Outside that range, the method throws `HasherException::invalidBcryptCost()`.

This validation is stateful. It depends on the algorithm that is currently set on the instance when `setCost()` runs.

Practical rule: if you plan to change both values, call `setAlgorithm()` first and `setCost()` second.

## Algorithm changes are not validated by the package

`setAlgorithm()` assigns the provided string directly and returns the same instance.

The package defines `HasherException::algorithmNotSupported(...)`, but `Hasher` does not currently call it.

Practical effect:

* invalid or unsupported algorithm names are not rejected at `setAlgorithm()` time
* failures, if any, happen later inside PHP's password functions

## Hashing and rehash checks use the current instance settings

These methods use the current algorithm and cost stored on the object:

* `hash()`
* `needsRehash()`

If you change either property after creating a hash, `needsRehash()` can flip from `false` to `true` for the same stored hash.

That is how the package signals that an existing password should be upgraded to newer hashing settings.

## Verification is hash-driven, not config-driven

`check()` only calls `password_verify($password, $hash)`.

It does not compare the stored hash against the instance's configured algorithm or cost first.

So this is valid:

* hash a password with one `Hasher` configuration
* verify it later with another `Hasher` object configured differently

Use `needsRehash()` separately when you want to enforce current hashing settings after a successful login.

## Getters expose the current instance state

`getAlgorithm()` and `getCost()` return the values currently stored on that `Hasher` instance.

They do not inspect an existing hash. Use them to confirm how the object is configured before calling `hash()` or `needsRehash()`, not to infer how an already-stored password was created.

## Metadata comes from the hash

`info()` returns `password_get_info($hash)` directly.

That means its result reflects the provided hash payload, not the current `Hasher` object's local properties.

## Exception surface

The package exposes two exception factories:

* `HasherException::invalidBcryptCost()`
* `HasherException::algorithmNotSupported(string $algorithm)`

In current package code, only `invalidBcryptCost()` is thrown by `Hasher` itself.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://quantumphp.gitbook.io/docs/packages/hasher/contracts.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
