Skip to content
/ which Public

A cross-platform PHP library for locating commands in a PATH.

License

Notifications You must be signed in to change notification settings

nubs/which

Repository files navigation

Which

A PHP library for locating commands in a PATH.

Build Status Scrutinizer Code Quality Code Coverage

Latest Stable Version Total Downloads License

Dependency Status

Requirements

This library requires PHP 5.6, or newer.

Installation

This package uses composer so you can just add nubs/which as a dependency to your composer.json file or execute the following command:

composer require nubs/which

Example

Here is a quick example to demonstrate how this library is generally meant to be used:

$locatorFactory = new \Nubs\Which\LocatorFactory\PlatformLocatorFactory();
$locator = $locatorFactory->create();

echo $locator->locate('php');
// /usr/bin/php

Usage

Constructing a Locator

There are several ways to create a locator. The preferred way is to use the brianium/habitat constructor. Habitat makes accessing the environment variables easy, even in cases where the $_ENV superglobal isn't populated. You can use it like this:

$habitat = new \Habitat\Habitat();
$environment = $habitat->getEnvironment();
$locatorFactory = new \Nubs\Which\LocatorFactory\PlatformLocatorFactory();
$locator = $locatorFactory->create($environment);

Habitat environment is not necessary. Without passing an environment, PHP's built-in getenv will be used:

$locatorFactory = new \Nubs\Which\LocatorFactory\PlatformLocatorFactory();
$locator = $locatorFactory->create();

There are also two platform-specific factories in case you don't want to rely on the platform detection in the PlatformLocatorFactory. If you are on a POSIXy system (e.g., Linux, OSX, BSD), you can use the PosixLocatorFactory and if you are on a Windows system you can use the WindowsLocatorFactory.

$locatorFactory = new \Nubs\Which\LocatorFactory\PosixLocatorFactory();
$locator = $locatorFactory->create();

// or

$locatorFactory = new \Nubs\Which\LocatorFactory\WindowsLocatorFactory();
$locator = $locatorFactory->create();

Finally, if you want full control over the paths that are searched, you can use specify exactly which paths to use:

$paths = ['/opt/special/bin', '/usr/local/bin', '/usr/bin', '/bin'];
$pathBuilder = new \Nubs\Which\PathBuilder\PosixPathBuilder($paths);
$locator = new \Nubs\Which\Locator($pathBuilder);

// or

$paths = ['C:\\Windows\\System32', 'C:\\Windows'];
$pathExtensions = ['.exe', '.com'];
$pathBuilder = new \Nubs\Which\PathBuilder\WindowsPathBuilder(
    $paths,
    $pathExtensions
);
$locator = new \Nubs\Which\Locator($pathBuilder);

Locating commands

The locator can find commands based off of its configured paths and will return null if the command could not be found:

$locatorFactory = new \Nubs\Which\LocatorFactory\PlatformLocatorFactory();
$locator = $locatorFactory->create();

echo $locator->locate('php');
// /usr/bin/php

var_dump($locator->locate('asdf'));
// NULL

It can also be given an absolute or a relative path, in which case the configured paths are ignored and pathing is done based off the current directory:

$locatorFactory = new \Nubs\Which\LocatorFactory\PlatformLocatorFactory();
$locator = $locatorFactory->create();

echo $locator->locate('/opt/php/bin/php');
// /opt/php/bin/php

chdir('/opt/php');

echo $locator->locate('bin/php');
// /opt/php/bin/php

Finally, an additional locateAll method is included. If a command exists at multiple places on the PATH, this will return all of them. It operates under all the rules as the standard locate method.

$locatorFactory = new \Nubs\Which\LocatorFactory\PlatformLocatorFactory();
$locator = $locatorFactory->create();

var_dump($locator->locateAll('php'));
// array(2) {
//   [0] =>
//   string(12) "/usr/bin/php"
//   [1] =>
//   string(16) "/opt/php/bin/php"
// }

var_dump($locator->locate('asdf'));
// array(0) {
// }

var_dump($locator->locateAll('/opt/php/bin/php'));
// array(1) {
//   [0] =>
//   string(16) "/opt/php/bin/php"
// }

chdir('/opt/php');

var_dump($locator->locateAll('bin/php'));
// array(1) {
//   [0] =>
//   string(16) "/opt/php/bin/php"
// }

CLI Interface

There is also a CLI interface for both POSIX systems and Windows that imitates the standard which command. It is available as nubs/which-cli.

Why?

I created which in order to fill a hole I came across: Detecting whether a user has a certain command installed. Primarily this was for sensible, a library that picks the user's preferred editor/browser/pager and falls back to a sensible default if no preference is specified. which provides the ability for sensible to decide whether the different command choices exist. Read more about it on my blog.

Similar Projects

I am also aware of a node.js library with a similar role: node-which.

License

which is licensed under the MIT license. See LICENSE for the full license text.