单例模式.

@param $option

@return Docker
359270
public static function docker(array $option)
    {
        // 参数可以为空，默认连接到 127.0.0.1:2375

        if (!(self::$docker instanceof self)) {
            self::$docker = new self($option, new Curl());
        }

        return self::$docker;
    }
76402
public static function setProvider($option = '')
    {
        // Set default provider.
        if (empty($option) || ($option != 'adaptive_payments') || ($option == 'express_checkout')) {
            self::$provider = new ExpressCheckout();
        } else {
            self::$provider = new AdaptivePayments();
        }

        return self::getProvider();
    }
311994
public function addOption(Option $option, $group = null)
    {
        $options = [$option];

        if ($group === null) {
            $group = $this->currentGroup;
        }

        $this->setOptions($options, $group);

        return $this;
    }
196839
public function uploadByPath($path, $type = '', $option = [])
    {
        // 文件是否存在
        if (empty($path) || ! is_file($path)) {
            return Format::formatResult(0, '文件不存在');
        }
        
        // 没有指定后缀
        if (! isset($option['ext'])) {
            $option['ext'] = FileInfo::getFileExt($path);
        }
        
        // 类型识别出错
        if (empty($option['ext']) && isset($option['mime'])) {
            $option['ext'] = FileInfo::mimeToExt($option['mime']);
        }
        
        // 上传文件类型
        $type = $this->getFileType($option['ext'], $type);
        if (empty($type)) {
            return Format::formatResult(0, '不合法的文件类型');
        }
        
        // 处理图片
        $type == 'image' && $this->processImage($path, $option);
        
        // 没有文件Md5
        if (! isset($option['hash'])) {
            $option['hash'] = md5_file($path);
        }
        
        // 是否上传过
        if ($this->onCheck && is_callable($this->onCheck)) {
            $url = call_user_func($this->onCheck, [
                'hash' => $option['hash'],
                'type' => $type,
                'ext' => $option['ext'],
                'path' => $path
            ]);
            
            // 文件存在
            if (! empty($url)) {
                return Format::formatResult(1, '上传成功', [
                    'url' => $url,
                    'hash' => $option['hash'],
                    'type' => $type,
                    'ext' => $option['ext'],
                    'path' => $this->option('root') . DS . $type . DS . $option['hash'] . '.' . $option['ext']
                ]);
            }
        }
        
        // 上传文件
        $target_path = $type . '/' . $option['hash'] . '.' . $option['ext'];
        $res = $this->uploadFile($path, $target_path);
        
        // 上传完成
        $this->onDone && is_callable($this->onDone) && call_user_func($this->onDone, [
            'hash' => $option['hash'],
            'type' => $type,
            'ext' => $option['ext'],
            'path' => $path
        ]);
        
        // 上传失败
        if ($res['code'] != 1) {
            $this->onError && is_callable($this->onError) && call_user_func($this->onError, [
                'hash' => $option['hash'],
                'type' => $type,
                'ext' => $option['ext'],
                'path' => $path
            ]);
            return $res;
        }
        
        // 上传成功
        $this->onSuccess && is_callable($this->onSuccess) && call_user_func($this->onSuccess, [
            'hash' => $option['hash'],
            'type' => $type,
            'ext' => $option['ext'],
            'path' => $path,
            'url' => $res['data']
        ]);
        
        // 返回结果
        return Format::formatResult(1, '上传成功', [
            'url' => $res['data'],
            'hash' => $option['hash'],
            'type' => $type,
            'ext' => $option['ext'],
            'path' => $this->option('root') . DS . $type . DS . $option['hash'] . '.' . $option['ext']
        ]);
    }
543294
public static function create($option = array(), $alias = null)
	{
		if('' === static::$driverName)
		{
			static::init();
		}
		if(isset(self::$instances[static::$driverName][$alias]))
		{
			return self::$instances[static::$driverName][$alias];
		}
		else
		{
			$object = static::__createBefore($option, $alias);
			if(null === $object)
			{
				$className = static::$driverName . $option['type'];
				$ref = new ReflectionClass($className);
				$object = $ref->newInstance(isset($option['option']) ? $option['option'] : array());
			}
			static::__createAfter($option, $alias, $object);
			if(null !== $alias)
			{
				self::$instances[static::$driverName][$alias] = $object;
			}
			return $object;
		}
	}
323790
public function options($option, $value=null) 
    {
        if (is_array($option)) {
            foreach ($option as $k=>$v) {
                $this->options($k, $v);
            }
        } else {
            // 兼容转换
            if ($option === 'cookies') {
                $option = 'cookie';
            } elseif ($option === 'headers') {
                $option = 'header';
            }
            
            if (array_key_exists($option, $this->def)) {
                if (method_exists($this, $option)) {
                    $this->$option($value);
                }
            } else {
                $this->options[strtoupper($option)] = $value;
            }
        }
        return $this;
    }
591511
public static function fromOption($option)
    {
        $message = sprintf(
            'Could not add invalid Option of type "%1$s" to option repository.',
            is_object($option)
                ? get_class($option)
                : gettype($option)
        );

        return new static($message);
    }
1036907
public function crop( array $options = [] ) : Image
	{
		$this->cropOption = empty( $options ) ? $this->cropOption : $options;
		// 裁剪
		$img = ImageManage::make( $this->originFileInfo['path'] );
		foreach( $this->cropOption as $suffix => $option ){
			list( $width, $height ) = $option;
			$img->resize( $width, $height, function( $constraint ){
				$constraint->aspectRatio();
			} );
			// 水印 todo 位置设置 目前是左上角
			if( $this->watermark === true ){
				$img->insert( 'Public/watermark.png' );
			}
			$target_file_name = "{$this->targetFolder}/{$this->fileName}_{$suffix}.{$this->ext}";

			// 生成略显图
			$img->save( $target_file_name );

			// 记录裁剪图片的信息
			$this->cropImages[$suffix] = $this->getImageInfoFormatData( $target_file_name );
		}
		return $this;
	}
1284123
public function get($option)
    {
        return (isset($this->options[$option]) ? $this->options[$option] : null);
    }
644281
public function filterTask(Option $option)
    {
        $root = $this->getRootAppDir($option);
        $current = $this->getCurrentAppDir($option);
        $prefix = trim(preg_replace('/^' . preg_quote($root, '/') . '/', '', $current), DS);

        $name = $option->getArg(0);
        if (! preg_match('/Filter$/', $name)) $name .= 'Filter';

        $option->set('skeleton', 'filter');
        $option->setArg(0, $prefix . DS . 'Filter' . DS . $name);
        $this->task('add:class', $option);
    }
1209800
public function get(string $option)
    {
        if (!isset($this->options[$option])) {
            throw new \InvalidArgumentException(sprintf('Option "%s" does not exists.', $option));
        }

        return $this->options[$option];
    }
233299
private function buildOption(Option $option): string
    {

        // Select unselected options when the options value is in selects value array
        if (!$option->getSelected() && in_array($option->getValue(), $this->value)) {
            $option->isSelected();
        }

        return $option->build();
    }
810636
protected function setOption(int $option): self
    {
        $this->setOptions($this->getOptions() | $option);

        return $this;
    }
834118
public function getOption($option)
    {
        if (!empty($this->options->{$option})) {
            return $this->options->{$option};
        }

        return false;
    }
362620
public function reqQuery(array $options = [])
    {
        // 允许传索引数组表示常见的only选项
        if (isset($options[0])) {
            $options['only'] = $options;
        }

        $req = $this->request->getData();
        if (isset($options['only'])) {
            $req = array_intersect_key($req, array_flip((array) $options['only']));
        }
        if (isset($options['except'])) {
            $req = array_diff_key($req, array_flip((array) $options['except']));
        }

        $isPresent = wei()->isPresent;
        foreach ($req as $name => $value) {
            if (!$isPresent($value)) {
                continue;
            }

            if (is_array($value)) {
                foreach ($value as $subName => $subValue) {
                    if (!$isPresent($subValue)) {
                        continue;
                    }

                    $this->processRelationQuery($name, $subName, $subValue);
                }
            } else {
                $this->processColumnQuery($name, $value);
            }
        }
        return $this;
    }
733162
public function select($options=array()) {
        $pk   =  $this->getPk();
        if(is_string($options) || is_numeric($options)) {
            // 根据主键查询
            if(strpos($options,',')) {
                $where[$pk]     =  array('IN',$options);
            }else{
                $where[$pk]     =  $options;
            }
            $options            =  array();
            $options['where']   =  $where;
        }elseif (is_array($options) && (count($options) > 0) && is_array($pk)) {
            // 根据复合主键查询
            $count = 0;
            foreach (array_keys($options) as $key) {
                if (is_int($key)) $count++; 
            } 
            if ($count == count($pk)) {
                $i = 0;
                foreach ($pk as $field) {
                    $where[$field] = $options[$i];
                    unset($options[$i++]);
                }
                $options['where']  =  $where;
            } else {
                return false;
            }
        } elseif(false === $options){ // 用于子查询 不查询只返回SQL
            $options            =  array();
            // 分析表达式
            $options            =  $this->_parseOptions($options);
            return  '( '.$this->fetchSql(true)->select($options).' )';
        }
        // 分析表达式
        $options    =  $this->_parseOptions($options);
        // 判断查询缓存
        if(isset($options['cache'])){
            $cache  =   $options['cache'];
            $key    =   is_string($cache['key'])?$cache['key']:md5(serialize($options));
            $data   =   S($key,'',$cache);
            if(false !== $data){
                return $data;
            }
        }        
        $resultSet  = $this->db->select($options);
        if(false === $resultSet) {
            return false;
        }
        if(empty($resultSet)) { // 查询结果为空
            return null;
        }

        if(is_string($resultSet)){
            return $resultSet;
        }

        $resultSet  =   array_map(array($this,'_read_data'),$resultSet);
        $this->_after_select($resultSet,$options);
        if(isset($options['index'])){ // 对数据集进行索引
            $index  =   explode(',',$options['index']);
            foreach ($resultSet as $result){
                $_key   =  $result[$index[0]];
                if(isset($index[1]) && isset($result[$index[1]])){
                    $cols[$_key] =  $result[$index[1]];
                }else{
                    $cols[$_key] =  $result;
                }
            }
            $resultSet  =   $cols;
        }
        if(isset($cache)){
            S($key,$resultSet,$cache);
        }
        return $resultSet;
    }
1075726
public static function merge(...$options) {
            $o = [];

            foreach ($options as $opt) {
                if ($opt instanceof Options) {
                    $o = array_merge($o, $opt->toArray());
                } elseif (is_array($opt)) {
                    $o = array_merge($o, $opt);
                }
            }

            return new self(Util::trimNulls($o));
        }