<code>private $config = array( 'mimes' => array(), //允许上传的文件MiMe类型 'maxSize' => 0, //上传的文件大小限制 (0-不做限制) 'exts' => array(), //允许上传的文件后缀 'autoSub' => true, //自动子目录保存文件 'subName' => array('date', 'Y-m-d'), //子目录创建方式,[0]-函数名,[1]-参数,多个参数使用数组 'rootPath' => './Uploads/', //保存根路径 'savePath' => '', //保存路径 'saveName' => array('uniqid', ''), //上传文件命名规则,[0]-函数名,[1]-参数,多个参数使用数组 'saveExt' => '', //文件保存后缀,空则使用原后缀 'replace' => false, //存在同名是否覆盖 'hash' => true, //是否生成hash编码 'callback' => false, //检测文件是否存在回调,如果存在返回文件信息数组 'driver' => '', // 文件上传驱动 'driverConfig' => array(), // 上传驱动配置 ); public function __construct($config = array(), $driver = '', $driverConfig = null){ /* 获取配置 */ $this->config = array_merge($this->config, $config); }</code>
这个类在初始化时候把所有的配置都放在了这个数组属性中,可是我在看官方文档的时候却可以这样以调用类属性的方式来设置这些配置,如:
<code>$upload = new \Think\Upload();// 实例化上传类 $upload->maxSize = 3145728 ;// 设置附件上传大小 </code>
看到这里我就不明白了,这个maxSize只是config数组属性里的一个下标按理说应该$upload->config['maxSize']这样赋值啊,怎么可以直接以属性的方式赋值呢??
<code>private $config = array( 'mimes' => array(), //允许上传的文件MiMe类型 'maxSize' => 0, //上传的文件大小限制 (0-不做限制) 'exts' => array(), //允许上传的文件后缀 'autoSub' => true, //自动子目录保存文件 'subName' => array('date', 'Y-m-d'), //子目录创建方式,[0]-函数名,[1]-参数,多个参数使用数组 'rootPath' => './Uploads/', //保存根路径 'savePath' => '', //保存路径 'saveName' => array('uniqid', ''), //上传文件命名规则,[0]-函数名,[1]-参数,多个参数使用数组 'saveExt' => '', //文件保存后缀,空则使用原后缀 'replace' => false, //存在同名是否覆盖 'hash' => true, //是否生成hash编码 'callback' => false, //检测文件是否存在回调,如果存在返回文件信息数组 'driver' => '', // 文件上传驱动 'driverConfig' => array(), // 上传驱动配置 ); public function __construct($config = array(), $driver = '', $driverConfig = null){ /* 获取配置 */ $this->config = array_merge($this->config, $config); }</code>
这个类在初始化时候把所有的配置都放在了这个数组属性中,可是我在看官方文档的时候却可以这样以调用类属性的方式来设置这些配置,如:
<code>$upload = new \Think\Upload();// 实例化上传类 $upload->maxSize = 3145728 ;// 设置附件上传大小 </code>
看到这里我就不明白了,这个maxSize只是config数组属性里的一个下标按理说应该$upload->config['maxSize']这样赋值啊,怎么可以直接以属性的方式赋值呢??
魔术方法 __set(),在给不可访问属性赋值时,__set() 会被调用。
你看看类里面的__set()方法…
<code>/** * 使用 $this->name 获取配置 * @param string $name 配置名称 * @return multitype 配置值 */ public function __get($name) { return $this->config[$name]; } public function __set($name, $value) { if (isset($this->config[$name])) { $this->config[$name] = $value; if ('driverConfig' == $name) { //改变驱动配置后重置上传驱动 //注意:必须选改变驱动然后再改变驱动配置 $this->setDriver(); } } }</code>
看,这俩魔术方法重新实现类类属性的访问与操作;
这样一来看似类属性$config是个数组,实际却可以通过这俩魔术方法数组类型的类属性$config内每一个元素当作以各自的KEY为类属性名,VALUE为类属性值直接操作了。
如果不重写那俩魔术方法,换种写法可能一目了然了:
<code>/** * 默认上传配置 * @var array */ $mimes = array(); //允许上传的文件MiMe类型 $maxSize = 0; //上传的文件大小限制 (0-不做限制) $exts = array(); //允许上传的文件后缀 $autoSub = true; //自动子目录保存文件 $subName = array('date', 'Y-m-d'); //子目录创建方式,[0]-函数名,[1]-参数,多个参数使用数组 $rootPath = './Uploads/'; //保存根路径 $savePath = ''; //保存路径 $saveName = array('uniqid', ''); //上传文件命名规则,[0]-函数名,[1]-参数,多个参数使用数组 $saveExt = ''; //文件保存后缀,空则使用原后缀 $replace = false; //存在同名是否覆盖 $hash = true; //是否生成hash编码 $callback = false; //检测文件是否存在回调,如果存在返回文件信息数组 $driver = ''; // 文件上传驱动 $driverConfig = array(); // 上传驱动配置</code>
只不过这里还涉及到一个$driverConfig类属性的特殊性,这个另说了。因该不在你的问题讨论范围。