PHPackages                             tuupola/whereami - 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. tuupola/whereami

ActiveLibrary

tuupola/whereami
================

Common interface for wifi positioning services

0.4.1(8y ago)33441[1 PRs](https://github.com/tuupola/whereami/pulls)MITPHPPHP ^5.6 || ^7.0

Since Apr 16Pushed 8y ago3 watchersCompare

[ Source](https://github.com/tuupola/whereami)[ Packagist](https://packagist.org/packages/tuupola/whereami)[ Docs](https://github.com/tuupola/whereami)[ RSS](/packages/tuupola-whereami/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependencies (11)Versions (7)Used By (0)

Whereami
========

[](#whereami)

[![Latest Version](https://camo.githubusercontent.com/eb44b020ee62ae0b7c2f46bd1c6b7d7b93d8919707788d2edcc310e3f85e7be3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f747575706f6c612f7768657265616d692e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tuupola/whereami)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Build Status](https://camo.githubusercontent.com/2e117781187a3115350af5ba316ad8c52ab7c94d9e8e6075f0cfc6673b88731b/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f747575706f6c612f7768657265616d692f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/tuupola/whereami)[![Coverage](https://camo.githubusercontent.com/fc31b765df80bdb6bc4520465148409ffcd739019ff287b09a17934ecf8223dc/687474703a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f747575706f6c612f7768657265616d692e7376673f7374796c653d666c61742d737175617265)](https://codecov.io/github/tuupola/whereami)

Common PHP interface for wifi positioning services, inspired by [whoami](https://linux.die.net/man/1/whoami).

[![Whereami](https://camo.githubusercontent.com/5d1dde73375e72760e39564df6001ccbcc6bf2be90becd6f876104357481f37b/687474703a2f2f7777772e617070656c7369696e692e6e65742f696d672f7768657265616d692d686561646c696e652d313430302d322e706e67)](https://camo.githubusercontent.com/5d1dde73375e72760e39564df6001ccbcc6bf2be90becd6f876104357481f37b/687474703a2f2f7777772e617070656c7369696e692e6e65742f696d672f7768657265616d692d686561646c696e652d313430302d322e706e67)

Install
-------

[](#install)

Install the library using [Composer](https://getcomposer.org/). You will also need to choose a [HTTP client](http://docs.php-http.org/en/latest/clients.html) for example [php-http/curl-client](http://docs.php-http.org/en/latest/clients/curl-client.html).

```
$ composer require tuupola/whereami
$ composer require php-http/curl-client
```

If you do not install HTTP client you will get `No HTTPlug clients found` and `Puli Factory is not available` errors. Ignore the Puli part, you do not need it. Just install an HTTP client.

Finally if your project does not already have one, you must include a PSR-7 implementation. Good candidate is `zendframework/zend-diactoros`. Many frameworks such as [Slim](https://www.slimframework.com/) and [Expressive](https://docs.zendframework.com/zend-expressive/) already include PSR-7 by default and this part is not needed.

```
$ composer require zendframework/zend-diactoros
```

Usage
-----

[](#usage)

### Current location

[](#current-location)

To find current computers location you must provide wifi location service provider and optionally a wifi network scanner. With macOS you can use `AirportScanner` which does not require any extra setup. With Linux based systems you can use `IwlistScanner` which needs root privileges to be run. Example below uses [Mozilla Location Service](https://location.services.mozilla.com/).

```
require __DIR__ . "/vendor/autoload.php";

use Whereami\Provider\MozillaProvider;
use Whereami\Scanner\AirportScanner;
use Whereami\Whereami;

$provider = new MozillaProvider("your-api-key-here");
$scanner = new AirportScanner;
$locator = new Whereami($provider, $scanner);

$location = $locator->whereami();

/*
Array
(
    [latitude] => 1.355989
    [longitude] => 103.992365
    [accuracy] =>  65
)
*/
```

Pro tip! Like mentioned above providing scanner is optional. If scanner is not provided system will try to autodetect it. This way same code should work in both macOS and \*NIX systems.

```
require __DIR__ . "/vendor/autoload.php";

use Whereami\Provider\MozillaProvider;
use Whereami\Whereami;

$provider = new MozillaProvider("your-api-key-here");
$locator = new Whereami($provider);

$location = $locator->whereami();
```

### Third party location

[](#third-party-location)

Sometimes it is useful to locate third party locations. For example you might have several IoT devices whose location you need to track. You can locate these by calling `$locator->whereis($networks)` method with network info as a parameter.

```
require __DIR__ . "/vendor/autoload.php";

use Whereami\Provider\MozillaProvider;
use Whereami\Whereami;

$provider = new MozillaProvider("your-api-key-here");
$locator = new Whereami($provider);

$networks[] = [
    "name" => "#WiFi@Changi",
    "address" => "64:d8:14:72:60:0c",
    "signal" => -90,
    "channel" => 149,
];

$networks[] = [
    "name" => "#WiFi@Changi",
    "address" => "10:bd:18:5f:e9:83",
    "signal" => -70,
    "channel" => 6,
];

$location = $locator->whereis($networks);

/*
Array
(
    [latitude] => 1.3558172
    [longitude] => 103.9915859
    [accuracy] => 38
)
*/
```

Providers
---------

[](#providers)

### Combain Provider

[](#combain-provider)

This provider uses [Combain CPS API](https://combain.com/api/). It requires an API key but they do offer [free evaluation account](https://combain.com/sign-up/) for developers.

```
use Whereami\Provider\CombainProvider;

$provider = new CombainProvider("your-api-key-here");
```

### Google Geolocation Provider

[](#google-geolocation-provider)

This provider uses [The Google Maps Geolocation API](https://developers.google.com/maps/documentation/geolocation/intro). You will need an [API key](https://developers.google.com/maps/documentation/geolocation/get-api-key). There are some [limits on free usage](https://developers.google.com/maps/documentation/geolocation/usage-limits).

```
use Whereami\Provider\GoogleProvider;

$provider = new GoogleProvider("your-api-key-here");
```

### Google Browserlocation Provider

[](#google-browserlocation-provider)

This provider uses old undocumented browserlocation API. It does not require API key.

```
use Whereami\Provider\BrowserlocationProvider;

$provider = new BrowserlocationProvider(null);
```

### Mozilla Provider

[](#mozilla-provider)

This provider uses [Mozilla Location Service (MLS)](https://location.services.mozilla.com/). It requires an API key but you can use the key `test` for developing.

```
use Whereami\Provider\MozillaProvider;

$provider = new MozillaProvider("your-api-key-here");
```

### Radiocells Provider

[](#radiocells-provider)

This provider uses [Radiocells Network Geolocation Services API](https://radiocells.org/geolocation). It is free to use and does not require an API key.

```
use Whereami\Provider\RadiocellsProvider;

$provider = new RadiocellsProvider(null);
```

### Unwired Provider

[](#unwired-provider)

This provider uses [Unwired Labs LocationAPI](https://unwiredlabs.com/locationapi). API key is required but you can sign up for [free developer account](https://unwiredlabs.com/trial).

```
use Whereami\Provider\UnwiredProvider;

$provider = new UnwiredProvider("your-api-key-here");
```

Scanners
--------

[](#scanners)

Scanners scan the surrounding wifi networks and return the results as an array. This array is then given to a provider which uses the network data to retrieve the geoposition.

### Airport Scanner

[](#airport-scanner)

This is the default scanner for macOS. It uses the `airport` commandline tool from Apple80211 framework. Custom command can be passed via constructor. This is optional and should be used for example if your `airport` binary is located in non standard place

```
use Whereami\Scanner\AirportScanner;

$scanner = new AirportScanner("/tmp/airport  --scan 2>&1");
```

### Iwlist With Sudo

[](#iwlist-with-sudo)

This is the default scanner for Linux and other \*NIX based systems. It uses the [iwlist](https://linux.die.net/man/8/iwlist) commandline tool. This scanner is bit more complicated to set up since it needs root privileges to be run.

There are several ways to get around this. The default one is to give your webserver privileges to run `sudo iwlist` without password by editing the `/etc/sudoers` file.

```
$ sudo visudo

```

Then add the following to the end of the file.

```
apache ALL=(ALL) NOPASSWD: /sbin/iwlist

```

After editing the file save and exit. Make sure you can run the command as your webserver user.

```
$ sudo su apache
$ /sbin/iwlist scan

```

If you can see the scan results you are good to go.

```
use Whereami\Scanner\IwlistScanner;

$scanner = new IwlistScanner;
```

### Iwlist Without Sudo

[](#iwlist-without-sudo)

If you do not want to give the webserver privileges to run `iwlist` as root you could set up a root cronjob which writes the scan results to text file instead.

```
$ sudo crontab -e

```

Add the following line to the crontab. This will run the scan every 10 minutes.

```
*/10 * * * * /sbin/iwlist scan > /tmp/iwlist.txt

```

After editing the file save and exit. Wait for 10 minutes to make sure your cron entry works.

```
$ cat /tmp/iwlist.txt

```

If you can see the scan results you are good to go. However you must use custom command which uses the output from the cronjob.

```
use Whereami\Scanner\IwlistScanner;

$scanner = new IwlistScanner("cat /tmp/iwlist.txt");
```

Adapters
--------

[](#adapters)

Some operating have commandline tools for determining the current position. Adapters provide an interface for these. You can use an adapter for developing if you do not have access to any external geopositioning provider.

```
require __DIR__ . "/vendor/autoload.php";

use Whereami\Adapter\CoreLocationAdapter;
use Whereami\Whereami;

$adapter = new CoreLocationAdapter;
$locator = new Whereami($adapter);

$location = $locator->whereami();
```

Note that adapters always return the location of the current machine. They cannot be used to determine third party location. Trying to do so will trigger a PHP warning.

### Corelocation

[](#corelocation)

This adapter uses the macOS [CoreLocationCLI](https://github.com/fulldecent/corelocationcli) tool. Internally it uses [Core Location](https://developer.apple.com/reference/corelocation) services. Install it using Homebrew.

```
$ brew install corelocationcli

```

```
use Whereami\Adapter\CoreLocationAdapter;

$adapter = new CoreLocationAdapter;
```

### LocateMe

[](#locateme)

This adapter uses the macOS [LocateMe](http://iharder.sourceforge.net/current/macosx/locateme/) tool. Internally it uses [Core Location](https://developer.apple.com/reference/corelocation) services. Install it using Homebrew.

```
$ brew install locateme

```

```
use Whereami\Adapter\LocateMeAdapter;

$adapter = new LocateMeAdapter;
```

Testing
-------

[](#testing)

You can run tests either manually or automatically on every code change. Automatic tests require [entr](http://entrproject.org/) to work.

```
$ make test
```

```
$ brew install entr
$ make watch
```

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity18

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity52

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

Every ~78 days

Total

4

Last Release

3081d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3325405a7d8a43bc40dd0e760a4b7f268fba32a7150cf0327f64f13d1661df0b?d=identicon)[tuupola](/maintainers/tuupola)

---

Top Contributors

[![tuupola](https://avatars.githubusercontent.com/u/21913?v=4)](https://github.com/tuupola "tuupola (59 commits)")

---

Tags

geopositionwifiwlocwifigeoposition

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/tuupola-whereami/health.svg)

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

###  Alternatives

[j0k3r/graby

Graby helps you extract article content from web pages

384349.6k2](/packages/j0k3r-graby)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)[brd6/notion-sdk-php

Notion SDK for PHP

5918.0k](/packages/brd6-notion-sdk-php)[php-soap/psr18-wsse-middleware

Adds WSSE security to your HTTP SOAP Transport

12491.9k6](/packages/php-soap-psr18-wsse-middleware)[darthsoup/php-whmcs-api

WHMCS API client for PHP

2317.3k4](/packages/darthsoup-php-whmcs-api)[dhope0000/lxd

PHP-based API wrapper for LXD REST API.

136.2k](/packages/dhope0000-lxd)

PHPackages © 2026

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