A PHP library for locating commands in a PATH.
This library requires PHP 5.6, or newer.
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
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
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);
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"
// }
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
.
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.
I am also aware of a node.js library with a similar role: node-which.
which is licensed under the MIT license. See LICENSE for the full license text.