├── .gitignore
├── Andromeda
├── Andromeda.php
├── App.php
├── Di.php
├── Di
│ ├── FactoryDefault.php
│ ├── Injectable.php
│ └── InjectionAwareInterface.php
├── DiInterface.php
├── Exception.php
├── Mvc
│ ├── Controller.php
│ ├── SingletonWriter.php
│ └── Writer.php
├── README.md
├── Request.php
├── Response.php
└── core
│ ├── Controller.class.php
│ ├── Loader.class.php
│ ├── Log.class.php
│ ├── Model.class.php
│ ├── Mysql.class.php
│ ├── TemplateEngine
│ ├── Compile.class.php
│ ├── Template.class.php
│ ├── cache
│ │ └── aa08769cdcb26674c6706093503ff0a3.php
│ ├── template
│ │ └── member.tpl
│ └── test.php
│ ├── Util.class.php
│ ├── View.class.php
│ └── log
│ └── driver
│ └── File.php
├── App
├── Config
│ ├── config.php
│ ├── loader.php
│ ├── router.php
│ └── service.php
├── Controllers
│ └── Home
│ │ ├── BaseController.class.php
│ │ └── IndexController.class.php
├── Models
│ └── UserModel.class.php
└── Views
│ ├── admin
│ └── index.html
│ └── home
│ ├── getUser.html
│ ├── getUserById.html
│ ├── index.html
│ └── var.html
├── Doc
└── 实现action的参数获取.md
├── LICENSE
├── Public
└── README.md
├── README.md
├── composer.json
├── composer.lock
├── index.php
└── test
├── di
├── Di.php
└── test.php
└── namespace
├── NameSpaceClass.php
├── UseNameSpace.php
└── test.php
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Phalcon template
3 | /cache/
4 | /config/development/
5 |
6 | .idea/
7 | App/Log/*
8 | vendor/
--------------------------------------------------------------------------------
/Andromeda/Andromeda.php:
--------------------------------------------------------------------------------
1 | setDI($di);
132 |
133 |
134 | $num = count(self::$s_arr_query);
135 | //echo 'oldNum='.$num;
136 | //取出前3个参数后面的参数组
137 | self::$s_arr_query = array_slice(self::$s_arr_query, 3, $num - 3);
138 | //$controller->$action_name(self::$s_arr_query);//
139 |
140 | $num = count(self::$s_arr_query);
141 | //echo 'newNum='.$num;
142 | /*$str_temp = '';
143 | foreach (self::$s_arr_query as $key => $value) {
144 | $str_temp = $str_temp . '"'.self::$s_arr_query[$key] . '",';
145 | }
146 |
147 | Log::write($str_temp);
148 | $str_temp = rtrim($str_temp, ',');
149 |
150 | $fun = '$controller->$action_name(' . $str_temp . ');';
151 | Log::write($fun);
152 | //$fun='$controller->$action_name(self::$s_arr_query);';
153 | //echo $fun;
154 | eval($fun);*/
155 |
156 | //解析有几个参数就组几个参数
157 | //$param=self::getFucntionParameter('$controller->$action_name',self::$s_arr_query);
158 | //Log::write(json_encode(self::$s_arr_query));
159 | //call_user_func(array($controller_name,$action_name),['p1'=>"2222"],['p2'=>"11111"]);
160 | $reflect = new \ReflectionMethod($controller_name, $action_name);
161 | //处理一下参数
162 | $params=self::bindParams($reflect,self::$s_arr_query);
163 |
164 | $reflect->invokeArgs($controller, $params);
165 |
166 | }
167 |
168 | /**
169 | * 绑定参数
170 | * @param \ReflectionMethod| \ReflectionFunction $reflect
171 | * @param array $vars
172 | * @return array 参数
173 | */
174 | private static function bindParams($reflect, $vars = [])
175 | {
176 | // 处理post参数
177 | $postParam=Request::instance()->param();
178 | Log::write("post:".json_encode($postParam));
179 |
180 | //处理get参数
181 | $args = [];
182 | //反射的方法存在参数
183 | if ($reflect->getNumberOfParameters() > 0) {
184 | //判断数组类型,数字数组时按顺序绑定参数
185 | $params = $reflect->getParameters();
186 | foreach ($params as $param) {
187 | $args[] = self::getParamValue($param, $postParam);
188 | }
189 | }
190 |
191 | return $args;
192 | }
193 |
194 |
195 | /**
196 | * 设置错误与异常处理
197 | */
198 | private static function error()
199 | {
200 | error_reporting(E_ALL);
201 | set_error_handler([__CLASS__, 'appError']);
202 | set_exception_handler([__CLASS__, 'appException']);
203 | register_shutdown_function([__CLASS__, 'appShutdown']);
204 | }
205 |
206 | public static function appError()
207 | {
208 | echo '-------error--------';
209 | $errorArr = error_get_last();
210 | echo $errorArr['type'] . "
";
211 | echo $errorArr['message'] . "
";
212 | }
213 |
214 | /**
215 | * 设置异常处理
216 | * @param Throwable $exception
217 | */
218 | public static function appException($exception)
219 | {
220 | echo '
';
221 | echo "----------exception--------
";
222 | //todo 判断是不是人为抛出的异常,如果是则正常抛,否则都归为系统异常,不向用户暴露错误原因,开启debug模式可以出异常
223 |
224 |
225 | echo "code=" . $exception->getCode() . "
";
226 | echo "message=" . $exception->getMessage() . "
";
227 | echo "file=" . $exception->getFile() . "
";
228 | echo "line=" . $exception->getLine(), "
";
229 | echo "trace=" . $exception->getTraceAsString() . "
";
230 | }
231 |
232 | /**
233 | * php脚本无论正常执行完毕或者异常结束都会调用
234 | */
235 | public static function appShutdown()
236 | {
237 | //echo '****shutdown****';
238 | }
239 |
240 | /**
241 | * 获取参数值,并判断是否必要参数没填
242 | * @param \ReflectionParameter $param
243 | * @param $vars
244 | * @return array
245 | */
246 | private static function getParamValue($param, $vars)
247 | { //参数名字
248 | $name = $param->getName();
249 | //参数的类
250 | $class = $param->getClass();
251 |
252 | if ($class) {
253 | //todo:参数是个类的情况
254 | return null;
255 | } else {
256 | if (isset($vars[$name])) {
257 | $result = $vars[$name];
258 | } elseif ($param->isDefaultValueAvailable()) {
259 | $result = $param->getDefaultValue();
260 | } else {
261 | throw new \InvalidArgumentException("method param is missing:" . $name);
262 | }
263 | }
264 |
265 | return $result;
266 |
267 |
268 | }
269 |
270 | }
271 |
272 |
273 |
274 |
275 |
276 |
--------------------------------------------------------------------------------
/Andromeda/App.php:
--------------------------------------------------------------------------------
1 | _sharedInstances[$name] = $definition;
29 | }
30 |
31 |
32 | /**
33 | * 获取共享服务实例
34 | * @param $name :服务名
35 | * @param $param_arr :配置
36 | * @return mixed
37 | * @throws \Exception
38 | */
39 | public function get($name, $param_arr = null)
40 | {
41 |
42 | $instance = null;
43 |
44 | if (isset($this->_sharedInstances[$name])) {
45 | $definition = $this->_sharedInstances[$name];
46 | } else {
47 | //去独立服务里面去找
48 | if(isset($this->_services['name'])){
49 | //找到,new一个新的实例
50 | $instance=new $name;
51 | return $instance;
52 | }else{
53 | //没找到
54 | throw new \Exception("Service '" . $name . "' wasn't found in the dependency injection container");
55 | }
56 |
57 |
58 |
59 | }
60 |
61 | if (!is_object($definition)) {
62 | throw new \Exception("Service $name wasn't a object");
63 | }
64 |
65 | if ($param_arr == null) {
66 | $instance = call_user_func($definition);
67 | } else {
68 | $instance = call_user_func_array($definition, $param_arr);
69 | }
70 | return $instance;
71 |
72 | }
73 |
74 | /*
75 | * 设置独立服务,每次获取的时候会实例化
76 | * @param $name
77 | * @param $definition
78 | */
79 | public function set($name, $definition)
80 | {
81 | $this->_sharedInstances[$name] = $definition;
82 | $this->_services[$name]=$definition;
83 | }
84 |
85 | public function __construct()
86 | {
87 | return $this;
88 | }
89 | }
--------------------------------------------------------------------------------
/Andromeda/Di/Injectable.php:
--------------------------------------------------------------------------------
1 | _dependencyInjector=$dependenceInjector;
28 | }
29 |
30 | public function getDI()
31 | {
32 | return $this->_dependencyInjector;
33 | }
34 |
35 |
36 | public function setEventsManager($eventsManager){
37 | $this->_eventsManager=$eventsManager;
38 | }
39 |
40 | public function getEventsManager(){
41 | return $this->_eventsManager;
42 | }
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | }
--------------------------------------------------------------------------------
/Andromeda/Di/InjectionAwareInterface.php:
--------------------------------------------------------------------------------
1 | data[$label] = $data;
38 | }
39 |
40 | /**
41 | * 获取异常额外Debug数据
42 | * 主要用于输出到异常页面便于调试
43 | * @return array 由setData设置的Debug数据
44 | */
45 | final public function getData()
46 | {
47 | return $this->data;
48 | }
49 | }
--------------------------------------------------------------------------------
/Andromeda/Mvc/Controller.php:
--------------------------------------------------------------------------------
1 | _dependencyInjector->_sharedInstances[$name])) {
25 | $definition = $this->_dependencyInjector->_sharedInstances[$name];
26 | } else {
27 | throw new \Exception("Service '" . $name . "' wasn't found in the dependency injection container");
28 | }
29 |
30 | if (is_object($definition)) {
31 | $instance = call_user_func($definition);
32 | }
33 | return $instance;
34 |
35 | }
36 |
37 |
38 | public function __construct($di=null)
39 | {
40 | //$this->loader=new \Loader();
41 | $this->view=new \View();
42 | $this->_dependencyInjector=$di;
43 | }
44 |
45 |
46 |
47 |
48 | public function redirect($url,$message,$wait=0){
49 | if($wait=0){
50 | header("Location:$url");
51 |
52 | }else{
53 | include CURR_VIEW_PATH."message.html";
54 |
55 | }
56 | exit;
57 |
58 | }
59 |
60 | protected function assign($name,$value='') {
61 | $this->view->assign($name,$value);
62 | return $this;
63 | }
64 |
65 | protected function display($template){
66 | $this->view->display(CURR_VIEW_PATH.$template);
67 |
68 | }
69 |
70 | /**
71 | * 浏览器友好的变量输出
72 | * @param mixed $var 变量
73 | * @param boolean $echo 是否输出 默认为True 如果为false 则返回输出字符串
74 | * @param string $label 标签 默认为空
75 | * @param boolean $strict 是否严谨 默认为true
76 | * @return void|string
77 | */
78 | protected function dump($var, $echo=true, $label=null, $strict=true) {
79 | $label = ($label === null) ? '' : rtrim($label) . ' ';
80 | if (!$strict) {
81 | if (ini_get('html_errors')) {
82 | $output = print_r($var, true);
83 | $output = '
' . $label . htmlspecialchars($output, ENT_QUOTES) . '
';
84 | } else {
85 | $output = $label . print_r($var, true);
86 | }
87 | } else {
88 | ob_start();
89 | var_dump($var);
90 | $output = ob_get_clean();
91 | if (!extension_loaded('xdebug')) {
92 | $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
93 | $output = '' . $label . htmlspecialchars($output, ENT_QUOTES) . '
';
94 | }
95 | }
96 | if ($echo) {
97 | echo($output);
98 | return null;
99 | }else
100 | return $output;
101 | }
102 |
103 |
104 | }
105 |
106 |
--------------------------------------------------------------------------------
/Andromeda/Mvc/SingletonWriter.php:
--------------------------------------------------------------------------------
1 | ";
27 | }
28 |
29 | public static function getInstance($di)
30 | {
31 | if (!self::$singletonWriter) {
32 | self::$singletonWriter = new self($di);
33 | }
34 | return self::$singletonWriter;
35 | }
36 |
37 | /**
38 | * 在浏览器输出一些内容
39 | * @param $content
40 | */
41 | public function write($content)
42 | {
43 | echo "SingletonWriter write $content";
44 | }
45 |
46 | public function hello()
47 | {
48 | echo "SingletonWriter hello guys
";
49 | }
50 |
51 | public static function staticHello()
52 | {
53 | echo "SingletonWriter static hello guys
";
54 | }
55 |
56 | public function setDI($di)
57 | {
58 | // TODO: Implement setDI() method.
59 | }
60 |
61 | public function getDI()
62 | {
63 | // TODO: Implement getDI() method.
64 | }
65 | }
--------------------------------------------------------------------------------
/Andromeda/Mvc/Writer.php:
--------------------------------------------------------------------------------
1 | ";
22 | }
23 |
24 | /**
25 | * 在浏览器输出一些内容
26 | * @param $content
27 | */
28 | public function write($content){
29 | echo "write $content
";
30 | }
31 |
32 | public function hello(){
33 | echo "hello guys
";
34 | }
35 |
36 | public function setDI($di)
37 | {
38 | // TODO: Implement setDI() method.
39 | }
40 |
41 | public function getDI()
42 | {
43 | // TODO: Implement getDI() method.
44 | }
45 | }
--------------------------------------------------------------------------------
/Andromeda/README.md:
--------------------------------------------------------------------------------
1 | 框架目录
2 |
--------------------------------------------------------------------------------
/Andromeda/Request.php:
--------------------------------------------------------------------------------
1 | 'application/xml,text/xml,application/x-xml',
89 | 'json' => 'application/json,text/x-json,application/jsonrequest,text/json',
90 | 'js' => 'text/javascript,application/javascript,application/x-javascript',
91 | 'css' => 'text/css',
92 | 'rss' => 'application/rss+xml',
93 | 'yaml' => 'application/x-yaml,text/yaml',
94 | 'atom' => 'application/atom+xml',
95 | 'pdf' => 'application/pdf',
96 | 'text' => 'text/plain',
97 | 'image' => 'image/png,image/jpg,image/jpeg,image/pjpeg,image/gif,image/webp,image/*',
98 | 'csv' => 'text/csv',
99 | 'html' => 'text/html,application/xhtml+xml,*/*',
100 | ];
101 |
102 | protected $content;
103 |
104 | // 全局过滤规则
105 | protected $filter;
106 | // Hook扩展方法
107 | protected static $hook = [];
108 | // 绑定的属性
109 | protected $bind = [];
110 | // php://input
111 | protected $input;
112 | // 请求缓存
113 | protected $cache;
114 | // 缓存是否检查
115 | protected $isCheckCache;
116 |
117 | /**
118 | * 构造函数
119 | * @access protected
120 | * @param array $options 参数
121 | */
122 | protected function __construct($options = [])
123 | {
124 | foreach ($options as $name => $item) {
125 | if (property_exists($this, $name)) {
126 | $this->$name = $item;
127 | }
128 | }
129 |
130 | // 保存 php://input
131 | $this->input = file_get_contents('php://input');
132 | }
133 |
134 | public function __call($method, $args)
135 | {
136 | if (array_key_exists($method, self::$hook)) {
137 | array_unshift($args, $this);
138 | return call_user_func_array(self::$hook[$method], $args);
139 | } else {
140 | throw new Exception('method not exists:' . __CLASS__ . '->' . $method);
141 | }
142 | }
143 |
144 | /**
145 | * Hook 方法注入
146 | * @access public
147 | * @param string|array $method 方法名
148 | * @param mixed $callback callable
149 | * @return void
150 | */
151 | public static function hook($method, $callback = null)
152 | {
153 | if (is_array($method)) {
154 | self::$hook = array_merge(self::$hook, $method);
155 | } else {
156 | self::$hook[$method] = $callback;
157 | }
158 | }
159 |
160 | /**
161 | * 初始化
162 | * @access public
163 | * @param array $options 参数
164 | * @return Request
165 | */
166 | public static function instance($options = [])
167 | {
168 | if (is_null(self::$instance)) {
169 | self::$instance = new static($options);
170 | }
171 | return self::$instance;
172 | }
173 |
174 | /**
175 | * 创建一个URL请求
176 | * @access public
177 | * @param string $uri URL地址
178 | * @param string $method 请求类型
179 | * @param array $params 请求参数
180 | * @param array $cookie
181 | * @param array $files
182 | * @param array $server
183 | * @param string $content
184 | * @return \Request
185 | */
186 | public static function create($uri, $method = 'GET', $params = [], $cookie = [], $files = [], $server = [], $content = null)
187 | {
188 | $server['PATH_INFO'] = '';
189 | $server['REQUEST_METHOD'] = strtoupper($method);
190 | $info = parse_url($uri);
191 | if (isset($info['host'])) {
192 | $server['SERVER_NAME'] = $info['host'];
193 | $server['HTTP_HOST'] = $info['host'];
194 | }
195 | if (isset($info['scheme'])) {
196 | if ('https' === $info['scheme']) {
197 | $server['HTTPS'] = 'on';
198 | $server['SERVER_PORT'] = 443;
199 | } else {
200 | unset($server['HTTPS']);
201 | $server['SERVER_PORT'] = 80;
202 | }
203 | }
204 | if (isset($info['port'])) {
205 | $server['SERVER_PORT'] = $info['port'];
206 | $server['HTTP_HOST'] = $server['HTTP_HOST'] . ':' . $info['port'];
207 | }
208 | if (isset($info['user'])) {
209 | $server['PHP_AUTH_USER'] = $info['user'];
210 | }
211 | if (isset($info['pass'])) {
212 | $server['PHP_AUTH_PW'] = $info['pass'];
213 | }
214 | if (!isset($info['path'])) {
215 | $info['path'] = '/';
216 | }
217 | $options = [];
218 | $options[strtolower($method)] = $params;
219 | $queryString = '';
220 | if (isset($info['query'])) {
221 | parse_str(html_entity_decode($info['query']), $query);
222 | if (!empty($params)) {
223 | $params = array_replace($query, $params);
224 | $queryString = http_build_query($query, '', '&');
225 | } else {
226 | $params = $query;
227 | $queryString = $info['query'];
228 | }
229 | } elseif (!empty($params)) {
230 | $queryString = http_build_query($params, '', '&');
231 | }
232 | if ($queryString) {
233 | parse_str($queryString, $get);
234 | $options['get'] = isset($options['get']) ? array_merge($get, $options['get']) : $get;
235 | }
236 |
237 | $server['REQUEST_URI'] = $info['path'] . ('' !== $queryString ? '?' . $queryString : '');
238 | $server['QUERY_STRING'] = $queryString;
239 | $options['cookie'] = $cookie;
240 | $options['param'] = $params;
241 | $options['file'] = $files;
242 | $options['server'] = $server;
243 | $options['url'] = $server['REQUEST_URI'];
244 | $options['baseUrl'] = $info['path'];
245 | $options['pathinfo'] = '/' == $info['path'] ? '/' : ltrim($info['path'], '/');
246 | $options['method'] = $server['REQUEST_METHOD'];
247 | $options['domain'] = isset($info['scheme']) ? $info['scheme'] . '://' . $server['HTTP_HOST'] : '';
248 | $options['content'] = $content;
249 | self::$instance = new self($options);
250 | return self::$instance;
251 | }
252 |
253 | /**
254 | * 设置或获取当前包含协议的域名
255 | * @access public
256 | * @param string $domain 域名
257 | * @return string
258 | */
259 | public function domain($domain = null)
260 | {
261 | if (!is_null($domain)) {
262 | $this->domain = $domain;
263 | return $this;
264 | } elseif (!$this->domain) {
265 | $this->domain = $this->scheme() . '://' . $this->host();
266 | }
267 | return $this->domain;
268 | }
269 |
270 | /**
271 | * 设置或获取当前完整URL 包括QUERY_STRING
272 | * @access public
273 | * @param string|true $url URL地址 true 带域名获取
274 | * @return string
275 | */
276 | public function url($url = null)
277 | {
278 | if (!is_null($url) && true !== $url) {
279 | $this->url = $url;
280 | return $this;
281 | } elseif (!$this->url) {
282 | if (IS_CLI) {
283 | $this->url = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
284 | } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
285 | $this->url = $_SERVER['HTTP_X_REWRITE_URL'];
286 | } elseif (isset($_SERVER['REQUEST_URI'])) {
287 | $this->url = $_SERVER['REQUEST_URI'];
288 | } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
289 | $this->url = $_SERVER['ORIG_PATH_INFO'] . (!empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '');
290 | } else {
291 | $this->url = '';
292 | }
293 | }
294 | return true === $url ? $this->domain() . $this->url : $this->url;
295 | }
296 |
297 | /**
298 | * 设置或获取当前URL 不含QUERY_STRING
299 | * @access public
300 | * @param string $url URL地址
301 | * @return string
302 | */
303 | public function baseUrl($url = null)
304 | {
305 | if (!is_null($url) && true !== $url) {
306 | $this->baseUrl = $url;
307 | return $this;
308 | } elseif (!$this->baseUrl) {
309 | $str = $this->url();
310 | $this->baseUrl = strpos($str, '?') ? strstr($str, '?', true) : $str;
311 | }
312 | return true === $url ? $this->domain() . $this->baseUrl : $this->baseUrl;
313 | }
314 |
315 | /**
316 | * 设置或获取当前执行的文件 SCRIPT_NAME
317 | * @access public
318 | * @param string $file 当前执行的文件
319 | * @return string
320 | */
321 | public function baseFile($file = null)
322 | {
323 | if (!is_null($file) && true !== $file) {
324 | $this->baseFile = $file;
325 | return $this;
326 | } elseif (!$this->baseFile) {
327 | $url = '';
328 | if (!IS_CLI) {
329 | $script_name = basename($_SERVER['SCRIPT_FILENAME']);
330 | if (basename($_SERVER['SCRIPT_NAME']) === $script_name) {
331 | $url = $_SERVER['SCRIPT_NAME'];
332 | } elseif (basename($_SERVER['PHP_SELF']) === $script_name) {
333 | $url = $_SERVER['PHP_SELF'];
334 | } elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $script_name) {
335 | $url = $_SERVER['ORIG_SCRIPT_NAME'];
336 | } elseif (($pos = strpos($_SERVER['PHP_SELF'], '/' . $script_name)) !== false) {
337 | $url = substr($_SERVER['SCRIPT_NAME'], 0, $pos) . '/' . $script_name;
338 | } elseif (isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['SCRIPT_FILENAME'], $_SERVER['DOCUMENT_ROOT']) === 0) {
339 | $url = str_replace('\\', '/', str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_FILENAME']));
340 | }
341 | }
342 | $this->baseFile = $url;
343 | }
344 | return true === $file ? $this->domain() . $this->baseFile : $this->baseFile;
345 | }
346 |
347 | /**
348 | * 设置或获取URL访问根地址
349 | * @access public
350 | * @param string $url URL地址
351 | * @return string
352 | */
353 | public function root($url = null)
354 | {
355 | if (!is_null($url) && true !== $url) {
356 | $this->root = $url;
357 | return $this;
358 | } elseif (!$this->root) {
359 | $file = $this->baseFile();
360 | if ($file && 0 !== strpos($this->url(), $file)) {
361 | $file = str_replace('\\', '/', dirname($file));
362 | }
363 | $this->root = rtrim($file, '/');
364 | }
365 | return true === $url ? $this->domain() . $this->root : $this->root;
366 | }
367 |
368 | /**
369 | * 获取当前请求URL的pathinfo信息(含URL后缀)
370 | * @access public
371 | * @return string
372 | */
373 | public function pathinfo()
374 | {
375 | if (is_null($this->pathinfo)) {
376 | if (isset($_GET[Config::get('var_pathinfo')])) {
377 | // 判断URL里面是否有兼容模式参数
378 | $_SERVER['PATH_INFO'] = $_GET[Config::get('var_pathinfo')];
379 | unset($_GET[Config::get('var_pathinfo')]);
380 | } elseif (IS_CLI) {
381 | // CLI模式下 index.php module/controller/action/params/...
382 | $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
383 | }
384 |
385 | // 分析PATHINFO信息
386 | if (!isset($_SERVER['PATH_INFO'])) {
387 | foreach (Config::get('pathinfo_fetch') as $type) {
388 | if (!empty($_SERVER[$type])) {
389 | $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ?
390 | substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type];
391 | break;
392 | }
393 | }
394 | }
395 | $this->pathinfo = empty($_SERVER['PATH_INFO']) ? '/' : ltrim($_SERVER['PATH_INFO'], '/');
396 | }
397 | return $this->pathinfo;
398 | }
399 |
400 | /**
401 | * 获取当前请求URL的pathinfo信息(不含URL后缀)
402 | * @access public
403 | * @return string
404 | */
405 | public function path()
406 | {
407 | if (is_null($this->path)) {
408 | $suffix = Config::get('url_html_suffix');
409 | $pathinfo = $this->pathinfo();
410 | if (false === $suffix) {
411 | // 禁止伪静态访问
412 | $this->path = $pathinfo;
413 | } elseif ($suffix) {
414 | // 去除正常的URL后缀
415 | $this->path = preg_replace('/\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo);
416 | } else {
417 | // 允许任何后缀访问
418 | $this->path = preg_replace('/\.' . $this->ext() . '$/i', '', $pathinfo);
419 | }
420 | }
421 | return $this->path;
422 | }
423 |
424 | /**
425 | * 当前URL的访问后缀
426 | * @access public
427 | * @return string
428 | */
429 | public function ext()
430 | {
431 | return pathinfo($this->pathinfo(), PATHINFO_EXTENSION);
432 | }
433 |
434 | /**
435 | * 获取当前请求的时间
436 | * @access public
437 | * @param bool $float 是否使用浮点类型
438 | * @return integer|float
439 | */
440 | public function time($float = false)
441 | {
442 | return $float ? $_SERVER['REQUEST_TIME_FLOAT'] : $_SERVER['REQUEST_TIME'];
443 | }
444 |
445 | /**
446 | * 当前请求的资源类型
447 | * @access public
448 | * @return false|string
449 | */
450 | public function type()
451 | {
452 | $accept = $this->server('HTTP_ACCEPT');
453 | if (empty($accept)) {
454 | return false;
455 | }
456 |
457 | foreach ($this->mimeType as $key => $val) {
458 | $array = explode(',', $val);
459 | foreach ($array as $k => $v) {
460 | if (stristr($accept, $v)) {
461 | return $key;
462 | }
463 | }
464 | }
465 | return false;
466 | }
467 |
468 | /**
469 | * 设置资源类型
470 | * @access public
471 | * @param string|array $type 资源类型名
472 | * @param string $val 资源类型
473 | * @return void
474 | */
475 | public function mimeType($type, $val = '')
476 | {
477 | if (is_array($type)) {
478 | $this->mimeType = array_merge($this->mimeType, $type);
479 | } else {
480 | $this->mimeType[$type] = $val;
481 | }
482 | }
483 |
484 | /**
485 | * 当前的请求类型
486 | * @access public
487 | * @param bool $method true 获取原始请求类型
488 | * @return string
489 | */
490 | public function method($method = false)
491 | {
492 | if (true === $method) {
493 | // 获取原始请求类型
494 | return IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']);
495 | } elseif (!$this->method) {
496 | if (isset($_POST[Config::get('var_method')])) {
497 | $this->method = strtoupper($_POST[Config::get('var_method')]);
498 | $this->{$this->method}($_POST);
499 | } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
500 | $this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
501 | } else {
502 | $this->method = IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']);
503 | }
504 | }
505 | return $this->method;
506 | }
507 |
508 | /**
509 | * 是否为GET请求
510 | * @access public
511 | * @return bool
512 | */
513 | public function isGet()
514 | {
515 | return $this->method() == 'GET';
516 | }
517 |
518 | /**
519 | * 是否为POST请求
520 | * @access public
521 | * @return bool
522 | */
523 | public function isPost()
524 | {
525 | return $this->method() == 'POST';
526 | }
527 |
528 | /**
529 | * 是否为PUT请求
530 | * @access public
531 | * @return bool
532 | */
533 | public function isPut()
534 | {
535 | return $this->method() == 'PUT';
536 | }
537 |
538 | /**
539 | * 是否为DELTE请求
540 | * @access public
541 | * @return bool
542 | */
543 | public function isDelete()
544 | {
545 | return $this->method() == 'DELETE';
546 | }
547 |
548 | /**
549 | * 是否为HEAD请求
550 | * @access public
551 | * @return bool
552 | */
553 | public function isHead()
554 | {
555 | return $this->method() == 'HEAD';
556 | }
557 |
558 | /**
559 | * 是否为PATCH请求
560 | * @access public
561 | * @return bool
562 | */
563 | public function isPatch()
564 | {
565 | return $this->method() == 'PATCH';
566 | }
567 |
568 | /**
569 | * 是否为OPTIONS请求
570 | * @access public
571 | * @return bool
572 | */
573 | public function isOptions()
574 | {
575 | return $this->method() == 'OPTIONS';
576 | }
577 |
578 | /**
579 | * 是否为cli
580 | * @access public
581 | * @return bool
582 | */
583 | public function isCli()
584 | {
585 | return PHP_SAPI == 'cli';
586 | }
587 |
588 | /**
589 | * 是否为cgi
590 | * @access public
591 | * @return bool
592 | */
593 | public function isCgi()
594 | {
595 | return strpos(PHP_SAPI, 'cgi') === 0;
596 | }
597 |
598 | /**
599 | * 获取当前请求的参数
600 | * @access public
601 | * @param string|array $name 变量名
602 | * @param mixed $default 默认值
603 | * @param string|array $filter 过滤方法
604 | * @return mixed
605 | */
606 | public function param($name = '', $default = null, $filter = '')
607 | {
608 | if (empty($this->param)) {
609 | $method = $this->method(true);
610 | // 自动获取请求变量
611 | switch ($method) {
612 | case 'POST':
613 | $vars = $this->post(false);
614 | break;
615 | case 'PUT':
616 | case 'DELETE':
617 | case 'PATCH':
618 | $vars = $this->put(false);
619 | break;
620 | default:
621 | $vars = [];
622 | }
623 | // 当前请求参数和URL地址中的参数合并
624 | $this->param = array_merge($this->get(false), $vars, $this->route(false));
625 | }
626 | if (true === $name) {
627 | // 获取包含文件上传信息的数组
628 | $file = $this->file();
629 | $data = is_array($file) ? array_merge($this->param, $file) : $this->param;
630 | return $this->input($data, '', $default, $filter);
631 | }
632 | return $this->input($this->param, $name, $default, $filter);
633 | }
634 |
635 | /**
636 | * 设置获取路由参数
637 | * @access public
638 | * @param string|array $name 变量名
639 | * @param mixed $default 默认值
640 | * @param string|array $filter 过滤方法
641 | * @return mixed
642 | */
643 | public function route($name = '', $default = null, $filter = '')
644 | {
645 | if (is_array($name)) {
646 | $this->param = [];
647 | return $this->route = array_merge($this->route, $name);
648 | }
649 | return $this->input($this->route, $name, $default, $filter);
650 | }
651 |
652 | /**
653 | * 设置获取GET参数
654 | * @access public
655 | * @param string|array $name 变量名
656 | * @param mixed $default 默认值
657 | * @param string|array $filter 过滤方法
658 | * @return mixed
659 | */
660 | public function get($name = '', $default = null, $filter = '')
661 | {
662 | if (empty($this->get)) {
663 | $this->get = $_GET;
664 | }
665 | if (is_array($name)) {
666 | $this->param = [];
667 | return $this->get = array_merge($this->get, $name);
668 | }
669 | return $this->input($this->get, $name, $default, $filter);
670 | }
671 |
672 | /**
673 | * 设置获取POST参数
674 | * @access public
675 | * @param string $name 变量名
676 | * @param mixed $default 默认值
677 | * @param string|array $filter 过滤方法
678 | * @return mixed
679 | */
680 | public function post($name = '', $default = null, $filter = '')
681 | {
682 | if (empty($this->post)) {
683 | $content = $this->input;
684 | if (empty($_POST) && false !== strpos($this->contentType(), 'application/json')) {
685 | $this->post = (array) json_decode($content, true);
686 | } else {
687 | $this->post = $_POST;
688 | }
689 | }
690 | if (is_array($name)) {
691 | $this->param = [];
692 | return $this->post = array_merge($this->post, $name);
693 | }
694 | return $this->input($this->post, $name, $default, $filter);
695 | }
696 |
697 | /**
698 | * 设置获取PUT参数
699 | * @access public
700 | * @param string|array $name 变量名
701 | * @param mixed $default 默认值
702 | * @param string|array $filter 过滤方法
703 | * @return mixed
704 | */
705 | public function put($name = '', $default = null, $filter = '')
706 | {
707 | if (is_null($this->put)) {
708 | $content = $this->input;
709 | if (false !== strpos($this->contentType(), 'application/json')) {
710 | $this->put = (array) json_decode($content, true);
711 | } else {
712 | parse_str($content, $this->put);
713 | }
714 | }
715 | if (is_array($name)) {
716 | $this->param = [];
717 | return $this->put = is_null($this->put) ? $name : array_merge($this->put, $name);
718 | }
719 |
720 | return $this->input($this->put, $name, $default, $filter);
721 | }
722 |
723 | /**
724 | * 设置获取DELETE参数
725 | * @access public
726 | * @param string|array $name 变量名
727 | * @param mixed $default 默认值
728 | * @param string|array $filter 过滤方法
729 | * @return mixed
730 | */
731 | public function delete($name = '', $default = null, $filter = '')
732 | {
733 | return $this->put($name, $default, $filter);
734 | }
735 |
736 | /**
737 | * 设置获取PATCH参数
738 | * @access public
739 | * @param string|array $name 变量名
740 | * @param mixed $default 默认值
741 | * @param string|array $filter 过滤方法
742 | * @return mixed
743 | */
744 | public function patch($name = '', $default = null, $filter = '')
745 | {
746 | return $this->put($name, $default, $filter);
747 | }
748 |
749 | /**
750 | * 获取request变量
751 | * @param string $name 数据名称
752 | * @param string $default 默认值
753 | * @param string|array $filter 过滤方法
754 | * @return mixed
755 | */
756 | public function request($name = '', $default = null, $filter = '')
757 | {
758 | if (empty($this->request)) {
759 | $this->request = $_REQUEST;
760 | }
761 | if (is_array($name)) {
762 | $this->param = [];
763 | return $this->request = array_merge($this->request, $name);
764 | }
765 | return $this->input($this->request, $name, $default, $filter);
766 | }
767 |
768 | /**
769 | * 获取session数据
770 | * @access public
771 | * @param string|array $name 数据名称
772 | * @param string $default 默认值
773 | * @param string|array $filter 过滤方法
774 | * @return mixed
775 | */
776 | public function session($name = '', $default = null, $filter = '')
777 | {
778 | if (empty($this->session)) {
779 | $this->session = Session::get();
780 | }
781 | if (is_array($name)) {
782 | return $this->session = array_merge($this->session, $name);
783 | }
784 | return $this->input($this->session, $name, $default, $filter);
785 | }
786 |
787 | /**
788 | * 获取cookie参数
789 | * @access public
790 | * @param string|array $name 数据名称
791 | * @param string $default 默认值
792 | * @param string|array $filter 过滤方法
793 | * @return mixed
794 | */
795 | public function cookie($name = '', $default = null, $filter = '')
796 | {
797 | if (empty($this->cookie)) {
798 | $this->cookie = Cookie::get();
799 | }
800 | if (is_array($name)) {
801 | return $this->cookie = array_merge($this->cookie, $name);
802 | } elseif (!empty($name)) {
803 | $data = Cookie::has($name) ? Cookie::get($name) : $default;
804 | } else {
805 | $data = $this->cookie;
806 | }
807 |
808 | // 解析过滤器
809 | $filter = $this->getFilter($filter, $default);
810 |
811 | if (is_array($data)) {
812 | array_walk_recursive($data, [$this, 'filterValue'], $filter);
813 | reset($data);
814 | } else {
815 | $this->filterValue($data, $name, $filter);
816 | }
817 | return $data;
818 | }
819 |
820 | /**
821 | * 获取server参数
822 | * @access public
823 | * @param string|array $name 数据名称
824 | * @param string $default 默认值
825 | * @param string|array $filter 过滤方法
826 | * @return mixed
827 | */
828 | public function server($name = '', $default = null, $filter = '')
829 | {
830 | if (empty($this->server)) {
831 | $this->server = $_SERVER;
832 | }
833 | if (is_array($name)) {
834 | return $this->server = array_merge($this->server, $name);
835 | }
836 | return $this->input($this->server, false === $name ? false : strtoupper($name), $default, $filter);
837 | }
838 |
839 | /**
840 | * 获取上传的文件信息
841 | * @access public
842 | * @param string|array $name 名称
843 | * @return null|array|\File
844 | */
845 | public function file($name = '')
846 | {
847 | if (empty($this->file)) {
848 | $this->file = isset($_FILES) ? $_FILES : [];
849 | }
850 | if (is_array($name)) {
851 | return $this->file = array_merge($this->file, $name);
852 | }
853 | $files = $this->file;
854 | if (!empty($files)) {
855 | // 处理上传文件
856 | $array = [];
857 | foreach ($files as $key => $file) {
858 | if (is_array($file['name'])) {
859 | $item = [];
860 | $keys = array_keys($file);
861 | $count = count($file['name']);
862 | for ($i = 0; $i < $count; $i++) {
863 | if (empty($file['tmp_name'][$i]) || !is_file($file['tmp_name'][$i])) {
864 | continue;
865 | }
866 | $temp['key'] = $key;
867 | foreach ($keys as $_key) {
868 | $temp[$_key] = $file[$_key][$i];
869 | }
870 | $item[] = (new File($temp['tmp_name']))->setUploadInfo($temp);
871 | }
872 | $array[$key] = $item;
873 | } else {
874 | if ($file instanceof File) {
875 | $array[$key] = $file;
876 | } else {
877 | if (empty($file['tmp_name']) || !is_file($file['tmp_name'])) {
878 | continue;
879 | }
880 | $array[$key] = (new File($file['tmp_name']))->setUploadInfo($file);
881 | }
882 | }
883 | }
884 | if (strpos($name, '.')) {
885 | list($name, $sub) = explode('.', $name);
886 | }
887 | if ('' === $name) {
888 | // 获取全部文件
889 | return $array;
890 | } elseif (isset($sub) && isset($array[$name][$sub])) {
891 | return $array[$name][$sub];
892 | } elseif (isset($array[$name])) {
893 | return $array[$name];
894 | }
895 | }
896 | return;
897 | }
898 |
899 | /**
900 | * 获取环境变量
901 | * @param string|array $name 数据名称
902 | * @param string $default 默认值
903 | * @param string|array $filter 过滤方法
904 | * @return mixed
905 | */
906 | public function env($name = '', $default = null, $filter = '')
907 | {
908 | if (empty($this->env)) {
909 | $this->env = $_ENV;
910 | }
911 | if (is_array($name)) {
912 | return $this->env = array_merge($this->env, $name);
913 | }
914 | return $this->input($this->env, false === $name ? false : strtoupper($name), $default, $filter);
915 | }
916 |
917 | /**
918 | * 设置或者获取当前的Header
919 | * @access public
920 | * @param string|array $name header名称
921 | * @param string $default 默认值
922 | * @return string
923 | */
924 | public function header($name = '', $default = null)
925 | {
926 | if (empty($this->header)) {
927 | $header = [];
928 | if (function_exists('apache_request_headers') && $result = apache_request_headers()) {
929 | $header = $result;
930 | } else {
931 | $server = $this->server ?: $_SERVER;
932 | foreach ($server as $key => $val) {
933 | if (0 === strpos($key, 'HTTP_')) {
934 | $key = str_replace('_', '-', strtolower(substr($key, 5)));
935 | $header[$key] = $val;
936 | }
937 | }
938 | if (isset($server['CONTENT_TYPE'])) {
939 | $header['content-type'] = $server['CONTENT_TYPE'];
940 | }
941 | if (isset($server['CONTENT_LENGTH'])) {
942 | $header['content-length'] = $server['CONTENT_LENGTH'];
943 | }
944 | }
945 | $this->header = array_change_key_case($header);
946 | }
947 | if (is_array($name)) {
948 | return $this->header = array_merge($this->header, $name);
949 | }
950 | if ('' === $name) {
951 | return $this->header;
952 | }
953 | $name = str_replace('_', '-', strtolower($name));
954 | return isset($this->header[$name]) ? $this->header[$name] : $default;
955 | }
956 |
957 | /**
958 | * 获取变量 支持过滤和默认值
959 | * @param array $data 数据源
960 | * @param string|false $name 字段名
961 | * @param mixed $default 默认值
962 | * @param string|array $filter 过滤函数
963 | * @return mixed
964 | */
965 | public function input($data = [], $name = '', $default = null, $filter = '')
966 | {
967 | if (false === $name) {
968 | // 获取原始数据
969 | return $data;
970 | }
971 | $name = (string) $name;
972 | if ('' != $name) {
973 | // 解析name
974 | if (strpos($name, '/')) {
975 | list($name, $type) = explode('/', $name);
976 | } else {
977 | $type = 's';
978 | }
979 | // 按.拆分成多维数组进行判断
980 | foreach (explode('.', $name) as $val) {
981 | if (isset($data[$val])) {
982 | $data = $data[$val];
983 | } else {
984 | // 无输入数据,返回默认值
985 | return $default;
986 | }
987 | }
988 | if (is_object($data)) {
989 | return $data;
990 | }
991 | }
992 |
993 | // 解析过滤器
994 | $filter = $this->getFilter($filter, $default);
995 |
996 | if (is_array($data)) {
997 | array_walk_recursive($data, [$this, 'filterValue'], $filter);
998 | reset($data);
999 | } else {
1000 | $this->filterValue($data, $name, $filter);
1001 | }
1002 |
1003 | if (isset($type) && $data !== $default) {
1004 | // 强制类型转换
1005 | $this->typeCast($data, $type);
1006 | }
1007 | return $data;
1008 | }
1009 |
1010 | /**
1011 | * 设置或获取当前的过滤规则
1012 | * @param mixed $filter 过滤规则
1013 | * @return mixed
1014 | */
1015 | public function filter($filter = null)
1016 | {
1017 | if (is_null($filter)) {
1018 | return $this->filter;
1019 | } else {
1020 | $this->filter = $filter;
1021 | }
1022 | }
1023 |
1024 | protected function getFilter($filter, $default)
1025 | {
1026 | if (is_null($filter)) {
1027 | $filter = [];
1028 | } else {
1029 | $filter = $filter ?: $this->filter;
1030 | if (is_string($filter) && false === strpos($filter, '/')) {
1031 | $filter = explode(',', $filter);
1032 | } else {
1033 | $filter = (array) $filter;
1034 | }
1035 | }
1036 |
1037 | $filter[] = $default;
1038 | return $filter;
1039 | }
1040 |
1041 | /**
1042 | * 递归过滤给定的值
1043 | * @param mixed $value 键值
1044 | * @param mixed $key 键名
1045 | * @param array $filters 过滤方法+默认值
1046 | * @return mixed
1047 | */
1048 | private function filterValue(&$value, $key, $filters)
1049 | {
1050 | $default = array_pop($filters);
1051 | foreach ($filters as $filter) {
1052 | if (is_callable($filter)) {
1053 | // 调用函数或者方法过滤
1054 | $value = call_user_func($filter, $value);
1055 | } elseif (is_scalar($value)) {
1056 | if (false !== strpos($filter, '/')) {
1057 | // 正则过滤
1058 | if (!preg_match($filter, $value)) {
1059 | // 匹配不成功返回默认值
1060 | $value = $default;
1061 | break;
1062 | }
1063 | } elseif (!empty($filter)) {
1064 | // filter函数不存在时, 则使用filter_var进行过滤
1065 | // filter为非整形值时, 调用filter_id取得过滤id
1066 | $value = filter_var($value, is_int($filter) ? $filter : filter_id($filter));
1067 | if (false === $value) {
1068 | $value = $default;
1069 | break;
1070 | }
1071 | }
1072 | }
1073 | }
1074 | return $this->filterExp($value);
1075 | }
1076 |
1077 | /**
1078 | * 过滤表单中的表达式
1079 | * @param string $value
1080 | * @return void
1081 | */
1082 | public function filterExp(&$value)
1083 | {
1084 | // 过滤查询特殊字符
1085 | if (is_string($value) && preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) {
1086 | $value .= ' ';
1087 | }
1088 | // TODO 其他安全过滤
1089 | }
1090 |
1091 | /**
1092 | * 强制类型转换
1093 | * @param string $data
1094 | * @param string $type
1095 | * @return mixed
1096 | */
1097 | private function typeCast(&$data, $type)
1098 | {
1099 | switch (strtolower($type)) {
1100 | // 数组
1101 | case 'a':
1102 | $data = (array) $data;
1103 | break;
1104 | // 数字
1105 | case 'd':
1106 | $data = (int) $data;
1107 | break;
1108 | // 浮点
1109 | case 'f':
1110 | $data = (float) $data;
1111 | break;
1112 | // 布尔
1113 | case 'b':
1114 | $data = (boolean) $data;
1115 | break;
1116 | // 字符串
1117 | case 's':
1118 | default:
1119 | if (is_scalar($data)) {
1120 | $data = (string) $data;
1121 | } else {
1122 | throw new \InvalidArgumentException('variable type error:' . gettype($data));
1123 | }
1124 | }
1125 | }
1126 |
1127 | /**
1128 | * 是否存在某个请求参数
1129 | * @access public
1130 | * @param string $name 变量名
1131 | * @param string $type 变量类型
1132 | * @param bool $checkEmpty 是否检测空值
1133 | * @return mixed
1134 | */
1135 | public function has($name, $type = 'param', $checkEmpty = false)
1136 | {
1137 | if (empty($this->$type)) {
1138 | $param = $this->$type();
1139 | } else {
1140 | $param = $this->$type;
1141 | }
1142 | // 按.拆分成多维数组进行判断
1143 | foreach (explode('.', $name) as $val) {
1144 | if (isset($param[$val])) {
1145 | $param = $param[$val];
1146 | } else {
1147 | return false;
1148 | }
1149 | }
1150 | return ($checkEmpty && '' === $param) ? false : true;
1151 | }
1152 |
1153 | /**
1154 | * 获取指定的参数
1155 | * @access public
1156 | * @param string|array $name 变量名
1157 | * @param string $type 变量类型
1158 | * @return mixed
1159 | */
1160 | public function only($name, $type = 'param')
1161 | {
1162 | $param = $this->$type();
1163 | if (is_string($name)) {
1164 | $name = explode(',', $name);
1165 | }
1166 | $item = [];
1167 | foreach ($name as $key) {
1168 | if (isset($param[$key])) {
1169 | $item[$key] = $param[$key];
1170 | }
1171 | }
1172 | return $item;
1173 | }
1174 |
1175 | /**
1176 | * 排除指定参数获取
1177 | * @access public
1178 | * @param string|array $name 变量名
1179 | * @param string $type 变量类型
1180 | * @return mixed
1181 | */
1182 | public function except($name, $type = 'param')
1183 | {
1184 | $param = $this->$type();
1185 | if (is_string($name)) {
1186 | $name = explode(',', $name);
1187 | }
1188 | foreach ($name as $key) {
1189 | if (isset($param[$key])) {
1190 | unset($param[$key]);
1191 | }
1192 | }
1193 | return $param;
1194 | }
1195 |
1196 | /**
1197 | * 当前是否ssl
1198 | * @access public
1199 | * @return bool
1200 | */
1201 | public function isSsl()
1202 | {
1203 | $server = array_merge($_SERVER, $this->server);
1204 | if (isset($server['HTTPS']) && ('1' == $server['HTTPS'] || 'on' == strtolower($server['HTTPS']))) {
1205 | return true;
1206 | } elseif (isset($server['REQUEST_SCHEME']) && 'https' == $server['REQUEST_SCHEME']) {
1207 | return true;
1208 | } elseif (isset($server['SERVER_PORT']) && ('443' == $server['SERVER_PORT'])) {
1209 | return true;
1210 | } elseif (isset($server['HTTP_X_FORWARDED_PROTO']) && 'https' == $server['HTTP_X_FORWARDED_PROTO']) {
1211 | return true;
1212 | } elseif (Config::get('https_agent_name') && isset($server[Config::get('https_agent_name')])) {
1213 | return true;
1214 | }
1215 | return false;
1216 | }
1217 |
1218 | /**
1219 | * 当前是否Ajax请求
1220 | * @access public
1221 | * @param bool $ajax true 获取原始ajax请求
1222 | * @return bool
1223 | */
1224 | public function isAjax($ajax = false)
1225 | {
1226 | $value = $this->server('HTTP_X_REQUESTED_WITH', '', 'strtolower');
1227 | $result = ('xmlhttprequest' == $value) ? true : false;
1228 | if (true === $ajax) {
1229 | return $result;
1230 | } else {
1231 | return $this->param(Config::get('var_ajax')) ? true : $result;
1232 | }
1233 | }
1234 |
1235 | /**
1236 | * 当前是否Pjax请求
1237 | * @access public
1238 | * @param bool $pjax true 获取原始pjax请求
1239 | * @return bool
1240 | */
1241 | public function isPjax($pjax = false)
1242 | {
1243 | $result = !is_null($this->server('HTTP_X_PJAX')) ? true : false;
1244 | if (true === $pjax) {
1245 | return $result;
1246 | } else {
1247 | return $this->param(Config::get('var_pjax')) ? true : $result;
1248 | }
1249 | }
1250 |
1251 | /**
1252 | * 获取客户端IP地址
1253 | * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
1254 | * @param boolean $adv 是否进行高级模式获取(有可能被伪装)
1255 | * @return mixed
1256 | */
1257 | public function ip($type = 0, $adv = false)
1258 | {
1259 | $type = $type ? 1 : 0;
1260 | static $ip = null;
1261 | if (null !== $ip) {
1262 | return $ip[$type];
1263 | }
1264 |
1265 | if ($adv) {
1266 | if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
1267 | $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
1268 | $pos = array_search('unknown', $arr);
1269 | if (false !== $pos) {
1270 | unset($arr[$pos]);
1271 | }
1272 | $ip = trim(current($arr));
1273 | } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
1274 | $ip = $_SERVER['HTTP_CLIENT_IP'];
1275 | } elseif (isset($_SERVER['REMOTE_ADDR'])) {
1276 | $ip = $_SERVER['REMOTE_ADDR'];
1277 | }
1278 | } elseif (isset($_SERVER['REMOTE_ADDR'])) {
1279 | $ip = $_SERVER['REMOTE_ADDR'];
1280 | }
1281 | // IP地址合法验证
1282 | $long = sprintf("%u", ip2long($ip));
1283 | $ip = $long ? [$ip, $long] : ['0.0.0.0', 0];
1284 | return $ip[$type];
1285 | }
1286 |
1287 | /**
1288 | * 检测是否使用手机访问
1289 | * @access public
1290 | * @return bool
1291 | */
1292 | public function isMobile()
1293 | {
1294 | if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], "wap")) {
1295 | return true;
1296 | } elseif (isset($_SERVER['HTTP_ACCEPT']) && strpos(strtoupper($_SERVER['HTTP_ACCEPT']), "VND.WAP.WML")) {
1297 | return true;
1298 | } elseif (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE'])) {
1299 | return true;
1300 | } elseif (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i', $_SERVER['HTTP_USER_AGENT'])) {
1301 | return true;
1302 | } else {
1303 | return false;
1304 | }
1305 | }
1306 |
1307 | /**
1308 | * 当前URL地址中的scheme参数
1309 | * @access public
1310 | * @return string
1311 | */
1312 | public function scheme()
1313 | {
1314 | return $this->isSsl() ? 'https' : 'http';
1315 | }
1316 |
1317 | /**
1318 | * 当前请求URL地址中的query参数
1319 | * @access public
1320 | * @return string
1321 | */
1322 | public function query()
1323 | {
1324 | return $this->server('QUERY_STRING');
1325 | }
1326 |
1327 | /**
1328 | * 当前请求的host
1329 | * @access public
1330 | * @return string
1331 | */
1332 | public function host()
1333 | {
1334 | return $this->server('HTTP_HOST');
1335 | }
1336 |
1337 | /**
1338 | * 当前请求URL地址中的port参数
1339 | * @access public
1340 | * @return integer
1341 | */
1342 | public function port()
1343 | {
1344 | return $this->server('SERVER_PORT');
1345 | }
1346 |
1347 | /**
1348 | * 当前请求 SERVER_PROTOCOL
1349 | * @access public
1350 | * @return integer
1351 | */
1352 | public function protocol()
1353 | {
1354 | return $this->server('SERVER_PROTOCOL');
1355 | }
1356 |
1357 | /**
1358 | * 当前请求 REMOTE_PORT
1359 | * @access public
1360 | * @return integer
1361 | */
1362 | public function remotePort()
1363 | {
1364 | return $this->server('REMOTE_PORT');
1365 | }
1366 |
1367 | /**
1368 | * 当前请求 HTTP_CONTENT_TYPE
1369 | * @access public
1370 | * @return string
1371 | */
1372 | public function contentType()
1373 | {
1374 | $contentType = $this->server('CONTENT_TYPE');
1375 | if ($contentType) {
1376 | if (strpos($contentType, ';')) {
1377 | list($type) = explode(';', $contentType);
1378 | } else {
1379 | $type = $contentType;
1380 | }
1381 | return trim($type);
1382 | }
1383 | return '';
1384 | }
1385 |
1386 | /**
1387 | * 获取当前请求的路由信息
1388 | * @access public
1389 | * @param array $route 路由名称
1390 | * @return array
1391 | */
1392 | public function routeInfo($route = [])
1393 | {
1394 | if (!empty($route)) {
1395 | $this->routeInfo = $route;
1396 | } else {
1397 | return $this->routeInfo;
1398 | }
1399 | }
1400 |
1401 | /**
1402 | * 设置或者获取当前请求的调度信息
1403 | * @access public
1404 | * @param array $dispatch 调度信息
1405 | * @return array
1406 | */
1407 | public function dispatch($dispatch = null)
1408 | {
1409 | if (!is_null($dispatch)) {
1410 | $this->dispatch = $dispatch;
1411 | }
1412 | return $this->dispatch;
1413 | }
1414 |
1415 | /**
1416 | * 设置或者获取当前的模块名
1417 | * @access public
1418 | * @param string $module 模块名
1419 | * @return string|Request
1420 | */
1421 | public function module($module = null)
1422 | {
1423 | if (!is_null($module)) {
1424 | $this->module = $module;
1425 | return $this;
1426 | } else {
1427 | return $this->module ?: '';
1428 | }
1429 | }
1430 |
1431 | /**
1432 | * 设置或者获取当前的控制器名
1433 | * @access public
1434 | * @param string $controller 控制器名
1435 | * @return string|Request
1436 | */
1437 | public function controller($controller = null)
1438 | {
1439 | if (!is_null($controller)) {
1440 | $this->controller = $controller;
1441 | return $this;
1442 | } else {
1443 | return $this->controller ?: '';
1444 | }
1445 | }
1446 |
1447 | /**
1448 | * 设置或者获取当前的操作名
1449 | * @access public
1450 | * @param string $action 操作名
1451 | * @return string|Request
1452 | */
1453 | public function action($action = null)
1454 | {
1455 | if (!is_null($action)) {
1456 | $this->action = $action;
1457 | return $this;
1458 | } else {
1459 | return $this->action ?: '';
1460 | }
1461 | }
1462 |
1463 | /**
1464 | * 设置或者获取当前的语言
1465 | * @access public
1466 | * @param string $lang 语言名
1467 | * @return string|Request
1468 | */
1469 | public function langset($lang = null)
1470 | {
1471 | if (!is_null($lang)) {
1472 | $this->langset = $lang;
1473 | return $this;
1474 | } else {
1475 | return $this->langset ?: '';
1476 | }
1477 | }
1478 |
1479 | /**
1480 | * 设置或者获取当前请求的content
1481 | * @access public
1482 | * @return string
1483 | */
1484 | public function getContent()
1485 | {
1486 | if (is_null($this->content)) {
1487 | $this->content = $this->input;
1488 | }
1489 | return $this->content;
1490 | }
1491 |
1492 | /**
1493 | * 获取当前请求的php://input
1494 | * @access public
1495 | * @return string
1496 | */
1497 | public function getInput()
1498 | {
1499 | return $this->input;
1500 | }
1501 |
1502 | /**
1503 | * 生成请求令牌
1504 | * @access public
1505 | * @param string $name 令牌名称
1506 | * @param mixed $type 令牌生成方法
1507 | * @return string
1508 | */
1509 | public function token($name = '__token__', $type = 'md5')
1510 | {
1511 | $type = is_callable($type) ? $type : 'md5';
1512 | $token = call_user_func($type, $_SERVER['REQUEST_TIME_FLOAT']);
1513 | if ($this->isAjax()) {
1514 | header($name . ': ' . $token);
1515 | }
1516 | Session::set($name, $token);
1517 | return $token;
1518 | }
1519 |
1520 | /**
1521 | * 设置当前地址的请求缓存
1522 | * @access public
1523 | * @param string $key 缓存标识,支持变量规则 ,例如 item/:name/:id
1524 | * @param mixed $expire 缓存有效期
1525 | * @param array $except 缓存排除
1526 | * @param string $tag 缓存标签
1527 | * @return void
1528 | */
1529 | public function cache($key, $expire = null, $except = [], $tag = null)
1530 | {
1531 | if (!is_array($except)) {
1532 | $tag = $except;
1533 | $except = [];
1534 | }
1535 |
1536 | if (false !== $key && $this->isGet() && !$this->isCheckCache) {
1537 | // 标记请求缓存检查
1538 | $this->isCheckCache = true;
1539 | if (false === $expire) {
1540 | // 关闭当前缓存
1541 | return;
1542 | }
1543 | if ($key instanceof \Closure) {
1544 | $key = call_user_func_array($key, [$this]);
1545 | } elseif (true === $key) {
1546 | foreach ($except as $rule) {
1547 | if (0 === stripos($this->url(), $rule)) {
1548 | return;
1549 | }
1550 | }
1551 | // 自动缓存功能
1552 | $key = '__URL__';
1553 | } elseif (strpos($key, '|')) {
1554 | list($key, $fun) = explode('|', $key);
1555 | }
1556 | // 特殊规则替换
1557 | if (false !== strpos($key, '__')) {
1558 | $key = str_replace(['__MODULE__', '__CONTROLLER__', '__ACTION__', '__URL__', ''], [$this->module, $this->controller, $this->action, md5($this->url(true))], $key);
1559 | }
1560 |
1561 | if (false !== strpos($key, ':')) {
1562 | $param = $this->param();
1563 | foreach ($param as $item => $val) {
1564 | if (is_string($val) && false !== strpos($key, ':' . $item)) {
1565 | $key = str_replace(':' . $item, $val, $key);
1566 | }
1567 | }
1568 | } elseif (strpos($key, ']')) {
1569 | if ('[' . $this->ext() . ']' == $key) {
1570 | // 缓存某个后缀的请求
1571 | $key = md5($this->url());
1572 | } else {
1573 | return;
1574 | }
1575 | }
1576 | if (isset($fun)) {
1577 | $key = $fun($key);
1578 | }
1579 |
1580 | if (strtotime($this->server('HTTP_IF_MODIFIED_SINCE')) + $expire > $_SERVER['REQUEST_TIME']) {
1581 | // 读取缓存
1582 | $response = Response::create()->code(304);
1583 | throw new \Andromeda\Exception($response);
1584 | } elseif (Cache::has($key)) {
1585 | list($content, $header) = Cache::get($key);
1586 | $response = Response::create($content)->header($header);
1587 | throw new \Andromeda\Exception($response);
1588 | } else {
1589 | $this->cache = [$key, $expire, $tag];
1590 | }
1591 | }
1592 | }
1593 |
1594 | /**
1595 | * 读取请求缓存设置
1596 | * @access public
1597 | * @return array
1598 | */
1599 | public function getCache()
1600 | {
1601 | return $this->cache;
1602 | }
1603 |
1604 | /**
1605 | * 设置当前请求绑定的对象实例
1606 | * @access public
1607 | * @param string|array $name 绑定的对象标识
1608 | * @param mixed $obj 绑定的对象实例
1609 | * @return mixed
1610 | */
1611 | public function bind($name, $obj = null)
1612 | {
1613 | if (is_array($name)) {
1614 | $this->bind = array_merge($this->bind, $name);
1615 | } else {
1616 | $this->bind[$name] = $obj;
1617 | }
1618 | }
1619 |
1620 | public function __set($name, $value)
1621 | {
1622 | $this->bind[$name] = $value;
1623 | }
1624 |
1625 | public function __get($name)
1626 | {
1627 | return isset($this->bind[$name]) ? $this->bind[$name] : null;
1628 | }
1629 |
1630 | public function __isset($name)
1631 | {
1632 | return isset($this->bind[$name]);
1633 | }
1634 | }
1635 |
--------------------------------------------------------------------------------
/Andromeda/Response.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | namespace Andromeda;
13 |
14 |
15 | class Response
16 | {
17 | // 原始数据
18 | protected $data;
19 |
20 | // 当前的contentType
21 | protected $contentType = 'text/html';
22 |
23 | // 字符集
24 | protected $charset = 'utf-8';
25 |
26 | //状态
27 | protected $code = 200;
28 |
29 | // 输出参数
30 | protected $options = [];
31 | // header参数
32 | protected $header = [];
33 |
34 | protected $content = null;
35 |
36 | /**
37 | * 构造函数
38 | * @access public
39 | * @param mixed $data 输出数据
40 | * @param int $code
41 | * @param array $header
42 | * @param array $options 输出参数
43 | */
44 | public function __construct($data = '', $code = 200, array $header = [], $options = [])
45 | {
46 | $this->data($data);
47 | if (!empty($options)) {
48 | $this->options = array_merge($this->options, $options);
49 | }
50 | $this->contentType($this->contentType, $this->charset);
51 | $this->header = array_merge($this->header, $header);
52 | $this->code = $code;
53 | }
54 |
55 | /**
56 | * 创建Response对象
57 | * @access public
58 | * @param mixed $data 输出数据
59 | * @param string $type 输出类型
60 | * @param int $code
61 | * @param array $header
62 | * @param array $options 输出参数
63 | * @return Response
64 | */
65 | public static function create($data = '', $type = '', $code = 200, array $header = [], $options = [])
66 | {
67 | $type = empty($type) ? 'null' : strtolower($type);
68 |
69 | $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst($type);
70 | if (class_exists($class)) {
71 | $response = new $class($data, $code, $header, $options);
72 | } else {
73 | $response = new static($data, $code, $header, $options);
74 | }
75 |
76 | return $response;
77 | }
78 |
79 | /**
80 | * 发送数据到客户端
81 | * @access public
82 | * @return mixed
83 | * @throws \InvalidArgumentException
84 | */
85 | public function send()
86 | {
87 | // 监听response_send
88 | Hook::listen('response_send', $this);
89 |
90 | // 处理输出数据
91 | $data = $this->getContent();
92 |
93 | // Trace调试注入
94 | if (Env::get('app_trace', Config::get('app_trace'))) {
95 | Debug::inject($this, $data);
96 | }
97 |
98 | if (200 == $this->code) {
99 | $cache = Request::instance()->getCache();
100 | if ($cache) {
101 | $this->header['Cache-Control'] = 'max-age=' . $cache[1] . ',must-revalidate';
102 | $this->header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT';
103 | $this->header['Expires'] = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + $cache[1]) . ' GMT';
104 | Cache::tag($cache[2])->set($cache[0], [$data, $this->header], $cache[1]);
105 | }
106 | }
107 |
108 | if (!headers_sent() && !empty($this->header)) {
109 | // 发送状态码
110 | http_response_code($this->code);
111 | // 发送头部信息
112 | foreach ($this->header as $name => $val) {
113 | if (is_null($val)) {
114 | header($name);
115 | } else {
116 | header($name . ':' . $val);
117 | }
118 | }
119 | }
120 |
121 | echo $data;
122 |
123 | if (function_exists('fastcgi_finish_request')) {
124 | // 提高页面响应
125 | fastcgi_finish_request();
126 | }
127 |
128 | // 监听response_end
129 | Hook::listen('response_end', $this);
130 |
131 | // 清空当次请求有效的数据
132 | if (!($this instanceof RedirectResponse)) {
133 | Session::flush();
134 | }
135 | }
136 |
137 | /**
138 | * 处理数据
139 | * @access protected
140 | * @param mixed $data 要处理的数据
141 | * @return mixed
142 | */
143 | protected function output($data)
144 | {
145 | return $data;
146 | }
147 |
148 | /**
149 | * 输出的参数
150 | * @access public
151 | * @param mixed $options 输出参数
152 | * @return $this
153 | */
154 | public function options($options = [])
155 | {
156 | $this->options = array_merge($this->options, $options);
157 | return $this;
158 | }
159 |
160 | /**
161 | * 输出数据设置
162 | * @access public
163 | * @param mixed $data 输出数据
164 | * @return $this
165 | */
166 | public function data($data)
167 | {
168 | $this->data = $data;
169 | return $this;
170 | }
171 |
172 | /**
173 | * 设置响应头
174 | * @access public
175 | * @param string|array $name 参数名
176 | * @param string $value 参数值
177 | * @return $this
178 | */
179 | public function header($name, $value = null)
180 | {
181 | if (is_array($name)) {
182 | $this->header = array_merge($this->header, $name);
183 | } else {
184 | $this->header[$name] = $value;
185 | }
186 | return $this;
187 | }
188 |
189 | /**
190 | * 设置页面输出内容
191 | * @param $content
192 | * @return $this
193 | */
194 | public function content($content)
195 | {
196 | if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([
197 | $content,
198 | '__toString',
199 | ])
200 | ) {
201 | throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content)));
202 | }
203 |
204 | $this->content = (string) $content;
205 |
206 | return $this;
207 | }
208 |
209 | /**
210 | * 发送HTTP状态
211 | * @param integer $code 状态码
212 | * @return $this
213 | */
214 | public function code($code)
215 | {
216 | $this->code = $code;
217 | return $this;
218 | }
219 |
220 | /**
221 | * LastModified
222 | * @param string $time
223 | * @return $this
224 | */
225 | public function lastModified($time)
226 | {
227 | $this->header['Last-Modified'] = $time;
228 | return $this;
229 | }
230 |
231 | /**
232 | * Expires
233 | * @param string $time
234 | * @return $this
235 | */
236 | public function expires($time)
237 | {
238 | $this->header['Expires'] = $time;
239 | return $this;
240 | }
241 |
242 | /**
243 | * ETag
244 | * @param string $eTag
245 | * @return $this
246 | */
247 | public function eTag($eTag)
248 | {
249 | $this->header['ETag'] = $eTag;
250 | return $this;
251 | }
252 |
253 | /**
254 | * 页面缓存控制
255 | * @param string $cache 状态码
256 | * @return $this
257 | */
258 | public function cacheControl($cache)
259 | {
260 | $this->header['Cache-control'] = $cache;
261 | return $this;
262 | }
263 |
264 | /**
265 | * 页面输出类型
266 | * @param string $contentType 输出类型
267 | * @param string $charset 输出编码
268 | * @return $this
269 | */
270 | public function contentType($contentType, $charset = 'utf-8')
271 | {
272 | $this->header['Content-Type'] = $contentType . '; charset=' . $charset;
273 | return $this;
274 | }
275 |
276 | /**
277 | * 获取头部信息
278 | * @param string $name 头部名称
279 | * @return mixed
280 | */
281 | public function getHeader($name = '')
282 | {
283 | if (!empty($name)) {
284 | return isset($this->header[$name]) ? $this->header[$name] : null;
285 | } else {
286 | return $this->header;
287 | }
288 | }
289 |
290 | /**
291 | * 获取原始数据
292 | * @return mixed
293 | */
294 | public function getData()
295 | {
296 | return $this->data;
297 | }
298 |
299 | /**
300 | * 获取输出数据
301 | * @return mixed
302 | */
303 | public function getContent()
304 | {
305 | if (null == $this->content) {
306 | $content = $this->output($this->data);
307 |
308 | if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([
309 | $content,
310 | '__toString',
311 | ])
312 | ) {
313 | throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content)));
314 | }
315 |
316 | $this->content = (string) $content;
317 | }
318 | return $this->content;
319 | }
320 |
321 | /**
322 | * 获取状态码
323 | * @return integer
324 | */
325 | public function getCode()
326 | {
327 | return $this->code;
328 | }
329 | }
330 |
--------------------------------------------------------------------------------
/Andromeda/core/Controller.class.php:
--------------------------------------------------------------------------------
1 | loader=new Loader();
10 | $this->view=new View();
11 | $this->di=$di;
12 |
13 |
14 | }
15 | public function redirect($url,$message,$wait=0){
16 | if($wait=0){
17 | header("Location:$url");
18 |
19 | }else{
20 | include CURR_VIEW_PATH."message.html";
21 |
22 | }
23 | exit;
24 |
25 | }
26 |
27 | protected function assign($name,$value='') {
28 | $this->view->assign($name,$value);
29 | return $this;
30 | }
31 |
32 | protected function display($template){
33 | $this->view->display(CURR_VIEW_PATH.$template);
34 |
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Andromeda/core/Loader.class.php:
--------------------------------------------------------------------------------
1 | db = Mysql::getInstance($dbConfig);
23 |
24 | $this->table = $GLOBALS['config']['DB_PREFIX'] . $table;
25 | $this->getFields();
26 |
27 | }
28 |
29 | //get the list of fields
30 | private function getFields()
31 | {
32 | $sql = "DESC " . $this->table;
33 | $result = $this->db->query($sql);
34 | foreach ($result as $v) {
35 | $this->fields[] = $v['Field'];
36 | if ($v['Key'] == 'PRI') {
37 | //if there is ok, save it in $pk
38 | $pk = $v['Field'];
39 |
40 | }
41 | }
42 |
43 | //if there is PK, add it into fields list
44 | if (isset($pk)) {
45 | $this->fields['pk'] = $pk;
46 |
47 | }
48 | }
49 |
50 | /**
51 | * Insert records
52 | * @access public
53 | * @param $list array associative array
54 | * @return mixed If succeed return inserted record id, else return false
55 | */
56 | public function insert($list)
57 | {
58 | $field_list = '';//field list string
59 | $value_list = '';//value list string
60 | foreach ($list as $k => $v) {
61 | if (in_array($k, $this->fields)) {
62 | $field_list .= "`" . $k . "`" . ',';
63 | $value_list .= "'" . $v . "'" . ',';
64 | }
65 | }
66 |
67 | //trim the comma on the right
68 | $field_list = rtrim($field_list, ',');
69 | $value_list = rtrim($value_list, ',');
70 | //Construct sql statement
71 | $sql = "insert into '{$this->table}' ({$field_list}) values ($value_list)";
72 | if ($this->db->query($sql)) {
73 | //insert succeed,return the last record's id;
74 | return $this->db->getInsertId();
75 |
76 | } else {
77 | return false;
78 |
79 | }
80 | }
81 |
82 | /*
83 | update records
84 | @access public
85 | @param $list array associative array needs to be updated
86 | @return mixed if succeed return the count of affected rows,else return false
87 | */
88 | public function update($list)
89 | {
90 | $upList = '';//update fields
91 | $where = 0;//update condition,default is 0;
92 | $update = '';
93 | foreach ($list as $k => $v) {
94 | if (in_array($k, $this->fields)) {
95 | if ($k == $this->fields['pk']) {
96 | //if it's PK,construct where condition
97 | $where = "'$k'=$v";
98 |
99 | } else {
100 | //if not PK,construct update list
101 | $update = $update . "'$k'=$v" . ",";
102 |
103 | }
104 | }
105 | }
106 | //trim comma on the right of update list
107 |
108 | //construct SQL statement
109 |
110 | $sql = "update '{$this->table}' set {$upList} where {$where}";
111 | if ($this->db->query($sql)) {
112 | //if succeed,return the count of affected rows
113 |
114 | if ($rows = mysql_affected_rows()) {
115 | //has count of affected rows
116 | return $rows;
117 |
118 | } else {
119 |
120 | //failed
121 | return false;
122 |
123 | }
124 |
125 | } else {
126 | return false;
127 |
128 | }
129 | }
130 |
131 | /*
132 | delete records
133 | @access public
134 | @param $pk mixed could be an int or a array
135 | @return mixed if succeed,return the count of deleted rows ,if fail ,return false
136 |
137 | */
138 | public function delete($pk)
139 | {
140 | $where = 0;//condition string
141 | //check if $pk is a single value or array,and construct where condition accordingly
142 |
143 | if (is_array($pk)) {
144 | //is array
145 | $where = "'{$this->fields['pk']}' in (" . implode(',', $pk) . ")";
146 |
147 | } else {
148 | //single value
149 | $where = "'{$this->fields['pk']}'=$pk";
150 |
151 | }
152 |
153 | //construct SQL statement
154 | $sql = "DELETE FROM '{$this->table}' WHERE $where";
155 | if ($this->db->query($sql)) {
156 | //if succeed return the count of affected rows;
157 | if ($rows = mysql_affected_rows()) {
158 | //has count of affected rows
159 | return $rows;
160 | } else {
161 | return false;
162 |
163 | }
164 |
165 | } else {
166 | return false;
167 |
168 | }
169 | }
170 |
171 | /** * Get info based on PK
172 | * @param $pk int Primary Key
173 | * @return array an array of single record
174 | */
175 |
176 | public function selectByPk($pk)
177 | {
178 | $sql = "select * from '{$this->table}' where '{$this->fields['pk']}'=$pk";
179 | return $this->db->getRow($sql);
180 |
181 | }
182 |
183 | /*
184 | get the count of all records
185 | */
186 | public function total()
187 | {
188 | $sql = "select count(*) from {$this->table}";
189 | return $this->db->getOne($sql);
190 |
191 | }
192 |
193 | /*
194 | get info of pagination
195 | @param $offset int offset value
196 | @param $limit int number of records of each fetch
197 | @param $where string where condition,default is empty
198 | */
199 | public function pageRows($offset, $limit, $where = '')
200 | {
201 | if (empty($where)) {
202 | $sql = "select * from {$this->table} limit $offset,$limit";
203 | } else {
204 | $sql = "select * from {$this->table} where $where limit $offset,$limit";
205 | }
206 | return $this->db->getAll($sql);
207 |
208 | }
209 |
210 |
211 | }
212 |
213 |
--------------------------------------------------------------------------------
/Andromeda/core/Mysql.class.php:
--------------------------------------------------------------------------------
1 |
6 | * @blog http://www.descartes.top/
7 | * @version >5.1 utf8
8 | */
9 | class Mysql
10 | {
11 | protected static $_instance = null;
12 | protected $dbName = '';
13 | protected $dsn;
14 | protected $dbClient;
15 |
16 | /**
17 | * 构造
18 | *
19 | * @param array $config
20 | * @throws Exception
21 | */
22 | private function __construct(array $config)
23 | {
24 | $host = isset($config['host']) ? $config['host'] : 'localhost';
25 |
26 | $user = isset($config['user']) ? $config['user'] : 'root';
27 |
28 | $password = isset($config['password']) ? $config['password'] : '';
29 |
30 | $db_name = isset($config['db_name']) ? $config['db_name'] : '';
31 |
32 | $port = isset($config['port']) ? $config['port'] : '3306';
33 |
34 | $charset = isset($config['charset']) ? $config['charset'] : 'utf-8';
35 |
36 | try {
37 | $this->dsn = 'mysql:host=' . $host . ';dbname=' . $db_name.";port=".$port;
38 | $this->dbClient = new PDO($this->dsn, $user, $password);
39 | $this->dbClient->exec('SET character_set_connection=' . $charset . ', character_set_results=' . $charset . ', character_set_client=binary');
40 | } catch (PDOException $e) {
41 | $this->outputError($e->getMessage());
42 | }
43 | }
44 |
45 | /**
46 | * 防止克隆
47 | *
48 | */
49 | private function __clone()
50 | {
51 | }
52 |
53 | /**
54 | * Singleton instance
55 | *
56 | * @param array $config
57 | * @return Object
58 | * @throws Exception
59 | */
60 | public static function getInstance(array $config)
61 | {
62 | if (self::$_instance === null) {
63 | self::$_instance = new self($config);
64 | }
65 | return self::$_instance;
66 | }
67 |
68 | /**
69 | * Query 查询
70 | *
71 | * @param String $strSql SQL语句
72 | * @param String $queryMode 查询方式(All or Row)
73 | * @param Boolean $debug
74 | * @return array
75 | */
76 | public function query($strSql, $queryMode = 'All', $debug = false)
77 | {
78 | if ($debug === true) $this->debug($strSql);
79 | $recordset = $this->dbClient->query($strSql);
80 | $this->getPDOError();
81 | if ($recordset) {
82 | $recordset->setFetchMode(PDO::FETCH_ASSOC);
83 | if ($queryMode == 'All') {
84 | $result = $recordset->fetchAll();
85 | } elseif ($queryMode == 'Row') {
86 | $result = $recordset->fetch();
87 | }
88 | } else {
89 | $result = null;
90 | }
91 | return $result;
92 | }
93 |
94 | /**
95 | * Update 更新
96 | *
97 | * @param String $table 表名
98 | * @param array $arrayDataValue 字段与值
99 | * @param String $where 条件
100 | * @param Boolean $debug
101 | * @return Int
102 | */
103 | public function update($table, $arrayDataValue, $where = '', $debug = false)
104 | {
105 | $this->checkFields($table, $arrayDataValue);
106 | if ($where) {
107 | $strSql = '';
108 | foreach ($arrayDataValue as $key => $value) {
109 | $strSql .= ", `$key`='$value'";
110 | }
111 | $strSql = substr($strSql, 1);
112 | $strSql = "UPDATE `$table` SET $strSql WHERE $where";
113 | } else {
114 | $strSql = "REPLACE INTO `$table` (`" . implode('`,`', array_keys($arrayDataValue)) . "`) VALUES ('" . implode("','", $arrayDataValue) . "')";
115 | }
116 | if ($debug === true) $this->debug($strSql);
117 | $result = $this->dbClient->exec($strSql);
118 | $this->getPDOError();
119 | return $result;
120 | }
121 |
122 | /**
123 | * Insert 插入
124 | *
125 | * @param String $table 表名
126 | * @param Array $arrayDataValue 字段与值
127 | * @param Boolean $debug
128 | * @return Int
129 | */
130 | public function insert($table, $arrayDataValue, $debug = false)
131 | {
132 | $this->checkFields($table, $arrayDataValue);
133 | $strSql = "INSERT INTO `$table` (`" . implode('`,`', array_keys($arrayDataValue)) . "`) VALUES ('" . implode("','", $arrayDataValue) . "')";
134 | if ($debug === true) $this->debug($strSql);
135 | $result = $this->dbClient->exec($strSql);
136 | $this->getPDOError();
137 | return $result;
138 | }
139 |
140 | /**
141 | * Replace 覆盖方式插入
142 | *
143 | * @param String $table 表名
144 | * @param Array $arrayDataValue 字段与值
145 | * @param Boolean $debug
146 | * @return Int
147 | */
148 | public function replace($table, $arrayDataValue, $debug = false)
149 | {
150 | $this->checkFields($table, $arrayDataValue);
151 | $strSql = "REPLACE INTO `$table`(`" . implode('`,`', array_keys($arrayDataValue)) . "`) VALUES ('" . implode("','", $arrayDataValue) . "')";
152 | if ($debug === true) $this->debug($strSql);
153 | $result = $this->dbClient->exec($strSql);
154 | $this->getPDOError();
155 | return $result;
156 | }
157 |
158 | /**
159 | * Delete 删除
160 | *
161 | * @param String $table 表名
162 | * @param String $where 条件
163 | * @param Boolean $debug
164 | * @return Int
165 | */
166 | public function delete($table, $where = '', $debug = false)
167 | {
168 | if ($where == '') {
169 | $this->outputError("'WHERE' is Null");
170 | } else {
171 | $strSql = "DELETE FROM `$table` WHERE $where";
172 | if ($debug === true) $this->debug($strSql);
173 | $result = $this->dbClient->exec($strSql);
174 | $this->getPDOError();
175 | return $result;
176 | }
177 | }
178 |
179 | /**
180 | * execSql 执行SQL语句,debug=>true可打印sql调试
181 | *
182 | * @param String $strSql
183 | * @param Boolean $debug
184 | * @return Int
185 | */
186 | public function execSql($strSql, $debug = false)
187 | {
188 | if ($debug === true) $this->debug($strSql);
189 | $result = $this->dbClient->exec($strSql);
190 | $this->getPDOError();
191 | return $result;
192 | }
193 |
194 | /**
195 | * 获取字段最大值
196 | *
197 | * @param string $table 表名
198 | * @param string $field_name 字段名
199 | * @param string $where 条件
200 | */
201 | public function getMaxValue($table, $field_name, $where = '', $debug = false)
202 | {
203 | $strSql = "SELECT MAX(" . $field_name . ") AS MAX_VALUE FROM $table";
204 | if ($where != '') $strSql .= " WHERE $where";
205 | if ($debug === true) $this->debug($strSql);
206 | $arrTemp = $this->query($strSql, 'Row');
207 | $maxValue = $arrTemp["MAX_VALUE"];
208 | if ($maxValue == "" || $maxValue == null) {
209 | $maxValue = 0;
210 | }
211 | return $maxValue;
212 | }
213 |
214 | /**
215 | * 获取指定列的数量
216 | *
217 | * @param string $table
218 | * @param string $field_name
219 | * @param string $where
220 | * @param bool $debug
221 | * @return int
222 | */
223 | public function getCount($table, $field_name, $where = '', $debug = false)
224 | {
225 | $strSql = "SELECT COUNT($field_name) AS NUM FROM $table";
226 | if ($where != '') $strSql .= " WHERE $where";
227 | if ($debug === true) $this->debug($strSql);
228 | $arrTemp = $this->query($strSql, 'Row');
229 | return $arrTemp['NUM'];
230 | }
231 |
232 | /**
233 | * 获取表引擎
234 | *
235 | * @param String $dbName 库名
236 | * @param String $tableName 表名
237 | * @param Boolean $debug
238 | * @return String
239 | */
240 | public function getTableEngine($dbName, $tableName)
241 | {
242 | $strSql = "SHOW TABLE STATUS FROM $dbName WHERE Name='" . $tableName . "'";
243 | $arrayTableInfo = $this->query($strSql);
244 | $this->getPDOError();
245 | return $arrayTableInfo[0]['Engine'];
246 | }
247 |
248 | //预处理执行
249 | public function prepareSql($sql = '')
250 | {
251 | return $this->dbClient->prepare($sql);
252 | }
253 |
254 | //执行预处理
255 | public function execute($presql)
256 | {
257 | return $this->dbClient->execute($presql);
258 | }
259 |
260 | /**
261 | * pdo属性设置
262 | */
263 | public function setAttribute($p, $d)
264 | {
265 | $this->dbClient->setAttribute($p, $d);
266 | }
267 |
268 | /**
269 | * beginTransaction 事务开始
270 | */
271 | public function beginTransaction()
272 | {
273 | $this->dbClient->beginTransaction();
274 | }
275 |
276 | /**
277 | * commit 事务提交
278 | */
279 | public function commit()
280 | {
281 | $this->dbClient->commit();
282 | }
283 |
284 | /**
285 | * rollback 事务回滚
286 | */
287 | public function rollback()
288 | {
289 | $this->dbClient->rollback();
290 | }
291 |
292 | /**
293 | * transaction 通过事务处理多条SQL语句
294 | * 调用前需通过getTableEngine判断表引擎是否支持事务
295 | *
296 | * @param array $arraySql
297 | * @return Boolean
298 | */
299 | public function execTransaction($arraySql)
300 | {
301 | $retval = 1;
302 | $this->beginTransaction();
303 | foreach ($arraySql as $strSql) {
304 | if ($this->execSql($strSql) == 0) $retval = 0;
305 | }
306 | if ($retval == 0) {
307 | $this->rollback();
308 | return false;
309 | } else {
310 | $this->commit();
311 | return true;
312 | }
313 | }
314 |
315 | /**
316 | * checkFields 检查指定字段是否在指定数据表中存在
317 | *
318 | * @param String $table
319 | * @param array $arrayField
320 | */
321 | private function checkFields($table, $arrayFields)
322 | {
323 | $fields = $this->getFields($table);
324 | foreach ($arrayFields as $key => $value) {
325 | if (!in_array($key, $fields)) {
326 | $this->outputError("Unknown column `$key` in field list.");
327 | }
328 | }
329 | }
330 |
331 | /**
332 | * getFields 获取指定数据表中的全部字段名
333 | *
334 | * @param String $table 表名
335 | * @return array
336 | */
337 | private function getFields($table)
338 | {
339 | $fields = array();
340 | $recordset = $this->dbClient->query("SHOW COLUMNS FROM $table");
341 | $this->getPDOError();
342 | $recordset->setFetchMode(PDO::FETCH_ASSOC);
343 | $result = $recordset->fetchAll();
344 | foreach ($result as $rows) {
345 | $fields[] = $rows['Field'];
346 | }
347 | return $fields;
348 | }
349 |
350 | /**
351 | * getPDOError 捕获PDO错误信息
352 | */
353 | private function getPDOError()
354 | {
355 | if ($this->dbClient->errorCode() != '00000') {
356 | $arrayError = $this->dbClient->errorInfo();
357 | $this->outputError($arrayError[2]);
358 | }
359 | }
360 |
361 | /**
362 | * debug
363 | *
364 | * @param mixed $debuginfo
365 | */
366 | private function debug($debuginfo)
367 | {
368 | var_dump($debuginfo);
369 | exit();
370 | }
371 |
372 | /**
373 | * 输出错误信息
374 | *
375 | * @param String $strErrMsg
376 | * @throws Exception
377 | */
378 | private function outputError($strErrMsg)
379 | {
380 | throw new Exception('MySQL Error: ' . $strErrMsg);
381 | }
382 |
383 | /**
384 | * destruct 关闭数据库连接
385 | */
386 | public function destruct()
387 | {
388 | $this->dbClient = null;
389 | }
390 |
391 | /**
392 | *PDO执行sql语句,返回改变的条数
393 | *如需调试可选用execSql($sql,true)
394 | */
395 | public function exec($sql = '')
396 | {
397 | return $this->dbClient->exec($sql);
398 | }
399 | }
400 |
401 |
402 |
--------------------------------------------------------------------------------
/Andromeda/core/TemplateEngine/Compile.class.php:
--------------------------------------------------------------------------------
1 | template = $template;
21 | $this->comfile = $compileFile;
22 | $this->content = file_get_contents($template);
23 | if($config['php_turn'] === false)
24 | {
25 | $this->T_P[] = "/<\?(=|php|)(.+?)\?>/is";
26 | $this->T_R[] = "<? \\1\\2? >";
27 | }
28 |
29 | //{$var}
30 | $this->T_P[] = "/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/";
31 |
32 | //{foreach $b}或者{loop $b}
33 | $this->T_P[] = "/\{(loop|foreach) \\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/i";
34 |
35 | //{[K|V]}
36 | $this->T_P[] = "/\{([K|V])\}/";
37 |
38 | //{/foreach}或者{\loop}或者{\if}
39 | $this->T_P[] = "/\{\/(loop|foreach|if)}/i";
40 |
41 | //{if (condition)}
42 | $this->T_P[] = "/\{if (.* ?)\}/i";
43 |
44 | //{(else if | elseif)}
45 | $this->T_P[] = "/\{(else if|elseif) (.* ?)\}/i";
46 |
47 | //{else}
48 | $this->T_P[] = "/\{else\}/i";
49 |
50 | //{#...# 或者 *...#,注释}
51 | $this->T_P[] = "/\{(\#|\*)(.* ?)(\#|\*)\}/";
52 |
53 | $this->T_R[] = "value['\\1']; ?>";
54 | $this->T_R[] = "value['\\2'] as \$K => \$V) { ?>";
55 | $this->T_R[] = "";
56 | $this->T_R[] = "";
57 | $this->T_R[] = "";
58 | $this->T_R[] = "";
59 | $this->T_R[] = "";
60 | $this->T_R[] = "";
61 | }
62 |
63 | public function compile()
64 | {
65 | $this->c_all();
66 | $this->c_staticFile();
67 | file_put_contents($this->comfile, $this->content);
68 | }
69 |
70 | public function c_all()
71 | {
72 | $this->content = preg_replace($this->T_P, $this->T_R, $this->content);
73 | }
74 |
75 | /**
76 | * 加入对JavaScript文件的解析
77 | * @return [type] [description]
78 | */
79 | public function c_staticFile()
80 | {
81 | $this->content = preg_replace('/\{\!(.* ?)\!\}/', '', $this->content);
82 | }
83 |
84 | public function __set($name, $value)
85 | {
86 | $this->$name = $value;
87 | }
88 |
89 | public function __get($name)
90 | {
91 | if(isset($this->$name))
92 | {
93 | return $this->$name;
94 | }
95 | else
96 | {
97 | return null;
98 | }
99 | }
100 | }
--------------------------------------------------------------------------------
/Andromeda/core/TemplateEngine/Template.class.php:
--------------------------------------------------------------------------------
1 | '.tpl', //模板的后缀
11 | 'templateDir' => "template/", //模板所在的文件夹
12 | 'compileDir' => "cache/", //编译后存放的目录
13 | 'cache_html' => false, //是否需要编译成静态的html文件
14 | 'suffix_cache' => '.html', //设置编译文件的后缀
15 | 'cache_time' => 7200, //设置多长时间自动更新
16 | 'php_turn' => true, //设置是否支持php原生代码
17 | 'debug' => false,
18 | );
19 |
20 | public $file; //模板文件名,不带路径
21 | public $debug = array(); //调试信息
22 | private $value = array(); //值栈
23 | private $compileTool; //编译器
24 | private $controlData = array();
25 | static private $instance = null; //模板类对象
26 |
27 | public function __construct($arrayConfig = array())
28 | {
29 | $this->debug['begin'] = microtime(true);
30 | $this->arrayConfig = array_merge($this->arrayConfig, $arrayConfig);
31 | //$this->getPath();
32 |
33 |
34 | if (!is_dir($this->arrayConfig['templateDir'])) {
35 | exit("template dir isn't found!");
36 | }
37 |
38 | if (!is_dir($this->arrayConfig['compileDir'])) {
39 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
40 | mkdir($this->arrayConfig['compileDir']);
41 | } else {
42 | mkdir($this->arrayConfig['compileDir'], 0770, true);
43 | }
44 | }
45 |
46 | }
47 |
48 | public function getPath()
49 | {
50 | $this->arrayConfig['templateDir'] = strstr(realpath($this->arrayConfig['templateDir']), '\\', '/') . '/';
51 | $this->arrayConfig['compileDir'] = strstr(realpath($this->arrayConfig['compileDir']), '\\', '/') . '/';
52 | }
53 |
54 | /**
55 | * 取得模板引擎的实例
56 | */
57 | public static function getInstance()
58 | {
59 | if (is_null(self::$instance)) {
60 | self::$instance = new Template();
61 | }
62 | return self::$instance;
63 | }
64 |
65 | /**
66 | * 单独设置引擎参数
67 | * 也支持一次性设置多个参数
68 | */
69 | public function setConfig($key, $value = null)
70 | {
71 | if (is_array($key)) {
72 | $this->arrayConfig = $key + $this->arrayConfig;
73 | } else {
74 | $this->arrayConfig[$key] = $value;
75 | }
76 | }
77 |
78 | /**
79 | * 获取当前模板引擎配置,仅供调试使用
80 | */
81 | public function getConfig($key = null)
82 | {
83 | if ($key && array_key_exists($key, $this->arrayConfig)) {
84 | return $this->arrayConfig[$key];
85 | } else {
86 | return $this->arrayConfig;
87 | }
88 | }
89 |
90 |
91 | /**
92 | * 注入单个变量
93 | */
94 | public function assign($key, $value)
95 | {
96 | $this->value[$key] = $value;
97 | }
98 |
99 | /**
100 | * 注入数组变量
101 | */
102 | public function assignArray($array)
103 | {
104 | if (is_array($array)) {
105 | foreach ($array as $k => $v) {
106 | $this->value[$k] = $v;
107 | }
108 | }
109 | }
110 |
111 | /**
112 | * 获取模板的位置
113 | * @return [type] [description]
114 | */
115 | public function path()
116 | {
117 | return $this->arrayConfig['templateDir'] . $this->file . $this->arrayConfig['suffix'];
118 | }
119 |
120 | /**
121 | * 判断配置文件是否要求缓存
122 | */
123 | public function needCache()
124 | {
125 | return $this->arrayConfig['cache_html'];
126 | }
127 |
128 | /**
129 | * 判断是否需要缓存
130 | */
131 | public function reCache($file)
132 | {
133 | $flag = false;
134 | $cacheFile = $this->arrayConfig['compileDir'] . md5($file) . $this->arrayConfig['suffix_cache'];
135 | if ($this->arrayConfig['cache_html'] === true) {
136 | //需要缓存
137 | $timeFlag = (time() - @filemtime($cacheFile)) < $this->arrayConfig['cache_time'] ? true : false;
138 | if (is_file($cacheFile) && filesize($cacheFile) > 1 && $timeFlag) {
139 | //缓存存在且未过期
140 | $flag = true;
141 | } else {
142 | $flag = false;
143 | }
144 | }
145 | return $flag;
146 | }
147 |
148 | /**
149 | * 展示模板
150 | */
151 | public function display($file)
152 | {
153 | $this->file = $file;
154 | echo $this->path()."\n";
155 | if (!is_file($this->path())) {
156 | exit('找不到对应的模板');
157 | }
158 | $compileFile = $this->arrayConfig['compileDir'] . md5($file) . '.php';
159 | $cacheFile = $this->arrayConfig['compileDir'] . md5($file) . $this->arrayConfig['suffix_cache'];
160 |
161 | if ($this->reCache($file) === false) {
162 | //如果需要缓存
163 | $this->debug['cached'] = 'false';
164 | $this->compileTool = new Compile($this->path(), $compileFile, $this->arrayConfig);
165 | if ($this->needCache()) {
166 | ob_start();
167 | }
168 | extract($this->value, EXTR_OVERWRITE);
169 | if (!is_file($compileFile) || fileatime($compileFile) < filemtime($this->path())) {
170 | $this->compileTool->value = $this->value;
171 | $this->compileTool->compile();
172 | include $compileFile;
173 | } else {
174 | include $compileFile;
175 | }
176 |
177 | if ($this->needCache()) {
178 | $message = ob_get_contents();
179 | file_put_contents($cacheFile, $message);
180 | }
181 | } else {
182 | readfile($cacheFile);
183 | $this->debug['cached'] = 'true';
184 | }
185 | $this->debug['spend'] = microtime(true) - $this->debug['begin'];
186 | $this->debug['count'] = count($this->value);
187 | $this->debug_info();
188 | }
189 |
190 | public function debug_info()
191 | {
192 | if ($this->arrayConfig['debug'] === true) {
193 | echo "
", '-------------------- debug_info--------------', "
";
194 | echo '程序运行日期:', date("Y-m-d h:i:s"), "
";
195 | echo '模板解析耗时:', $this->debug['spend'], '秒', "
";
196 | echo '模板包含标签数目:', $this->debug['count'], "
";
197 | echo '是否使用静态缓存:', $this->debug['cached'], "
";
198 | echo '模板引擎实例参数:', var_dump($this->getConfig());
199 | }
200 | }
201 |
202 | /**
203 | * 清楚缓存的html文件
204 | * @return [type] [description]
205 | */
206 | public function clean()
207 | {
208 | if ($path === null) {
209 | $path = $this->arrayConfig['compileDir'];
210 | $path = glob($path . '* ' . $this->arrayConfig['suffix_cache']);
211 | } else {
212 | $path = $this->arrayConfig['compileDir'] . md5($path) . $this->arrayConfig['suffix_cache'];
213 | }
214 | foreach ((array)$path as $v) {
215 | unlink($v);
216 | }
217 | }
218 | }
--------------------------------------------------------------------------------
/Andromeda/core/TemplateEngine/cache/aa08769cdcb26674c6706093503ff0a3.php:
--------------------------------------------------------------------------------
1 |
2 | value['data']; ?>,value['person']; ?>
3 |
4 | value['b'] as $K => $V) { ?>
5 |
6 |
7 | ";
9 | ?>
10 |
11 | 成功
12 |
13 | 失败
14 |
15 | 我最厉害value['data']; ?>
16 |
17 |
--------------------------------------------------------------------------------
/Andromeda/core/TemplateEngine/template/member.tpl:
--------------------------------------------------------------------------------
1 | {!bootstrap.js!}
2 | {$data},{$person}
3 |
4 | {foreach $b}
5 | - {V}
{/foreach}
6 |
7 | ";
9 | ?>
10 | {if $data === 'a'}
11 | 成功
12 | {elseif $data === 'b'}
13 | 失败
14 | {else}
15 | 我最厉害{$data}
16 | {/if}
17 | {#这里是注释#}
--------------------------------------------------------------------------------
/Andromeda/core/TemplateEngine/test.php:
--------------------------------------------------------------------------------
1 | true]);
4 | $tpl->assign('data', 'hello world');
5 | $tpl->assign('person', 'htGod');
6 | $tpl->assign('data1', 3);
7 | $arr = array(1,2,3,4,'5',6);
8 | $tpl->assign('b', $arr);
9 | $tpl->display('member');
10 |
--------------------------------------------------------------------------------
/Andromeda/core/Util.class.php:
--------------------------------------------------------------------------------
1 | $param)
31 | {
32 | $tmp[] = $k.'='.$param;
33 | }
34 | $params = implode('&',$tmp);
35 | return $params;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Andromeda/core/View.class.php:
--------------------------------------------------------------------------------
1 | render = $filePath;
36 |
37 | }
38 | }
39 |
40 | /**
41 | * 渲染变量
42 | * assign variable
43 | * @param $variable
44 | * @param string $value
45 | */
46 | public function assign($variable, $value = '')
47 | {
48 | if (is_array($variable)) {
49 |
50 | $this->data = array_merge($this->data, $variable);
51 | } else {
52 |
53 | $this->data[$variable] = $value;
54 | }
55 |
56 |
57 | }
58 |
59 | /**
60 | * 显示模板
61 | * display tempalte
62 | * @param $template
63 | */
64 | public function display($template)
65 | {
66 | $data = $this->data;
67 |
68 | $filePath = $template . '.html'; //todo 加配置支持其他后缀的模板
69 | if (file_exists($filePath)) {
70 |
71 | $this->render = $filePath;
72 |
73 | }
74 |
75 | if (isset($this)) {
76 | include($this->render);
77 | }
78 |
79 | }
80 |
81 |
82 | }
--------------------------------------------------------------------------------
/Andromeda/core/log/driver/File.php:
--------------------------------------------------------------------------------
1 | 'mysql',
12 | 'DB_HOST' => 'mysql',
13 | 'DB_NAME' => 'andromeda',
14 | 'DB_USER' => 'root',
15 | 'DB_PASSWORD'=> '123456',
16 | 'DB_PORT' => '3306',
17 | 'DB_CHARSET' => 'utf-8',
18 | 'DB_PREFIX' => ''
19 |
20 | );
21 |
--------------------------------------------------------------------------------
/App/Config/loader.php:
--------------------------------------------------------------------------------
1 | registerDirs(
18 | [
19 | //目录
20 | $config->application->controllersDir,
21 | $config->application->modelsDir
22 | ]
23 | )->register();
24 | */
25 |
26 |
--------------------------------------------------------------------------------
/App/Config/router.php:
--------------------------------------------------------------------------------
1 | setShared("singletonWriter", function () use ($di, $config) {
17 | $singletonWriter = SingletonWriter::getInstance($di);
18 | return $singletonWriter;
19 | });
20 |
21 |
22 | //setShared 设置共享实例
23 | $di->setShared("logger", function () use ($di) {
24 | $logger = new Log();
25 | return $logger;
26 | });
27 |
28 | //set 设置独享实例,每次调用都会new一个新的对象
29 | $di->set("writer", function () use ($di, $config) {
30 | $write = new Writer($di);
31 | return $write;
32 | });
33 |
34 |
--------------------------------------------------------------------------------
/App/Controllers/Home/BaseController.class.php:
--------------------------------------------------------------------------------
1 | writer->hello();
20 | $this->writer->hello();
21 | $this->writer->hello();
22 | Log::write("hehehehe");
23 | $this->singletonWriter->hello();
24 | $this->singletonWriter->hello();
25 | $this->singletonWriter->hello();
26 | $this->singletonWriter::staticHello();
27 |
28 |
29 | }
30 |
31 | public function var()
32 | {
33 | Log::ERR("访问var");
34 | $this->assign('var', "foobar");
35 | $this->display('var');
36 |
37 | }
38 |
39 | public function getUsers()
40 | {
41 | Log::ERR("访问getUser");
42 | $userModel = new UserModel("user");
43 | $result = $userModel->getUsers();
44 | $this->assign('page', 'home/getuser');
45 | $this->assign('result', $result);
46 | $this->display('getUser');
47 |
48 | }
49 |
50 | /**
51 | * index.php?p=home&c=Index&a=paramTest&p1=2&p3=3
52 | * @param $p1
53 | * @param int $p2
54 | * @param $p3
55 | */
56 | public function paramTest($p1, $p2, $p3=22)
57 | {
58 | Log::write("eeeee");
59 | var_dump($p1);
60 | var_dump($p2);
61 | var_dump($p3);
62 |
63 | }
64 |
65 | public function testTpl()
66 | {
67 | $tpl = new Template();
68 | $tpl->assign('data', 'hello world');
69 | $tpl->assign('person', 'htGod');
70 | $tpl->assign('data1', 3);
71 | $arr = array(1, 2, 3, 4, '5', 6);
72 | $tpl->assign('b', $arr);
73 | $tpl->display('home/member');
74 | }
75 |
76 |
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/App/Models/UserModel.class.php:
--------------------------------------------------------------------------------
1 | table}";
9 | $user=$this->db->query($sql);
10 | return $user;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/App/Views/admin/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | miniFramework
5 |
6 |
7 | hello this is a miniFramework!
8 |
9 |
10 |
--------------------------------------------------------------------------------
/App/Views/home/getUser.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Andromeda php framework
5 |
6 |
7 | hello this is a Andromeda php framework!
8 | now you are visiting the =$data['page']?>
9 |
10 |
11 | result prase example:
12 |
13 | ";
17 | echo 'user_name:'.$v['name']."
";
18 | }
19 |
20 | ?>
21 |
22 |
--------------------------------------------------------------------------------
/App/Views/home/getUserById.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Andromeda php framework
5 |
6 |
7 | Hello this is Andromeda php framework!
8 | now you are visiting the =$data['page']?>
9 |
10 |
11 |
12 |
13 |
14 |
15 | param prase example:
16 |
17 | id==$data['id']?>
18 | limit==$data['limit']?>
19 |
20 |
21 |
--------------------------------------------------------------------------------
/App/Views/home/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Andromeda php framework
5 |
6 |
7 | Hello this is Andromeda php framework!
8 | you are visiting the =$data['page'];?> page!
9 |
10 |
--------------------------------------------------------------------------------
/App/Views/home/var.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Andromeda php framework
5 |
6 |
7 | Hello this is Andromeda php framework!
8 |
9 |
10 |
11 |
12 | var==$data["var"];?>
13 |
16 |
17 |
--------------------------------------------------------------------------------
/Doc/实现action的参数获取.md:
--------------------------------------------------------------------------------
1 | ###实现从url或者post参数中取出调用action的参数
2 |
3 | 示例代码,取自ThinkPHP3.2.3
4 |
5 | ```
6 | public static function invokeAction($module,$action){
7 | if(!preg_match('/^[A-Za-z](\w)*$/',$action)){
8 | // 非法操作
9 | throw new \ReflectionException();
10 | }
11 | //执行当前操作
12 | $method = new \ReflectionMethod($module, $action);
13 | if($method->isPublic() && !$method->isStatic()) {
14 | $class = new \ReflectionClass($module);
15 | // 前置操作
16 | if($class->hasMethod('_before_'.$action)) {
17 | $before = $class->getMethod('_before_'.$action);
18 | if($before->isPublic()) {
19 | $before->invoke($module);
20 | }
21 | }
22 | // URL参数绑定检测
23 | if($method->getNumberOfParameters()>0 && C('URL_PARAMS_BIND')){
24 | switch($_SERVER['REQUEST_METHOD']) {
25 | case 'POST':
26 | $vars = array_merge($_GET,$_POST);
27 | break;
28 | case 'PUT':
29 | parse_str(file_get_contents('php://input'), $vars);
30 | break;
31 | default:
32 | $vars = $_GET;
33 | }
34 | $params = $method->getParameters();
35 | $paramsBindType = C('URL_PARAMS_BIND_TYPE');
36 | foreach ($params as $param){
37 | $name = $param->getName();
38 | if( 1 == $paramsBindType && !empty($vars) ){
39 | $args[] = array_shift($vars);
40 | }elseif( 0 == $paramsBindType && isset($vars[$name])){
41 | $args[] = $vars[$name];
42 | }elseif($param->isDefaultValueAvailable()){
43 | $args[] = $param->getDefaultValue();
44 | }else{
45 | E(L('_PARAM_ERROR_').':'.$name);
46 | }
47 | }
48 | // 开启绑定参数过滤机制
49 | if(C('URL_PARAMS_SAFE')){
50 | $filters = C('URL_PARAMS_FILTER')?:C('DEFAULT_FILTER');
51 | if($filters) {
52 | $filters = explode(',',$filters);
53 | foreach($filters as $filter){
54 | $args = array_map_recursive($filter,$args); // 参数过滤
55 | }
56 | }
57 | }
58 | array_walk_recursive($args,'think_filter');
59 | $method->invokeArgs($module,$args);
60 | }else{
61 | $method->invoke($module);
62 | }
63 | // 后置操作
64 | if($class->hasMethod('_after_'.$action)) {
65 | $after = $class->getMethod('_after_'.$action);
66 | if($after->isPublic()) {
67 | $after->invoke($module);
68 | }
69 | }
70 | }else{
71 | // 操作方法不是Public 抛出异常
72 | throw new \ReflectionException();
73 | }
74 | }
75 |
76 | ```
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Jimmy Lee
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Public/README.md:
--------------------------------------------------------------------------------
1 | #静态文件目录
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | Andromeda is a php framework,apply Di,Ioc.
4 |
5 | # License
6 | [MIT](LICENSE)
7 |
8 | # Quick start
9 |
10 | ```shell
11 | cd Andromeda
12 | composer install
13 | # start server
14 | php -S localhost:8000
15 | # curl or using browser
16 | http://localhost:8000/index.php?p=home&c=index&a=index
17 | http://localhost:8000/index.php?p=home&c=index&a=paramTest&p1=1&p3=2
18 | ```
19 |
20 |
21 | # Todo
22 |
23 | ## Cache driver
24 | - Redis
25 | - Memcached
26 | - File
27 |
28 | ## Database driver
29 | - MySQL
30 |
31 | ## Log driver
32 | - File
33 | - Elastic search
34 |
35 |
36 | # Dev log
37 | - 2024-06-11:升级依赖包;更新README
38 | - 2017-10-16:实现获取post与get参数结合
39 | - 2017-10-11:准备实现获取post参数
40 | - 2017-10-11:实现获取action参数,以及必填非必填参数判断
41 | - 2017-08-03:下一步实现获取action的参数,利用反射实现
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name":"jimersylee/andromeda",
3 | "description":"PHP framework",
4 | "type":"framework",
5 | "keywords":[
6 | "PHP","Framework","PHP Framework"
7 | ],
8 | "require":{
9 | "php":">=8.0.0",
10 | "filp/whoops": "2.*"
11 | }
12 | }
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "bbc7809637a120d23d46e0947f54205a",
8 | "packages": [
9 | {
10 | "name": "filp/whoops",
11 | "version": "2.16.0",
12 | "dist": {
13 | "type": "zip",
14 | "url": "https://mirrors.tencent.com/repository/composer/filp/whoops/2.16.0/filp-whoops-2.16.0.zip",
15 | "reference": "befcdc0e5dce67252aa6322d82424be928214fa2",
16 | "shasum": ""
17 | },
18 | "require": {
19 | "php": "^7.1 || ^8.0",
20 | "psr/log": "^1.0.1 || ^2.0 || ^3.0"
21 | },
22 | "require-dev": {
23 | "mockery/mockery": "^1.0",
24 | "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3",
25 | "symfony/var-dumper": "^4.0 || ^5.0"
26 | },
27 | "suggest": {
28 | "symfony/var-dumper": "Pretty print complex values better with var-dumper available",
29 | "whoops/soap": "Formats errors as SOAP responses"
30 | },
31 | "type": "library",
32 | "extra": {
33 | "branch-alias": {
34 | "dev-master": "2.7-dev"
35 | }
36 | },
37 | "autoload": {
38 | "psr-4": {
39 | "Whoops\\": "src/Whoops/"
40 | }
41 | },
42 | "license": [
43 | "MIT"
44 | ],
45 | "authors": [
46 | {
47 | "name": "Filipe Dobreira",
48 | "homepage": "https://github.com/filp",
49 | "role": "Developer"
50 | }
51 | ],
52 | "description": "php error handling for cool kids",
53 | "homepage": "https://filp.github.io/whoops/",
54 | "keywords": [
55 | "error",
56 | "exception",
57 | "handling",
58 | "library",
59 | "throwable",
60 | "whoops"
61 | ],
62 | "time": "2024-09-25T12:00:00+00:00"
63 | },
64 | {
65 | "name": "psr/log",
66 | "version": "1.1.4",
67 | "source": {
68 | "type": "git",
69 | "url": "https://github.com/php-fig/log.git",
70 | "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
71 | },
72 | "dist": {
73 | "type": "zip",
74 | "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
75 | "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
76 | "shasum": "",
77 | "mirrors": [
78 | {
79 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
80 | "preferred": true
81 | }
82 | ]
83 | },
84 | "require": {
85 | "php": ">=5.3.0"
86 | },
87 | "type": "library",
88 | "extra": {
89 | "branch-alias": {
90 | "dev-master": "1.1.x-dev"
91 | }
92 | },
93 | "autoload": {
94 | "psr-4": {
95 | "Psr\\Log\\": "Psr/Log/"
96 | }
97 | },
98 | "notification-url": "https://packagist.org/downloads/",
99 | "license": [
100 | "MIT"
101 | ],
102 | "authors": [
103 | {
104 | "name": "PHP-FIG",
105 | "homepage": "https://www.php-fig.org/"
106 | }
107 | ],
108 | "description": "Common interface for logging libraries",
109 | "homepage": "https://github.com/php-fig/log",
110 | "keywords": [
111 | "log",
112 | "psr",
113 | "psr-3"
114 | ],
115 | "support": {
116 | "source": "https://github.com/php-fig/log/tree/1.1.4"
117 | },
118 | "time": "2021-05-03T11:20:27+00:00"
119 | }
120 | ],
121 | "packages-dev": [],
122 | "aliases": [],
123 | "minimum-stability": "stable",
124 | "stability-flags": {},
125 | "prefer-stable": false,
126 | "prefer-lowest": false,
127 | "platform": {
128 | "php": ">=8.0.0"
129 | },
130 | "platform-dev": {},
131 | "plugin-api-version": "2.6.0"
132 | }
133 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | pushHandler(new PrettyPageHandler());
18 | $whoops->register();
19 |
20 |
21 | //分隔符 window与linux不同
22 | define("DS", DIRECTORY_SEPARATOR);
23 |
24 | define('ROOT', __DIR__ . DS);
25 |
26 | //echo BASE_PATH;
27 |
28 | define('APP_PATH', ROOT . 'App' . DS);//定义app目录
29 | //echo APP_PATH;
30 |
31 | // 环境常量
32 | define('IS_CLI', PHP_SAPI == 'cli' ? true : false);
33 |
34 |
35 | include ROOT . "/Andromeda/DiInterface.php";
36 | include ROOT . "/Andromeda/Di.php";
37 | include ROOT . "/Andromeda/Di/FactoryDefault.php";
38 | include ROOT . "/Andromeda/Di/InjectionAwareInterface.php";
39 | include ROOT . "/Andromeda/Di/Injectable.php";
40 |
41 | include ROOT . "/Andromeda/App.php";
42 | include ROOT . "/Andromeda/Andromeda.php";
43 | include ROOT . "/Andromeda/Request.php";
44 | include ROOT . "/Andromeda/Exception.php";
45 |
46 |
47 | //容器
48 | $di = new FactoryDefault();
49 |
50 |
51 | require_once "Andromeda/Andromeda.php";
52 | include ROOT . "/Andromeda/Mvc/Controller.php";
53 |
54 |
55 | //载入路由配置 handle routes
56 |
57 | include APP_PATH . "Config/router.php";
58 |
59 | //载入服务配置 read service
60 | include APP_PATH . "Config/service.php";
61 |
62 | //载入自动加载配置
63 | include APP_PATH . "Config/loader.php";
64 |
65 | //应用(组件)
66 | $app = new App($di);
67 |
68 | Andromeda::run($di);
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/test/di/Di.php:
--------------------------------------------------------------------------------
1 | _instances[$name])) {
19 | return $this->_instances[$name];
20 | }
21 | //检测有没有注册该服务
22 | if (!isset($this->_bindings[$name])) {
23 | return null;
24 | }
25 | $concrete = $this->_bindings[$name]['class'];//对象具体注册内容
26 | $obj = null;
27 | //匿名函数方式
28 | if ($concrete instanceof Closure) {
29 | $obj = call_user_func_array($concrete, $params);
30 | } //字符串方式
31 | elseif (is_string($concrete)) {
32 | if (empty($params)) {
33 | $obj = new $concrete;
34 | } else { //带参数的类实例化,使用反射
35 | $class = new ReflectionClass($concrete);
36 | $obj = $class->newInstanceArgs($params);
37 | }
38 | } //如果是共享服务,则写入_instances列表,下次直接取回
39 | if ($this->_bindings[$name]['shared'] == true && $obj) {
40 | $this->_instances[$name] = $obj;
41 | }
42 | return $obj;
43 | }
44 |
45 | //检测是否已经绑定
46 | public function has($name)
47 | {
48 | return isset($this->_bindings[$name]) or isset($this->_instances[$name]);
49 | }
50 |
51 | //卸载服务
52 | public function remove($name)
53 | {
54 | unset($this->_bindings[$name], $this->_instances[$name]);
55 | }
56 |
57 | //设置服务
58 | public function set($name, $class)
59 | {
60 | $this->_registerService($name, $class);
61 | }
62 |
63 | //设置共享服务
64 | public function setShared($name, $class)
65 | {
66 | $this->_registerService($name, $class, true);
67 | }
68 |
69 | //注册服务
70 | private function _registerService($name, $class, $shared = false)
71 | {
72 | $this->remove($name);
73 | if (!($class instanceof Closure) && is_object($class)) {
74 | $this->_instances[$name] = $class;
75 | } else {
76 | $this->_bindings[$name] = array("class" => $class, "shared" => $shared);
77 | }
78 | }
79 |
80 | //ArrayAccess接口,检测服务是否存在
81 | public function offsetExists($offset)
82 | {
83 | return $this->has($offset);
84 | }
85 |
86 | //ArrayAccess接口,以$di[$name]方式获取服务
87 | public function offsetGet($offset)
88 | {
89 | return $this->get($offset);
90 | }
91 |
92 | //ArrayAccess接口,以$di[$name]=$value方式注册服务,非共享
93 | public function offsetSet($offset, $value)
94 | {
95 | return $this->set($offset, $value);
96 | }
97 |
98 | //ArrayAccess接口,以unset($di[$name])方式卸载服务
99 | public function offsetUnset($offset)
100 | {
101 | return $this->remove($offset);
102 | }
103 | }
--------------------------------------------------------------------------------
/test/di/test.php:
--------------------------------------------------------------------------------
1 | name = $name;
24 | }
25 | }
26 |
27 | include "Di.php";
28 | $di = new Di();
29 | //匿名函数方式注册一个名为a1的服务
30 | $di->setShared('a1',function($name=""){
31 | return new A($name);
32 | });
33 | //直接以类名方式注册
34 | $di->set('a2','A');
35 | //直接传入实例化的对象
36 | $di->set('a3',new A("小唐"));
37 |
38 | $a1 = $di->get('a1',array("小李"));
39 | echo $a1->name."
";//小李
40 | $a1_1 = $di->get('a1',array("小王"));
41 | echo $a1->name."
";//小李
42 | echo $a1_1->name."
";//小李
43 |
44 | $a2 = $di->get('a2',array("小张"));
45 | echo $a2->name."
";//小张
46 | $a2_1 = $di->get('a2',array("小徐"));
47 | echo $a2->name."
";//小张
48 | echo $a2_1->name."
";//小徐
49 |
50 | $a3 = $di['a3'];//可以直接通过数组方式获取服务对象
51 | echo $a3->name."
";//小唐
--------------------------------------------------------------------------------
/test/namespace/NameSpaceClass.php:
--------------------------------------------------------------------------------
1 |