/** * 写入文件 * @param string $path 路径 * @param mixed $data 写入的值 * @param boolean $overwrite 是否覆盖已有文件 * @return boolean */ public static function write($path, $data, $overwrite = true) { $path = str_replace('\\', '/', $path); $pos = strrpos($path, '/'); $file_name = ""; $file_dir = ""; if ($pos === false) { $file_name = $path; } else { $file_dir = substr($path, 0, $pos + 1); $file_name = substr($path, $pos + 1); } $tmp_file = tempnam($file_dir, 'tsb_sfw'); Verify::isTrue(false !== file_put_contents($tmp_file, $data), "write to file: {$tmp_file} failed"); if ($overwrite) { @unlink($path); //删除原始文件 } if (!@rename($tmp_file, $path)) { @unlink($tmp_file); //删除原始文件 Verify::e("write to file: {$tmp_file} failed"); return false; } return true; }
/** * 根据id得到对象实例 * //TODO 单实例间互相引用会是问题 * @param string $id * @param array $properties 类属性, 覆盖配置文件中的属性 * @param callable $injector fun($src), 获取注入值的方法 * @param callable $init fun($inst, &$got) 初始化实例, 在创建后, 调用构造函数前 * @param array $construct_args 构造函数的参数 * @return object */ public function create($id, $construct_args = null, $properties = null, $injector = null, $init = null) { if ($properties === null) { $properties = array(); } if ($construct_args === null) { $construct_args = array(); } $ins = null; $is_singleton = false; $class_name = $this->getClassName($id); if (isset($this->conf[$id])) { $class = $this->conf[$id]; $class_refl = new \ReflectionClass($class_name); // 如果是单例 // 带构造参数的类不支持单例 if (count($properties) === 0 && count($construct_args) === 0 && isset($class['singleton']) && $class['singleton']) { $is_singleton = true; if (isset($this->singletons[$id])) { $ins = $this->singletons[$id]; Logger::info("get {$id}[{$class_name}] as singleton"); return $ins; } } if (isset($class['properties'])) { $properties = array_merge($class['properties'], $properties); } if (isset($class['pass_by_construct']) && $class['pass_by_construct']) { //属性在构造时传入 Verify::isTrue(count($construct_args) === 0, "{$class_name} pass_by_construct"); //构造时传输属性, 所以不能再传入其他构造参数 //组合构造参数 $construct_args = $this->buildConstructArgs($class_refl, $properties); $properties = array(); } } else { $class_refl = new \ReflectionClass($class_name); } if (!$is_singleton) { if (array_search($id, $this->create_stack) !== false) { $tmp = $this->create_stack; Verify::e("create {$id} failed, cyclic dependencies can only used with singleton. cyclic:" . print_r($tmp, true)); } $this->create_stack[] = $id; } try { if (isset($class['pass_by_construct']) && $class['pass_by_construct']) { $ins = $class_refl->newInstanceArgs($construct_args); $meta = $this->getMetaInfo($class_refl); if ($is_singleton) { $this->singletons[$id] = $ins; } $this->injectDependent($class_refl, $ins, $meta, $properties, $injector); } else { $nti = new NewThenInit($class_refl); $ins = $nti->getObject(); $meta = $this->getMetaInfo($class_refl); if ($is_singleton) { $this->singletons[$id] = $ins; } $this->injectDependent($class_refl, $ins, $meta, $properties, $injector); if ($init !== null) { $init($ins); } $nti->initArgs($construct_args); } } catch (\Exception $e) { array_pop($this->create_stack); throw $e; } array_pop($this->create_stack); Logger::info("create {$id}[{$class_name}] ok"); return $ins; }