public static function read($name, $key, array $options = []) {
		$options += ['conditions' => null, 'strategies' => true, 'write' => null];

		if (is_callable($options['conditions']) && !$options['conditions']()) {
			return false;
		}
		try {
			$adapter = static::adapter($name);
		} catch (ConfigException $e) {
			return false;
		}
		$key = static::key($key);

		if ($isMulti = is_array($key)) {
			$keys = $key;
		} else {
			$keys = [$key];
		}
		$params = compact('keys');

		$results = Filters::run(get_called_class(), __FUNCTION__, $params, function($params) use ($adapter) {
			return $adapter->read($params['keys']);
		});

		if ($write = $options['write']) {
			$isEvaluated = false;

			foreach ($keys as $key) {
				if (isset($results[$key])) {
					continue;
				}
				if (!$isEvaluated) {
					$write = is_callable($write) ? $write() : $write;
					$expiry = key($write);
					$value = current($write);
					$value = is_callable($value) ? $value() : $value;

					$isEvaluated = true;
				}
				if (!static::write($name, $key, $value, $expiry)) {
					return false;
				}
				$results[$key] = static::applyStrategies('write', $name, $value, [
					'key' => $key, 'mode' => 'LIFO', 'class' => __CLASS__
				]);
			}
		}

		if ($options['strategies']) {
			foreach ($results as $key => &$result) {
				$result = static::applyStrategies(__FUNCTION__, $name, $result, [
					'key' => $key, 'mode' => 'LIFO', 'class' => __CLASS__
				]);
			}
		}
		return $isMulti ? $results : ($results ? reset($results) : null);
	}
public static function read($name, $key, array $options = []) {
		$options += ['conditions' => null, 'strategies' => true, 'write' => null];

		if (is_callable($options['conditions']) && !$options['conditions']()) {
			return false;
		}
		try {
			$adapter = static::adapter($name);
		} catch (ConfigException $e) {
			return false;
		}
		$key = static::key($key);

		if ($isMulti = is_array($key)) {
			$keys = $key;
		} else {
			$keys = [$key];
		}
		$params = compact('keys');

		$results = Filters::run(get_called_class(), __FUNCTION__, $params, function($params) use ($adapter) {
			return $adapter->read($params['keys']);
		});

		if ($write = $options['write']) {
			$isEvaluated = false;

			foreach ($keys as $key) {
				if (isset($results[$key])) {
					continue;
				}
				if (!$isEvaluated) {
					$write = is_callable($write) ? $write() : $write;
					$expiry = key($write);
					$value = current($write);
					$value = is_callable($value) ? $value() : $value;

					$isEvaluated = true;
				}
				if (!static::write($name, $key, $value, $expiry)) {
					return false;
				}
				$results[$key] = static::applyStrategies('write', $name, $value, [
					'key' => $key, 'mode' => 'LIFO', 'class' => __CLASS__
				]);
			}
		}

		if ($options['strategies']) {
			foreach ($results as $key => &$result) {
				$result = static::applyStrategies(__FUNCTION__, $name, $result, [
					'key' => $key, 'mode' => 'LIFO', 'class' => __CLASS__
				]);
			}
		}
		return $isMulti ? $results : ($results ? reset($results) : null);
	}
public static function read ( $ name , $ key , array $ options = [ ] ) { $ options += [ 'conditions' => null , 'strategies' => true , 'write' => null ] ; if ( is_callable ( $ options [ 'conditions' ] ) && ! $ options [ 'conditions' ] ( ) ) { return false ; } try { $ adapter = static :: adapter ( $ name ) ; } catch ( ConfigException $ e ) { return false ; } $ key = static :: key ( $ key ) ; if ( $ isMulti = is_array ( $ key ) ) { $ keys = $ key ; } else { $ keys = [ $ key ] ; } $ params = compact ( 'keys' ) ; $ results = Filters :: run ( get_called_class ( ) , __FUNCTION__ , $ params , function ( $ params ) use ( $ adapter ) { return $ adapter -> read ( $ params [ 'keys' ] ) ; } ) ; if ( $ write = $ options [ 'write' ] ) { $ isEvaluated = false ; foreach ( $ keys as $ key ) { if ( isset ( $ results [ $ key ] ) ) { continue ; } if ( ! $ isEvaluated ) { $ write = is_callable ( $ write ) ? $ write ( ) : $ write ; $ expiry = key ( $ write ) ; $ value = current ( $ write ) ; $ value = is_callable ( $ value ) ? $ value ( ) : $ value ; $ isEvaluated = true ; } if ( ! static :: write ( $ name , $ key , $ value , $ expiry ) ) { return false ; } $ results [ $ key ] = static :: applyStrategies ( 'write' , $ name , $ value , [ 'key' => $ key , 'mode' => 'LIFO' , 'class' => __CLASS__ ] ) ; } } if ( $ options [ 'strategies' ] ) { foreach ( $ results as $ key => & $ result ) { $ result = static :: applyStrategies ( __FUNCTION__ , $ name , $ result , [ 'key' => $ key , 'mode' => 'LIFO' , 'class' => __CLASS__ ] ) ; } } return $ isMulti ? $ results : ( $ results ? reset ( $ results ) : null ) ; }
Reads from the specified cache configuration.

Can handle single- and multi-key reads.

Read-through caching can be used by passing expiry and the to-be-cached value
in the `write` option. Following three ways to achieve this.
```
Cache::read('default', 'foo', [
'write' => ['+5 days' => 'bar']
]); // returns `'bar'`

Cache::read('default', 'foo', [
'write' => ['+5 days' => function() { return 'bar'; }]
]);

Cache::read('default', 'foo', [
'write' => function() { return ['+5 days' => 'bar']; }
]);
```

@param string $name Configuration to be used for reading.
@param mixed $key Key to uniquely identify the cache entry or an array of keys
for multikey-reads.
@param array $options Options for the method and strategies.
- `'write'`: Allows for read-through caching see description for usage.
- `'strategies'` _boolean_: Indicates if strategies should be used,
defaults to `true`.
- `'conditions'` _mixed_: A function or item that must return or
evaluate to `true` in order to continue write operation.
@return mixed For single-key reads will return the result if the cache
key has been found otherwise returns `null`. When reading
multiple keys a results array is returned mapping keys to
retrieved values. Keys where the value couldn't successfully
been read will not be contained in the results array.
@filter
Reads from the specified cache configuration .