PHPackages                             webiik/attempts - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. webiik/attempts

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

webiik/attempts
===============

The Attempts provides common interface for user actions monitoring.

1.0(7y ago)03MITPHPPHP &gt;=7.2

Since Mar 28Pushed 7y ago1 watchersCompare

[ Source](https://github.com/webiik/attempts)[ Packagist](https://packagist.org/packages/webiik/attempts)[ Docs](https://www.webiik.com)[ RSS](/packages/webiik-attempts/feed)WikiDiscussions master Synced 3d ago

READMEChangelogDependenciesVersions (2)Used By (0)

[![](https://camo.githubusercontent.com/a397347ee4fb199934fee6354504f4702b89f5c22f0ce0ba94c5ff691cde545c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f77656269696b2f77656269696b2e737667)](https://camo.githubusercontent.com/a397347ee4fb199934fee6354504f4702b89f5c22f0ce0ba94c5ff691cde545c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f77656269696b2f77656269696b2e737667)[![](https://camo.githubusercontent.com/20f4b99a958aadb02ff273ac6428c17cf55c6b817657ed64b1c39c7f71955a0e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d302d627269676874677265656e2e737667)](https://camo.githubusercontent.com/20f4b99a958aadb02ff273ac6428c17cf55c6b817657ed64b1c39c7f71955a0e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d302d627269676874677265656e2e737667)

Attempts
========

[](#attempts)

The Attempts provides common interface for user actions monitoring.

Installation
------------

[](#installation)

```
composer require webiik/attempts
```

Example
-------

[](#example)

> The following example expects you have already written [your custom storage](#setstorage).

```
// Instatiate Attempts
$attempts = new \Webiik\Attempts\Attempts();

// Set storage (you have to write your own storage)
$attempts->setStorage(function() {
    return new \Webiik\Attempts\YourCustomStorage();
});

// Store user login attempt
$attempts->write('login', $attempts->getIp());

// Get user login attempts within the last hour
$startTimestamp = time() - 60 * 60;
$loginAttempts = $attempts->readByIp('login', $attempts->getIp(), $startTimestamp);

if(count($loginAttempts) > 10) {
    // E.g. Temporary prevent user to log in
}

// Delete expired login attempts with probability 2/100
$attempts->delete('login', $startTimestamp, 2);
```

Configuration
-------------

[](#configuration)

### setStorage

[](#setstorage)

```
setStorage(callable $factory): void
```

**setStorage()** sets storage factory. Storage writes, reads and deletes user attempts. Every storage must implement [StorageInterface](StorageInterface.php). Take a look at [StorageInterface](StorageInterface.php) to get more info. Keep on mind you have to write your own storage. For example, you can write storage that uses MySQL database to write, read and delete user attempts.

```
$attempts->setStorage(function() {
    return new \Webiik\Attempts\YourCustomStorage();
});
```

User Identifier
---------------

[](#user-identifier)

### getIp

[](#getip)

```
getIp(): string
```

**getIp()** returns user IP address.

```
$ip = $attempts->getIp();
```

Attempts
--------

[](#attempts-1)

### write

[](#write)

```
write(string $label, string $ip, string $hash = ''): void
```

**write()** writes user attempt to storage.

**Parameters**

- **label** label representing user action e.g. login
- **ip** user IP address (simple user identifier)
- **hash** advanced user identifier e.g. hash from user IP, OS, browser language and installed fonts

```
$attempts->write('login', $ip, $hash);
```

### read

[](#read)

```
read(string $label, string $ip, string $hash, int $startTimestamp = 0): array
```

**read()** reads user attempts from storage by **label**, **hash** and **ip** starting from **startTimestamp**.

```
$startTimestamp = time() - 60 * 60;
$loginAttempts = $attempts->read('login', $ip, $hash, $startTimestamp);
```

### readByIp

[](#readbyip)

```
readByIp(string $label, string $ip, int $startTimestamp = 0): array
```

**readByIp()** reads user attempts from storage by **label** and **ip** starting from **startTimestamp**.

```
$startTimestamp = time() - 60 * 60;
$loginAttempts = $attempts->readByIp('login', $ip, $startTimestamp);
```

### readByHash

[](#readbyhash)

```
readByHash(string $label, string $hash, int $startTimestamp = 0): array
```

**readByHash()** reads user attempts from storage by **label** and **hash** starting from **startTimestamp**.

```
$startTimestamp = time() - 60 * 60;
$loginAttempts = $attempts->readByHash('login', $hash, $startTimestamp);
```

### delete

[](#delete)

```
delete(string $label, int $timestamp, int $probability = 1): void
```

**delete()** deletes user attempts from storage by the specific **label**, older than the **timestamp**, with default **probability** 1/100.

```
$olderThanTimestamp = time() - 60 * 60;
$attempts->delete('login', $olderThanTimestamp);
```

### deleteAll

[](#deleteall)

```
deleteAll(int $timestamp, int $probability = 1): void
```

**deleteAll()** deletes user attempts from storage older than the **timestamp**, with default **probability** 1/100.

```
$olderThanTimestamp = time() - 60 * 60;
$attempts->delete($olderThanTimestamp);
```

Resources
---------

[](#resources)

- [Webiik framework](https://github.com/webiik/webiik)
- [Report issue](https://github.com/webiik/components/issues)

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity3

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

2604d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/1226362d003d186b45e7dfa44489c36af37196c6a1b476206700eaf4e9c96a5a?d=identicon)[Jiri Mihal](/maintainers/Jiri%20Mihal)

---

Top Contributors

[![Jiri-Mihal](https://avatars.githubusercontent.com/u/10408123?v=4)](https://github.com/Jiri-Mihal "Jiri-Mihal (1 commits)")

---

Tags

attempts

### Embed Badge

![Health badge](/badges/webiik-attempts/health.svg)

```
[![Health](https://phpackages.com/badges/webiik-attempts/health.svg)](https://phpackages.com/packages/webiik-attempts)
```

###  Alternatives

[psr/log

Common interface for logging libraries

10.4k1.2B9.2k](/packages/psr-log)[itsgoingd/clockwork

php dev tools in your browser

5.9k27.6M94](/packages/itsgoingd-clockwork)[graylog2/gelf-php

A php implementation to send log-messages to a GELF compatible backend like Graylog2.

41838.2M138](/packages/graylog2-gelf-php)[bugsnag/bugsnag-psr-logger

Official Bugsnag PHP PSR Logger.

32132.5M2](/packages/bugsnag-bugsnag-psr-logger)[consolidation/log

Improved Psr-3 / Psr\\Log logger based on Symfony Console components.

15462.2M7](/packages/consolidation-log)[datadog/php-datadogstatsd

An extremely simple PHP datadogstatsd client

19124.6M15](/packages/datadog-php-datadogstatsd)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
