tp5的唯一可访问目录是public,即项目根目录:

http://localhost/tp5/public/

开发规范:

类库、函数文件统一以.php为后缀

类(命名和路径)和命名空间保持一致

类文件采用驼峰法命名,首字母大写(类文件名 = 类名),其它文件用小写+下划线

方法和属性,采用驼峰法命名,首字母小写

常量,大写字母+下划线

配置参数,小写字母+下划线

应用类库的根命名空间统一为app,不建议更改

如果你的应用下面只有一个模块,那么这个模块的子目录可以省略,并设置参数:

'app_multi_module' => false,

控制器类比较灵活,可以无需继承任何基础类库

模型中,只有进行实际的数据库查询操作的时候,才会进行数据库的连接

可以把模型层进行多层设计,分为逻辑层/服务层/事件层

入口文件代码:

// 定义项目路径

define('APP_PATH', __DIR__ . '/../application/');

// 加载框架引导文件

require __DIR__ . '/../thinkphp/start.php';

start.php引导文件会执行:

加载系统常量定义;

加载环境变量定义文件;

注册自动加载机制;

注册错误和异常处理机制;

加载惯例配置文件;

执行应用;

统一使用return返回数据,而不是echo输出,如非必要,请不要使用exit或者die中断执行

URL是不区分大小写的

http://localhost/index.php/Index/Blog/read

上面URL地址全部改为小写,也是可以的!

怎么访问有大小写的控制器: 采用下划线

http://localhost/index.php/Index/blog_test/read

2.如果希望区分大小写: 修改配置

'url_convert'    =>  false,

隐藏index.php:

1、httpd.conf: 加载mod_rewrite.so模块
2、AllowOverride None 将None改为 All
3、在应用入口文件同级目录添加.htaccess文件,内容如下:

<IfModule mod_rewrite.c>

Options +FollowSymlinks -Multiviews

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-d

RewriteCond %{REQUEST_FILENAME} !-f

RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]

</IfModule>

common模块是一个特殊的模块, 默认是禁止直接访问的, 一般用于放置一些公共的类库用于其他模块的继承

模块的命名空间:

app\模块名\controller\控制器名

例如, app\index\controller\Blog

修改app为其它名称: 修改配置

'app_namespace' => 'application',

如果只有一个模块(且只有一个控制器): 直接绑定

define('BIND_MODULE','index');//只有一个模块index

define('BIND_MODULE','index/index');//且只有一个控制器index

访问时, http://localhost/index.php/read 就可以了

如果只有一个模块, 则可以简化目录结构:

修改配置

'app_multi_module'  =>  false,

调整目录

同时, 访问地址和命名空间都可以把模块省略了

trait实现代码复用:

在TP5中, 这么用: (如果是php5.4以上的版本, load_trait可以省略)

控制器输出: 定义输出的格式 'default_return_type'=>'json',

, 直接return(不用echo)

$data = ['name'=>'thinkphp','url'=>'thinkphp.cn'];

return ['data'=>$data,'code'=>1,'message'=>'操作完成'];

也可以用函数 json、view、xml、jsonp 指定输出的数据类型,

return json(['data'=>$data,'code'=>1,'message'=>'操作完成']);

修改配置文件所在目录:

define('CONF_PATH', __DIR__.'/../config/');

扩展配置: 在应用或模块配置目录下面增加extra子目录, 那么这个目录里的所有配置参数会自动加载, 和其它配置进行合并。

自动读取的配置文件都是二级配置参数, 一级配置名称就是扩展配置的文件名。

比如, extra/aaa.php内容如下:

<?php

return [

'abc'=>'hello',

];

那么应该这样读取:

echo Config::get("aaa.abc"); //输出"hello"

配置参数名不区分大小写, 建议全部使用小写。

还可以使用二维数组来配置更多的信息,

读取-->

echo Config::get('user.type');

设置-->

Config::set([

'type'      =>  'file',

'prefix'    =>  'think'

],'cache');

修改配置格式: define('CONF_EXT', '.ini');

支持的又, .ini、.xml、.json 和 .php

例如,

手动导入配置:

Config::parse(APP_PATH.'my_config.xml','xml');//第二个参数可以省略

$config = 'var1=val

var2=val';

Config::parse($config,'ini');//第二个参数不能省略

判断是否存在某个配置:

Config::has('配置参数2');

config("?配置参数2");

动态配置参数:

config('配置参数','配置值');

config([

'配置参数1'=>'配置值',

'配置参数2'=>'配置值'

]);

配置参数作用域: 就好比命名空间, 这样就可以定义相同名称的参数了

Config::set('user_type',1,'user'); //此参数纳入user作用域

环境变量配置:

在开发过程中, 在应用根目录下面的.env来模拟环境变量配置, 采用ini的格式, 例如

app_debug =  true

app_trace =  true

或(第二种是数组形式)

[database]

username =  root

password =  123456

读取环境变量-->

Env::get('database.username');//第二个参数表示: 默认值

可以在应用配置中使用环境变量:

return [

'hostname'  =>  Env::get('hostname','127.0.0.1'),

];

路由

+++++++++++++++++++++++++++++++++++++++++++++++++++

设置路由模式: 混合模式, 最好。

'url_route_on'  =>  true,

'url_route_must'=>  false,

对需要定义路由规则的访问地址定义路由规则, 其它的仍然按照第一种普通模式的PATH_INFO模式访问URL。

路由定义:

use think\Route;

Route::rule('new/:id','index/News/read');//第三个参数指定请求类型, 为空代表任何类型。

请求类型包括: GET/POST/PUT/DELETE/*

简化写法:   Route::get('new/:id','News/read');

多个请求类型:    Route::rule('new/:id','News/read','GET|POST');

批量注册路由规则:

Route::rule(['new/:id'=>'News/read','blog/:name'=>'Blog/detail']);

支持静态地址:    'my' => 'Member/myinfo',

可选定义:    'blog/:year/[:month]'=>'Blog/archive',

完全匹配: 在路由表达式最后使用$符号, 'new/:cate$'=> 'News/category',

所有路由都采用完全匹配: 配置参数 'route_complete_match'  =>  true,

支持额外参数: 'blog/:id'=>'blog/read?status=1&app_id=5',

批量注册路由规则:

https://www.kancloud.cn/manual/thinkphp5/118031

给路由规则中的动态变量, 设置正则限制:

https://www.kancloud.cn/manual/thinkphp5/118033

路由规则中没有固定的分隔符, 则使用组合变量:

https://www.kancloud.cn/manual/thinkphp5/131398

可以设置一些路由匹配的条件: 用于验证当前的路由规则是否有效

https://www.kancloud.cn/manual/thinkphp5/118034

路由到模块/控制器、重定向地址、控制器、类、闭包函数:

https://www.kancloud.cn/manual/thinkphp5/118037

支持设置RESTFul请求的路由规则:

https://www.kancloud.cn/manual/thinkphp5/118035

为了缩短URL地址, 使用路由别名:

https://www.kancloud.cn/manual/thinkphp5/163984

允许把相同前缀的路由定义进行合并分组:

https://www.kancloud.cn/manual/thinkphp5/118036

在没有匹配到所有的路由规则后执行一条设定的路由, MISS路由:

https://www.kancloud.cn/manual/thinkphp5/151354

可以使用闭包的方式定义一些特殊需求的路由, 而不需要执行控制器的操作方法了:

https://www.kancloud.cn/manual/thinkphp5/118038

使用路由绑定简化URL或者路由规则的定义:

https://www.kancloud.cn/manual/thinkphp5/118040

路由规则和分组支持绑定模型数据:

https://www.kancloud.cn/manual/thinkphp5/208987

支持完整域名、子域名和IP部署的路由和绑定功能:

https://www.kancloud.cn/manual/thinkphp5/118039

当路由定义变化时, URL地址怎么办:

https://www.kancloud.cn/manual/thinkphp5/118041

控制器

+++++++++++++++++++++++++++++++++++++++++++++++++++

需继承任何的基础类, 命名空间默认以app为根命名空间。

修改应用类库命名空间:

'app_namespace' => 'application',

输出转换:

采用return时, 控制器会自动进行数据转换处理。

在ajax请求时, 会自动转换为json。

'default_ajax_return'   => 'html',//默认输出类型

当设置输出格式为html时, 不会自动转换。

如果你的控制器类继承了\think\Controller类的话, 可以定义控制器初始化方法_initialize

设置 beforeActionList属性可以指定某个方法为其他方法的前置操作: first、second、three、hello、data都是此类里面的方法

protected $beforeActionList = [

'first',

'second' =>  ['except'=>'hello'],

'three'  =>  ['only'=>'hello,data'],

];

使用redirect助手函数还可以实现, 记住当前的URL后跳转

redirect('News/category')->remember();

需要跳转到上次记住的URL的时候使用:

redirect()->restore();

空操作:

public function _empty($name)

{

//把所有城市的操作解析到city方法

return $this->showCity($name);

}

空控制器:

<?php

namespace app\index\controller;

use think\Request;

class Error

{

public function index(Request $request)

{

//根据当前控制器名来判断要执行那个城市的操作

$cityName = $request->controller();

return $this->city($cityName);

}

//注意 city方法 本身是 protected 方法

protected function city($name)

{

//和$name这个城市相关的处理

return '当前城市' . $name;

}

}

更改默认的空控制器名:

'empty_controller'      => 'MyError',

多级控制器: 支持任意层次级别的控制器, 并且支持路由

namespace app\index\controller\one;

use think\Controller;

class Blog extends Controller

{

public function index()

{

return $this->fetch();

}

}

该控制器类的文件位置为:

application/index/controller/one/Blog.php

分层控制器:

namespace app\index\event;

class Blog

{

public function update($id)

{

return 'update:'.$id;

}

}

//调用:

$event = controller('Blog', 'event');

echo $event->update(5);

//跨模块:

$event = controller('Admin/Blog', 'event');

//直接调用分层控制器类的某个方法:

echo action('Blog/update', ['id' => 5], 'event');

自动定位控制器: 如果使用了多级控制器, 则开启这个, 便于URL访问

'controller_auto_search' => true,

>>https://www.kancloud.cn/manual/thinkphp5/156860

资源控制器: 轻松的创建RESTFul资源控制器

>>https://www.kancloud.cn/manual/thinkphp5/182949

请求

+++++++++++++++++++++++++++++++++++++++++++++++++++

请求信息: $request = Request::instance();

设置或获取请求信息, 更详细>>https://www.kancloud.cn/manual/thinkphp5/158834

检查变量是否设置:

Request::instance()->has('id','get');

Request::instance()->has('name','post');

获取param变量:
// 获取当前请求的name变量

Request::instance()->param('name');

// 获取当前请求的所有变量(经过过滤)

Request::instance()->param();

// 获取当前请求的所有变量(原始数据)

Request::instance()->param(false);

// 获取当前请求的所有变量(包含上传文件)

Request::instance()->param(true);

获取变量:

Request::instance()->get('id');

Request::instance()->get('id');

Request::instance()->put('name');

Request::instance()->request('id');

Request::instance()->server('PHP_SELF');

Request::instance()->session('user_id');

Request::instance()->cookie('user_id');

以上都可以用input助手函数来实现,

input('cookie.user_id');

变量过滤:

配置参数

'default_filter'         => 'htmlspecialchars',

或设置过滤方法,

Request::instance()->filter(['strip_tags','htmlspecialchars']),

或添加过滤方法,

Request::instance()->param('username','','strip_tags,strtolower');

获取部分变量:

// 只获取GET请求的id和name变量, get参数可以省略

Request::instance()->only(['id','name'],'get');

排除部分变量:

// 排除GET请求的id和name变量, get参数可以省略

Request::instance()->except(['id','name'],'get');

变量修饰符:

input('post.name/s');

Request::instance()->get('id/d');

更改变量:

Request::instance()->get(['id'=>10]);

注意, 尽量避免直接修改$_GET、$_POST数据, 也不能直接修改param变量。

请求类型: 取消了用于判断请求类型的系统常量(如IS_GET, IS_POST等), 统一采用 think\Request类 处理请求类型

Request::instance()->isGet();

其它方法如下,

isPost,isPut,isDelete,isAjax,isPjax、isMobile、isHead、isPatch、isCli、isCgi

请求类型伪装:

1.在form表单里提交_method变量

<input type="hidden" name="_method" value="PUT" >

2.配置参数: 表单请求类型伪装变量

'var_method'             => '_m',

3.可以对请求进行ajax伪装

http://localhost/index?_ajax=1

HTTP头信息:

$info = Request::instance()->header();

echo $info['accept'];

或直接获取,

$agent = Request::instance()->header('user-agent');

请求头的名称不区分大小写。

伪静态: 配置参数

'url_html_suffix' => 'html|shtml|xml',

方法注入:

1.注入

Request::hook('user','getUserInfo');

2.函数:

function getUserInfo(Request $request, $userId){

// 根据$userId获取用户信息

return $info;

}

3.在控制器中调用:

public function index(){

$info = Request::instance()->user($userId);

}

属性注入:

1.注入

Request::instance()->user = new User;

2.获取

Request::instance()->user;

参数绑定:

把URL地址(或者路由地址)中的变量作为操作方法的参数直接传入

假设定义了如下控制器,

namespace app\index\Controller;

class Blog {

public function archive($year='2016',$month='01'){

return 'year='.$year.'&month='.$month;

}

}

1.按名称绑定

http://serverName/index.php/index/blog/archive/year/2016/month/06

//必须指定year、month参数的名称, 顺序随意

2.按顺序绑定

'url_param_type'         => 1,//先修改配置参数为1

然后,

http://serverName/index.php/index/blog/archive/2016/06

依赖注入: 针对访问控制器进行依赖注入

1.架构方法注入

namespace app\index\controller;

use think\Request;

class Index{

protected $request;

public function __construct(Request $request) {

$this->request = $request;

}

public function hello() {

return 'Hello,' . $this->request->param('name') . '!';

}

}

2.操作方法注入

namespace app\index\controller;

use think\Request;

class Index{

public function hello(Request $request){

return 'Hello,' . $request->param('name') . '!';

}

}

请求缓存: 支持对请求地址设置缓存访问, 并设置有效期(只针对GET有效)

1.路由

Route::get('new/:id','News/read',[

'cache' => [ 'cache_flag',3600]

]);

2.动态设置

Request::instance()->cache('blog/:id',3600);

Request::instance()->cache('__URL__',600);//以当期URL地址作为缓存标识

Request::instance()->cache('[html]',600);//对html后缀的请求进行缓存

3.自动判断缓存: 配置参数

'request_cache' => true,

'request_cache_expire' => 3600,

'request_cache_except' => [ //设置排除规则

'/blog/index',

'/user/member'

],

数据库

+++++++++++++++++++++++++++++++++++++++++++++++++++

连接数据库:

1.配置参数: database.php

return [

'type'        => 'mysql',

'dsn'         => '',

'hostname'    => '127.0.0.1',

'database'    => 'thinkphp',

'username'    => 'root',

'password'    => '',

'hostport'    => '',

'params'      => [],

'charset'     => 'utf8',

'prefix'      => 'think_',

'debug'       => false,

// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)

'deploy'      => 0,

// 数据库读写是否分离 主从式有效

'rw_separate' => false,

// 读写分离后 主服务器数量

'master_num'  => 1,

// 指定从服务器序号

'slave_no'    => '',

// 是否严格检查字段是否存在

'fields_strict'  => true,

];

2.每个模块可以单独配置: 相同参数无需重复配置

return [

'hostname'    => '192.168.1.100',

'database'    => 'admin',

];

3.配置参数: 断线重连

'break_reconnect' => true,

4.在方法中动态定义连接信息

Db::connect('mysql://root:1234@127.0.0.1:3306/thinkphp#utf8');

或,

Db::connect('db_config1');//db_config1是配置参数

5.在模型中定义连接信息

namespace app\index\model;

use think\Model;

class User extends Model{

protected $connection = 'mysql://root:1234@127.0.0.1:3306/thinkphp#utf8';

//或

//protected $connection = 'db_config1';

}

基本使用:

Db::query('select * from think_user where id=?',[8]);

Db::execute('insert into think_user (id, name) values (?, ?)',[8,'thinkphp']);

Db::query('select * from think_user where id=:id',['id'=>8]);

Db::connect($config)->query('select * from think_user where id=:id',['id'=>8]);

CURD操作事件:

仅支持find、select、insert、update和delete方法。

Query::event('after_insert','callback');

或,

Query::event('before_select',function($options,$query){

return $result;

});

事务操作:

Db::transaction(function(){

Db::table('think_user')->find(1);

Db::table('think_user')->delete(1);

});

或手动控制事务,

// 启动事务

Db::startTrans();

try{

Db::table('think_user')->find(1);

Db::table('think_user')->delete(1);

// 提交事务

Db::commit();

} catch (\Exception $e) {

// 回滚事务

Db::rollback();

}

监听SQL:

Db::listen(function($sql, $time, $explain){

// 记录SQL

echo $sql. ' ['.$time.'s]';

// 查看性能分析结果

dump($explain);

});

调用存储过程:

$result = Db::query('call sp_query(?)',[8]);

数据集:

1.使用

$users = Db::name('user')->select();

if($users->isEmpty()){ //不能用empty判断

echo '数据集为空';

}

2. 返回的数据集对象是think\Collection, 包含这些方法

分布式数据库:

https://www.kancloud.cn/manual/thinkphp5/118061

查询构造器(链式操作):

https://www.kancloud.cn/manual/thinkphp5/135175

查询数据:

1.value: 返回某个字段的值

Db::table('think_user')->where('id',1)->value('name');

2.column: 返回某一列的值

Db::table('think_user')->where('status',1)->column('name','id');

3.分批处理数据集

Db::table('think_user')->chunk(100, function($users) {

foreach ($users as $user) {

//..

}

});

4.查询json字段

Db::table('think_user')->where('info$.email','tp@qq.com')->find();

添加数据:

1.添加一条

$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->insert($data);

2.返回自增主键

$userId = Db::name('user')->getLastInsID();

或,

Db::name('user')->insertGetId($data);

3.添加多条

$data = [

['foo' => 'bar', 'bar' => 'foo'],

['foo' => 'bar1', 'bar' => 'foo1'],

['foo' => 'bar2', 'bar' => 'foo2']

];

Db::name('user')->insertAll($data);//返回添加成功的条数

更新数据:

1.有主键时

Db::table('think_user')

->update(['name' => 'thinkphp','id'=>1]);

2.延迟更新: 第三个参数

Db::table('think_user')->where('id', 1)->setInc('score', 1, 10);

3. 要更新的数据需要使用SQL函数或者其它字段

Db::table('think_user')

->where('id', 1)

->update([

'login_time'  => ['exp','now()'],

'login_times' => ['exp','login_times+1'],

]);

删除数据:

1.根据主键

Db::table('think_user')->delete(1);

Db::table('think_user')->delete([1,2,3]);

2.条件删除

Db::table('think_user')->where('id','<',10)->delete();

查询方法:

1.AND条件

Db::table('think_user')

->where('name','like','%thinkphp')

->where('status',1)

->find();

2.OR条件

Db::table('think_user')

->where('name','like','%thinkphp')

->whereOr('title','like','%thinkphp')

->find();

3.获取表信息

Db::getTableInfo('think_user', 'fields');

//fields 所有字段、type 所有字段的类型、pk 表主键

//也可省略第二个参数, 表示获取表的所有信息

查询表达式:

统计查询:

时间查询:

https://www.kancloud.cn/manual/thinkphp5/165789

只返回sql语句:

1. fetchSql

$subQuery = Db::table('think_user')

->field('id,name')

->where('id','>',10)

->fetchSql(true)

->select();

2. buildSql

$subQuery = Db::table('think_user')

->field('id,name')

->where('id','>',10)

->buildSql();

3. select(false)

$subQuery = Db::table('think_user')

->field('id,name')

->where('id','>',10)

->select(false);

子查询:

1. 在上面代码的基础上...

Db::table($subQuery.' a')

->where('a.name','like','thinkphp')

->order('id','desc')

->select();

生成的SQL语句为:

SELECT * FROM ( SELECT `id`,`name` FROM `think_user` WHERE `id` > 10 ) a WHERE a.name LIKE 'thinkphp' ORDER BY `id` desc

2. 使用闭包...

Db::table('think_user')

->where('id','IN',function($query){

$query->table('think_profile')->where('status',1)->field('id');

})

->select();

原生操作: 最好使用参数绑定, 安全!

Db::query("select * from think_user where id=? AND status=?",[8,1]);

Db::execute("update think_user set name=:name where

status=:status",['name'=>'thinkphp','status'=>1]);

模型

+++++++++++++++++++++++++++++++++++++++++++++++++++

;

thinkphp5 (最棒的php开源框架)的更多相关文章

  1. 开源框架:SDWebImage

    http://blog.csdn.net/uxyheaven/article/details/7909373 SDWebImage是我搞iOS以来少数佩服的框架,膜拜一下作者.真的写的非常棒! 这套开 ...

  2. thinkphp5升级版开源框架tpframe v2.1发布

    免费开源框架tpframe是一款以thinkphp5为驱动,在此基础上进行进一步的完善与改进的框架,保持了ThinkPHP5原有的所有特性,优化核心,减少依赖,为个人或企业建站提供高效.快速解决的方案 ...

  3. Pyhton开源框架(加强版)

    info:Djangourl:https://www.oschina.net/p/djangodetail: Django 是 Python 编程语言驱动的一个开源模型-视图-控制器(MVC)风格的 ...

  4. Python开源框架

    info:更多Django信息url:https://www.oschina.net/p/djangodetail: Django 是 Python 编程语言驱动的一个开源模型-视图-控制器(MVC) ...

  5. 开源框架】Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发

    [原][开源框架]Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发,欢迎各位... 时间 2015-01-05 10:08:18 我是程序猿,我为自己代言 原文  http: ...

  6. SunSonic 3.0 ORM开源框架的学习

    SubSonic 3.0简介 接触到SubSonic3.0 ORM框架是看了AllEmpty大神的从零开始编写自己的C#框架(链接在此)系列的随笔接触到的,本文章学习内容源于AllEmpty大神. S ...

  7. 30 个很棒的 PHP 开源 CMS 内容管理系统

    本文汇集了30个优秀的开源CMS建站系统,采用PHP开发.以下列表不分先后顺序. 1. AdaptCMS AdaptCMS Lite 是一个开源的CMS系统,主要特点是易用,而且可以轻松和其他系统接驳 ...

  8. 开源框架Caliburn.Micro

    Caliburn.Micro学习笔记----引导类和命名匹配规则   用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeple ...

  9. 值得学习的C/C++开源框架(转)

    值得学习的C语言开源项目 - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的 ...

随机推荐

  1. NOIP2016模拟赛三 Problem C: 不虚就是要AK

    题目大意 给定一棵带有边权的树, 问你在树上随机选两个点, 它们最短路径上的边权之和为\(4\)的倍数的概率为多少. Solution 树分治. 没什么好讲的. #include <cstdio ...

  2. 发现一个直播录制工具you-get

    地址:https://github.com/soimort/you-get 截至到今天,支持的平台如下: Site URL Videos? Images? Audios? YouTube https: ...

  3. CBIntrospector俗称:内部检查工具

    Download View Introspector   (CBIntrospector)内部检查工具是IOS和IOS模拟器的小工具集,帮助在调试的UIKit类的用户界面,它尤其有用于动态UI布局创建 ...

  4. CoreData: 如何预载/导入已有的数据

    原文地址:CoreData: 如何预载/导入已有的数据作者:出其东门 在系列教程一中,我们为对象建立了可视化数据模型,运行了快速肮脏测试并勾在一个表视图(table view)中来显示.而在这个教程, ...

  5. ASIHTTPRequest, request sent twice

    ´ve just started using ASIHTTPRequest for iOs and I have a small issue with it. All requests are sen ...

  6. linux查看端口状态相关命令

    netstat netstat 命令应用是比较频繁的,比如查看端口占用啦,查看端口进程啦,这些时候都是有必要的. netstat命令各个参数说明如下: -t : 指明显示TCP端口 -u : 指明显示 ...

  7. java项目热加载工具jrebel

    flask有热加载的功能,修为代码后,自动生效. java项目也有类似的功能,不过需要使用收费的插件jrebel 提供一个免费的注册服务器:http://139.199.89.239:1008/884 ...

  8. 2016.11.10 Could not get JDBC Connection; nested exception is java.sql.SQLException: No suitable driver

    运行项目rds_web时,出现错误提示:Could not get JDBC Connection; nested exception is java.sql.SQLException: No sui ...

  9. 白盒测试中如何实现真正意义上并发测试(Java)

    在这个话题开始之前,首先我们来弄清楚为什么要做并发测试? 一般并发测试,是指模拟并发访问,测试多用户并发访问同一个应用.模块.数据时是否产生隐藏的并发问题,如内存泄漏.线程锁.资源争用问题. 站在性能 ...

  10. NSTimer使用不当引发的内存泄漏问题

    NSTimer可以用来执行一些定时任务,比较常用的方法就是: + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTar ...