异常类规范 增加异常类 改进Query类的value和column的缓存冲突问题

This commit is contained in:
thinkphp
2016-06-12 16:35:42 +08:00
parent 659900ab91
commit b10635e22e
33 changed files with 236 additions and 79 deletions

View File

@@ -112,7 +112,7 @@ class App
$data = $dispatch['response'];
break;
default:
throw new Exception('dispatch type not support', 10008);
throw new \InvalidArgumentException('dispatch type not support');
}
} catch (HttpResponseException $exception) {
$data = $exception->getResponse();
@@ -200,7 +200,7 @@ class App
} elseif ($param->isDefaultValueAvailable()) {
$args[] = $param->getDefaultValue();
} else {
throw new Exception('method param miss:' . $name, 10004);
throw new \InvalidArgumentException('method param miss:' . $name);
}
}
// 全局过滤
@@ -261,7 +261,7 @@ class App
// 执行操作
if (!preg_match('/^[A-Za-z](\/|\.|\w)*$/', $controller)) {
// 安全检测
throw new Exception('illegal controller name:' . $controller, 10000);
throw new \InvalidArgumentException('illegal controller name:' . $controller);
}
// 设置当前请求的模块、控制器、操作
@@ -361,7 +361,7 @@ class App
* @param \think\Request $request
* @param array $config
* @return array
* @throws Exception
* @throws HttpException
*/
public static function route($request, array $config)
{
@@ -384,7 +384,7 @@ class App
$result = Route::check($request, $path, $depr, !IS_CLI ? $config['url_domain_deploy'] : false);
if (APP_ROUTE_MUST && false === $result && $config['url_route_must']) {
// 路由无效
throw new HttpException(404, 'Not Found');
throw new HttpException(404, 'Route Not Found');
}
}
if (false === $result) {

View File

@@ -14,6 +14,7 @@ namespace think;
\think\Loader::import('controller/Jump', TRAIT_PATH, EXT);
use think\Exception;
use think\Exception\ValidateException;
use think\Request;
use think\View;
@@ -190,7 +191,7 @@ class Controller
if (!$v->check($data)) {
if ($this->failException) {
throw new Exception($v->getError());
throw new ValidateException($v->getError());
} else {
return $v->getError();
}

View File

@@ -11,10 +11,6 @@
namespace think;
/**
* ThinkPHP核心异常类
* 所有系统异常必须继承该类
*/
class Exception extends \Exception
{

View File

@@ -466,7 +466,7 @@ class Input
if (is_scalar($data)) {
$data = (string) $data;
} else {
throw new Exception('变量类型不允许:' . gettype($data));
throw new \InvalidArgumentException('变量类型不允许:' . gettype($data));
}
}
}

View File

@@ -12,6 +12,7 @@
namespace think;
use think\exception\HttpException;
use think\exception\ClassNotFoundException;
use think\Request;
class Loader
@@ -269,6 +270,7 @@ class Loader
* @param bool $appendSuffix 是否添加类名后缀
* @param string $common 公共模块名
* @return Object
* @throws ClassNotFoundException
*/
public static function model($name = '', $layer = 'model', $appendSuffix = false, $common = 'common')
{
@@ -289,7 +291,7 @@ class Loader
if (class_exists($class)) {
$model = new $class();
} else {
throw new Exception('class [ ' . $class . ' ] not exists', 10001);
throw new ClassNotFoundException('class [ ' . $class . ' ] not exists');
}
}
$_model[$name . $layer] = $model;
@@ -303,6 +305,7 @@ class Loader
* @param bool $appendSuffix 是否添加类名后缀
* @param string $empty 空控制器名称
* @return Object|false
* @throws ClassNotFoundException
*/
public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '')
{
@@ -324,7 +327,7 @@ class Loader
} elseif ($empty && class_exists($emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix))) {
return new $emptyClass(Request::instance());
} else {
throw new HttpException(404, 'class [ ' . $class . ' ] not exists');
throw new ClassNotFoundException('class [ ' . $class . ' ] not exists');
}
}
@@ -335,6 +338,7 @@ class Loader
* @param bool $appendSuffix 是否添加类名后缀
* @param string $common 公共模块名
* @return Object|false
* @throws ClassNotFoundException
*/
public static function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common')
{
@@ -360,7 +364,7 @@ class Loader
if (class_exists($class)) {
$validate = new $class;
} else {
throw new Exception('class [ ' . $class . ' ] not exists', 10001);
throw new ClassNotFoundException('class [ ' . $class . ' ] not exists');
}
}
$_instance[$name . $layer] = $validate;
@@ -409,7 +413,7 @@ class Loader
* @param string $method 类的静态方法名
*
* @return mixed
* @throws Exception
* @throws ClassNotFoundException
*/
public static function instance($class, $method = '')
{
@@ -424,7 +428,7 @@ class Loader
$_instance[$identify] = $o;
}
} else {
throw new Exception('class not exist :' . $class, 10007);
throw new ClassNotFoundException('class not exist :' . $class);
}
}
return $_instance[$identify];

View File

@@ -15,6 +15,7 @@ use think\Cache;
use think\Db;
use think\db\Query;
use think\Exception;
use think\Exception\ValidateException;
use think\Loader;
use think\model\Relation;
use think\paginator\Collection as PaginatorCollection;
@@ -773,7 +774,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
if (!$validate->check($data)) {
$this->error = $validate->getError();
if ($this->failException) {
throw new Exception($this->error);
throw new ValidateException($this->error);
} else {
return false;
}

View File

@@ -143,7 +143,7 @@ abstract class Paginator
public function total()
{
if ($this->simple) {
throw new \Exception('简洁模式下不能获取数据总数');
throw new \DomainException('简洁模式下不能获取数据总数');
}
return $this->total;
}
@@ -161,7 +161,7 @@ abstract class Paginator
public function lastPage()
{
if ($this->simple) {
throw new \Exception('简洁模式下不能获取最后一页');
throw new \DomainException('简洁模式下不能获取最后一页');
}
return $this->lastPage;
}

View File

@@ -100,7 +100,7 @@ class Response
* @access public
* @param mixed $data 数据
* @return mixed
* @throws Exception
* @throws \InvalidArgumentException
*/
public function send($data = null)
{
@@ -137,7 +137,7 @@ class Response
if (is_scalar($data)) {
echo $data;
} elseif (!is_null($data)) {
throw new Exception('不支持的数据类型输出:' . gettype($data));
throw new \InvalidArgumentException('不支持的数据类型输出:' . gettype($data));
}
if (function_exists('fastcgi_finish_request')) {

View File

@@ -11,6 +11,8 @@
namespace think;
use think\exception\ClassNotFoundException;
class Session
{
@@ -92,7 +94,7 @@ class Session
// 检查驱动类
if (!class_exists($class) || !session_set_save_handler(new $class($config))) {
throw new \think\Exception('error session handler', 11700);
throw new ClassNotFoundException('error session handler');
}
}
if ($isDoStart) {

View File

@@ -11,6 +11,8 @@
namespace think;
use think\exception\TemplateNotFoundException;
/**
* ThinkPHP分离出来的模板引擎
* 支持XML标签和普通标签的模板解析
@@ -1066,7 +1068,7 @@ class Template
$this->includeFile[$template] = filemtime($template);
return $template;
} else {
throw new Exception('template not exist:' . $template, 10700);
throw new TemplateNotFoundException('template not exist:' . $template);
}
}

View File

@@ -1115,7 +1115,7 @@ class Validate
if (method_exists($class, $method)) {
return call_user_func_array([$class, $method], $params);
} else {
throw new Exception(__CLASS__ . ':' . $method . ' method not exist');
throw new \BadMethodCallException(__CLASS__ . ':' . $method . ' method not exist');
}
}
}

View File

@@ -36,7 +36,7 @@ class Apc
public function __construct($options = [])
{
if (!function_exists('apc_cache_info')) {
throw new Exception('_NOT_SUPPERT_:Apc');
throw new \BadFunctionCallException('not support Apc');
}
if (!empty($options)) {
$this->options = array_merge($this->options, $options);

View File

@@ -30,12 +30,12 @@ class Memcache
* 架构函数
* @param array $options 缓存参数
* @access public
* @throws Exception
* @throws \BadFunctionCallException
*/
public function __construct($options = [])
{
if (!extension_loaded('memcache')) {
throw new Exception('_NOT_SUPPERT_:memcache');
throw new \BadFunctionCallException('not support memcache');
}
if (!empty($options)) {
$this->options = array_merge($this->options, $options);

View File

@@ -33,7 +33,7 @@ class Memcached
public function __construct($options = [])
{
if (!extension_loaded('memcached')) {
throw new Exception('_NOT_SUPPERT_:memcached');
throw new \BadFunctionCallException('not support memcached');
}
if (!empty($options)) {
$this->options = array_merge($this->options, $options);

View File

@@ -42,7 +42,7 @@ class Redis
public function __construct($options = [])
{
if (!extension_loaded('redis')) {
throw new Exception('_NOT_SUPPERT_:redis');
throw new \BadFunctionCallException('not support redis');
}
if (!empty($options)) {
$this->options = array_merge($this->options, $options);

View File

@@ -83,7 +83,7 @@ class Redisd
public function __construct($options = [])
{
if (!extension_loaded('redis')) {
throw new Exception('_NOT_SUPPERT_:redis');
throw new \BadFunctionCallException('not support redis');
}
$this->options = $options = array_merge($this->options, $options);

View File

@@ -38,7 +38,7 @@ class Sae
public function __construct($options = [])
{
if (!function_exists('memcache_init')) {
throw new Exception('请在SAE平台上运行代码。');
throw new \BadFunctionCallException('请在SAE平台上运行代码。');
}
$this->handler = memcache_init();
if (!$this->handler) {

View File

@@ -32,13 +32,13 @@ class Sqlite implements CacheInterface
/**
* 架构函数
* @param array $options 缓存参数
* @throws Exception
* @throws \BadFunctionCallException
* @access public
*/
public function __construct($options = [])
{
if (!extension_loaded('sqlite')) {
throw new Exception('_NOT_SUPPERT_:sqlite');
throw new \BadFunctionCallException('not support sqlite');
}
if (!empty($options)) {
$this->options = array_merge($this->options, $options);

View File

@@ -34,7 +34,7 @@ class Wincache
public function __construct($options = [])
{
if (!function_exists('wincache_ucache_info')) {
throw new Exception('_NOT_SUPPERT_:WinCache');
throw new \BadFunctionCallException('not support WinCache');
}
if (!empty($options)) {
$this->options = array_merge($this->options, $options);

View File

@@ -29,12 +29,12 @@ class Xcache
* 架构函数
* @param array $options 缓存参数
* @access public
* @throws Exception
* @throws \BadFunctionCallException
*/
public function __construct($options = [])
{
if (!function_exists('xcache_info')) {
throw new Exception('_NOT_SUPPERT_:Xcache');
throw new \BadFunctionCallException('not support Xcache');
}
if (!empty($options)) {
$this->options = array_merge($this->options, $options);

View File

@@ -18,8 +18,8 @@ use think\Db;
use think\db\Query;
use think\Debug;
use think\Exception;
use think\exception\DbBindParamException;
use think\exception\PDOException;
use think\db\exception\BindParamException;
use think\Log;
abstract class Connection
@@ -326,7 +326,7 @@ abstract class Connection
* @param boolean $master 是否在主服务器读操作
* @param bool|string $class 指定返回的数据集对象
* @return mixed
* @throws DbBindParamException
* @throws BindParamException
* @throws PDOException
*/
public function query($sql, $bind = [], $fetch = false, $master = false, $class = false)
@@ -375,7 +375,7 @@ abstract class Connection
* @param boolean $getLastInsID 是否获取自增ID
* @param string $sequence 自增序列名
* @return int
* @throws DbBindParamException
* @throws BindParamException
* @throws PDOException
*/
public function execute($sql, $bind = [], $fetch = false, $getLastInsID = false, $sequence = null)
@@ -465,7 +465,7 @@ abstract class Connection
$result = $this->PDOStatement->bindValue($param, $val);
}
if (!$result) {
throw new DbBindParamException(
throw new BindParamException(
"Error occurred when binding parameters '{$param}'",
$this->config,
$this->queryStr,

View File

@@ -9,7 +9,7 @@
// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>
// +----------------------------------------------------------------------
namespace think\exception;
namespace think\db;
use think\Exception;

View File

@@ -21,6 +21,8 @@ use think\db\Connection;
use think\Exception;
use think\exception\DbException;
use think\exception\PDOException;
use think\db\exception\ModelNotFoundException;
use think\db\exception\DataNotFoundException;
use think\Loader;
use think\Model;
use think\model\Relation;
@@ -379,6 +381,9 @@ class Query
if (!empty($this->options['cache'])) {
// 判断查询缓存
$cache = $this->options['cache'];
if (empty($this->options['table'])) {
$this->options['table'] = $this->getTable();
}
$key = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options));
$result = Cache::get($key);
}
@@ -412,6 +417,9 @@ class Query
if (!empty($this->options['cache'])) {
// 判断查询缓存
$cache = $this->options['cache'];
if (empty($this->options['table'])) {
$this->options['table'] = $this->getTable();
}
$guid = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options));
$result = Cache::get($guid);
}
@@ -1775,7 +1783,11 @@ class Query
}
}
} elseif (!empty($options['fail'])) {
throw new DbException('Data not Found', $options, $sql);
if(!empty($this->model)){
throw new ModelNotFoundException('Data not Found', $this->model, $options);
}else{
throw new DataNotFoundException('Data not Found', $options['table'], $options);
}
} else {
$data = false;
}

View File

@@ -9,14 +9,14 @@
// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>
// +----------------------------------------------------------------------
namespace think\exception;
namespace think\db\exception;
use think\exception\DbException;
use think\db\Exception;
/**
* PDO参数绑定异常
*/
class DbBindParamException extends DbException
class BindParamException extends Exception
{
/**

View File

@@ -0,0 +1,35 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>
// +----------------------------------------------------------------------
namespace think\db\exception;
use think\db\DbException;
class DataNotFoundException extends DbException
{
protected $table;
/**
* DbException constructor.
* @param string $message
* @param string $table
* @param array $config
*/
public function __construct($message, $table = '', Array $config = [])
{
$this->message = $message;
$this->table = $table;
$this->setData('Database Config', $config);
}
}

View File

@@ -0,0 +1,38 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>
// +----------------------------------------------------------------------
namespace think\db\exception;
use think\db\DbException;
class ModelNotFoundException extends DbException
{
protected $model;
/**
* 构造方法
* @param string $message
* @param string $model
*/
public function __construct($message, $model = '', Array $config = [])
{
$this->message = $message;
$this->model = $model;
$this->setData('Database Config', $config);
}
public function getModel()
{
return $this->model;
}
}

View File

@@ -0,0 +1,16 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------
namespace think\exception;
class ClassNotFoundException extends \RuntimeException
{
}

View File

@@ -0,0 +1,16 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------
namespace think\exception;
class TemplateNotFoundException extends \RuntimeException
{
}

View File

@@ -0,0 +1,16 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------
namespace think\exception;
class ValidateException extends \RuntimeException
{
}

View File

@@ -11,7 +11,7 @@
namespace think\view\driver;
use think\Exception;
use think\exception\TemplateNotFoundException;
use think\Log;
use think\Request;
@@ -62,7 +62,7 @@ class Php
}
// 模板不存在 抛出异常
if (!is_file($template)) {
throw new Exception('template file not exists:' . $template, 10700);
throw new TemplateNotFoundException('template file not exists:' . $template);
}
// 记录视图信息
APP_DEBUG && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info');

View File

@@ -11,7 +11,7 @@
namespace think\view\driver;
use think\Exception;
use think\exception\TemplateNotFoundException;
use think\Log;
use think\Request;
use think\Template;
@@ -72,7 +72,7 @@ class Think
}
// 模板不存在 抛出异常
if (!is_file($template)) {
throw new Exception('template file not exists:' . $template, 10700);
throw new TemplateNotFoundException('template file not exists:' . $template);
}
// 记录视图信息
APP_DEBUG && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info');

View File

@@ -31,6 +31,48 @@ class Foo extends Controller
{
$this->test = 'abcd';
}
public function assignTest()
{
$this->assign('abcd', 'dcba');
$this->assign(['key1' => 'value1', 'key2' => 'value2']);
}
public function fetchTest()
{
$template = dirname(__FILE__) . '/display.html';
return $this->fetch($template, ['name' => 'ThinkPHP']);
}
public function displayTest()
{
$template = dirname(__FILE__) . '/display.html';
return $this->display($template, ['name' => 'ThinkPHP']);
}
public function test()
{
$data = [
'username' => 'username',
'nickname' => 'nickname',
'password' => '123456',
'repassword' => '123456',
'email' => 'abc@abc.com',
'sex' => '0',
'age' => '20',
'code' => '1234',
];
$validate = [
['username', 'length:5,15', '用户名长度为5到15个字符'],
['nickname', 'require', '请填昵称'],
['password', '[\w-]{6,15}', '密码长度为6到15个字符'],
['repassword', 'confirm:password', '两次密码不一到致'],
['email', 'filter:validate_email', '邮箱格式错误'],
['sex', 'in:0,1', '性别只能为为男或女'],
['age', 'between:1,80', '年龄只能在10-80之间'],
];
return $this->validate($data, $validate);
}
}
class Bar extends Controller
@@ -88,8 +130,6 @@ class Baz extends Controller
}
}
define('ACTION_NAME', 'index');
class controllerTest extends \PHPUnit_Framework_TestCase
{
public function testInitialize()
@@ -123,8 +163,7 @@ class controllerTest extends \PHPUnit_Framework_TestCase
$view = $this->getView($controller);
$template = dirname(__FILE__) . '/display.html';
$viewFetch = $view->fetch($template, ['name' => 'ThinkPHP']);
$controllerFetch = $controller->fetch($template, ['name' => 'ThinkPHP']);
$this->assertEquals($controllerFetch, $viewFetch);
$this->assertEquals($controller->fetchTest(), $viewFetch);
}
public function testDisplay()
@@ -133,16 +172,15 @@ class controllerTest extends \PHPUnit_Framework_TestCase
$view = $this->getView($controller);
$template = dirname(__FILE__) . '/display.html';
$viewFetch = $view->display($template, ['name' => 'ThinkPHP']);
$controllerFetch = $controller->display($template, ['name' => 'ThinkPHP']);
$this->assertEquals($controllerFetch, $viewFetch);
$this->assertEquals($controller->displayTest(), $viewFetch);
}
public function testAssign()
{
$controller = new Foo(Request::instance());
$view = $this->getView($controller);
$controller->assign('abcd', 'dcba');
$controller->assign(['key1' => 'value1', 'key2' => 'value2']);
$controller->assignTest();
$expect = ['abcd' => 'dcba', 'key1' => 'value1', 'key2' => 'value2'];
$this->assertAttributeEquals($expect, 'data', $view);
}
@@ -150,27 +188,7 @@ class controllerTest extends \PHPUnit_Framework_TestCase
public function testValidate()
{
$controller = new Foo(Request::instance());
$data = [
'username' => 'username',
'nickname' => 'nickname',
'password' => '123456',
'repassword' => '123456',
'email' => 'abc@abc.com',
'sex' => '0',
'age' => '20',
'code' => '1234',
];
$validate = [
['username', 'length:5,15', '用户名长度为5到15个字符'],
['nickname', 'require', '请填昵称'],
['password', '[\w-]{6,15}', '密码长度为6到15个字符'],
['repassword', 'confirm:password', '两次密码不一到致'],
['email', 'filter:validate_email', '邮箱格式错误'],
['sex', 'in:0,1', '性别只能为为男或女'],
['age', 'between:1,80', '年龄只能在10-80之间'],
];
$result = $controller->validate($data, $validate);
$result = $controller->test();
$this->assertTrue($result);
}
}

View File

@@ -163,7 +163,7 @@ class sessionTest extends \PHPUnit_Framework_TestCase
// 测试session驱动是否存在
// @expectedException 异常类名
$this->setExpectedException('\think\Exception', 'error session handler', 11700);
$this->setExpectedException('\think\exception\ClassNotFoundException', 'error session handler');
Session::init($config);
}