https://blog.csdn.net/self_realian/article/details/78596261

一、什么是模型

为什么我们要在项目中使用模型,其实我们知道,我们可以直接在控制器中进行数据库的增、删、改、查,其实已经能基本完成我们的需求,但是,为什么还要有模型的存在呢?

比如说我们现在要做一个用户注册的操作,用户注册我们可能用两个表来保存用户的信息,一个是user表(保存用户基本信息),一个是user_info表(保存用户扩展信息,比如爱好等等),如果我们现在直接在我们的控制器中编写,那么我们需要对数据库两个表进行操作,我们就需要写两个db的方法来进行操作,我们需要将这些方法进行封装,最后放在模型里,只要执行这个模型里的某一个方法,那么就会自动完成我们所有操作的操作,也就是说,把我们数据库完成同一件事情的操作,放在一个公共方法里,这样我们在控制器里进行调用就会变得很方便。特别是代码复用的部分,我们可以编写这样的方法,让我们在任何地方可以使用用户注册这个方法。那么下面就看看如何定义模型:

首先在我们的application/index/创建一个model目录,专门放模型文件,然后在model目录下创建一个User.php文件

模型文件的命名规范: 首先我们的模型名和我们的表名要是对应的。比如我们要写我们数据库中的shulv_user表,那么我们的模型名就是去掉前缀之后使用驼峰的命名方式,也就是User.php,当数据库中有这种包含下划线的表名时,去掉下划线,并将下划线后边的字母大写,即时模型名,shulv_user_info 对应模型名就是UserInfo,这样他就会自动对应到数据库中的表。下边写代码验证一下:

namespace app\index\controller;

use think\Controller;

use app\index\model\User;//使用我们刚刚新建的那个模型

class Index extends Controller

{

public function index()

{

$res = User::get(51);//通过get()方法,取出user表中的id=51的这条数据(现在可以不用知道为什么使用get方法,后边会说)

$res = $res->toArray();//将取出的数据转换成数组

dump($res);

}

}

你会发现,我们没有在模型中的User.php中编写任何的代码,但是在控制器中use进来User模型之后,就可以直接使用静态方法,这是为什么呢?

因为在我们的模型文件中的类都继承了think\Model这个类,think\Model中其实有这样的方法,这些方法,后边会说到。同样我们还可以在控制器中使用new的方式

$user = new User();

$res = $user::get(53);

$res = $res->toArray();

dump($res);

当我们,不想通过use的方式将User模型引入进来的时候,我们还可以通过下边的方法:

namespace app\index\controller;

use think\Controller;

//use app\index\model\User;//使用我们刚刚新建的那个模型

use think\Loader;//通过引入think下的Loader类

class Index extends Controller

{

public function index()

{

$user = Loader::model("User");//通过Loader下的model这个静态方法来引入对应模型

$res = $user::get(52);

$res = $res->toArray();

dump($res);

}

}

//说明:这种方式,是当我们的控制器下有多个模型的时候,我们使用这种方式,这样我们就不用在使用每一个模型的时候都use一下,我们直接使用Loader::model()这种方法直接引入。另外,它还提供了一个助手函数model(),此时我们连Loader类都不用引入了

/*

$user = model("User");

$res = $user::get(52);

$res = $res->toArray();

dump($res);

*/

//在这里建议大家使用前两种方式,因为助手函数式可能被覆盖掉的,当然这种情况很少发生,但是为了避免,或者让我们的代码可读性更高,建议大家使用第一种方式,也就是将需要的模型都use进来,通过它的静态方法来获取数据,这样我们的代码看起来更清晰,我们可以在最上边就看见我们当前的控制器使用了哪些模型类,这样在后期维护中会变得很方便

二、通过模型进行数据查询

namespace app\index\controller;

use think\Controller;

use app\index\model\User;//使用我们刚刚新建的那个模型

//use think\Loader;//通过引入think下的Loader类

class Index extends Controller

{

public function index()

{

//之前我们查询一条数据的时候是通过给get()方法传递一个主键来获取对应数据,我们还可以传递一个闭包函数

$res = User::get(function($query){//在这里边构造查询条件

$query->where("id", "eq", 55);//这里条件的构造和前边的博客中说的一样(同样可以在后边继续添加链式方法)

});

$res = $res->toArray();

dump($res);

}

}

我们还可以通过下边这种方法构造where条件

namespace app\index\controller;

use think\Controller;

use app\index\model\User;//使用我们刚刚新建的那个模型

//use think\Loader;//通过引入think下的Loader类

class Index extends Controller

{

public function index()

{

$res = User::where("id", 51)

->find();//同样我们可以在后边添加更多的链式方法

$res = $res->toArray();

dump($res);

}

}

/*

当我们想获取表中的多条数据时,我们可以使用User::all();参数是主键名,可以使用字符串的方式,也可以使用数组的方式

$res = User::all("1,2,3");//这个时候返回的每一条记录都是一个对象,我们就可以通过foreach进行遍历输出

//或$res = User::all([1,2,3]);

foreach($res as $value){

dump($value->toArray());//这个时候我们就会获得三条数据

}

//这个all()还可以接收一个闭包函数作为参数,来构造where条件

$res = User::all(function($query){

$query->where("id", "<", 5); //同样可以添加更多的链式方法

});

*/

当我们想要获取单独的一个字段,我们知道Db类有一个value() 方法,模型我们也可以这样

$res = User::where()->value("email");//直接返回的是字符串

dump($res);

//获取某一个字段那一列时

$res = User::column("email");//返回的是一个数组

三、使用模型添加数据

在thinkphp,它的model为我们提供了一个create()方法(静态方法),直接向数据库中插入数据

namespace app\index\controller;

use think\Controller;

use app\index\model\User;//使用我们刚刚新建的那个模型

//use think\Loader;//通过引入think下的Loader类

class Index extends Controller

{

public function index()

{

$res = User::create([

'username'   =>  'shulv',

'password'   =>  md5('shulv'),

'email'      =>  'shulv@qq.com',

'num'        =>  100

]);//它的返回结果依然是一个对象

dump($res->id);//获得此时的自增id

dump($res);

}

}

namespace app\index\controller;

use think\Controller;

use app\index\model\User;//使用我们刚刚新建的那个模型

//use think\Loader;//通过引入think下的Loader类

class Index extends Controller

{

public function index()

{

// $res = User::create([

//      'username'   =>  'shulv',

//      'password'   =>  md5('shulv'),

//      'email'      =>  'shulv@qq.com',

//      'num'        =>  100

//      'demo'       =>  15245

// ]);//当我们要插入一个表中并没有的字段时,不传递第二个参数时,运行时会报错,说该字段不存在(此时数据库也并不会插入这条数据)

/*

我们知道,当前台传递数据时,往往直接传到$_POST中,我们会将POST中所有的数据插入到表中,那么我们就应该让它有的就插入表中,没有的就不插入,此时我们就需要给它传入第二个参数"true"

*/

$res = User::create([

'username'   =>  'shulv1',

'password'   =>  md5('shulv1'),

'email'      =>  'shulv1@qq.com',

'num'        =>  101,

'demo'       =>  15245

],true);

dump($res);

}

}

当我们仅允许添加指定的字段时,我们可以将第二个参数传递一个数组,数组中的元素就是,你指定添加的字段

public function index()

{

$res = User::create([

'username'   =>  'shulv2',

'password'   =>  md5('shulv2'),

'email'      =>  'shulv2@qq.com',

'num'        =>  102,

'demo'       =>  145

],['username','password']);

dump($res->id);

}

模型中还为我们提供了一个save()方法来插入数据(如果我们想使用save()就要先实例化我们的模型)

namespace app\index\controller;

use think\Controller;

use app\index\model\User;//使用我们刚刚新建的那个模型

//use think\Loader;//通过引入think下的Loader类

class Index extends Controller

{

public function index()

{

$userModel = new User;

//那么此时,我们就可以对数据库进行添加的操作了

$userModel->username = 'shulv3';

$userModel->password = md5('shulv3');

$userModel->email = 'shulv3@qq.com';

$userModel->num = 103;

$userModel->save();

dump($userModel->id);

}

}

当然我们还可以使用一种简单的方法,就是直接给save()传递一个数组,数组的元素为插入的值,就像create()方法传递参数那样。不一样的地方是,但遇见插入的字段,表中不存在的时候,它的处理方法是调用一个allowField()方法

$userModel = new User;

$res = $userModel

->allowField(true)

->save([//allowField('true')也可以传递一个数组,元素为允许插入的字段名

'username' => 'shulv4',

'password' => md5('shulv5'),

'email'    => 'shulv@qq.com',

'demo'     => 123

]);//返回值是插入的条数

dump($res);

那么当我们想要添加多条记录时,我们可以使用saveAll()方法,参数为一个二维数组

public function index()

{

$userModel = new User;

$res = $userModel->saveAll([

['email' => 'shulv4@qq.com'],

['email' => 'shulv5@qq.com']

]);//我这里只插入了email

foreach($res as $value){

dump($value->id);

//dump($value->toArray());

}

}

一、使用模型更新数据

如果我们想更新数据,我们在前边说Db类的时候我们知道,我们需要一些where条件,我直接用代码演示:

public function index()

{

$res = User::update([//通过Model的update()方法,传递一个数组进行数据更新

'username'  => '3404767031'

], ['id'=>80]);//表示更新id=80的这条记录的username

dump($res);

}

第二个参数,还可以支持一个闭包函数,和之前说的一样:

public function index()

{

$res = User::update([//通过Model的update()方法,传递一个数组进行数据更新

'username'  => 'test'

], function($query){

$query->where("id", "<", 85);

});//表示更新id<85的这几条记录的username

dump($res);

//当然可以直接通过我们之前说的那种,链式操作的方式来构造where条件:User::where()->update();

其实,我们还有一种更新数据的方法,那就是,现获取到某条记录,然后再对记录中的字段进行修改:

$userModel = User::get(80);

$userModel->username = 'shulv_80';

$res = $userModel->save();

dump($res);

我们还可以通过saveAll()的方法进行批量更新数据

$userModel = new User;

$res = $userModel->saveAll([

['id'=>88, 'username' => 'hhhhhh'],

['id'=>89, 'username' => 'tttttt']

]);

dump($res);

二、使用模型删除数据

//Model类为我们提供了destory()静态方法来删除数据

$res = User::destroy(79);//如果表中存在主键,我们可以直接传递主键进行删除

dump($res);

//Model类为我们提供了destory()静态方法来删除数据

// $res = User::destroy(79);//如果表中存在主键,我们可以直接传递主键进行删除

// dump($res);

$res = User::destroy(['id'=>80]);//也可以通过传递数组的方式

$res = User::destroy(function($query){

$query->where("id", "<", 85);

});//还可以通过闭包函数的方式

//通过先获取到执行的记录,然后进行删除

$userModel = User::get(90);

$res = $userModel->delete();

//添加where条件进行删除

$res = User::where("id", "=", 91)->delete();//返回值是删除的记录数

//删除所有数据  $res = User::where("1=1")->delete();

dump($res);

三、模型聚合操作

在thinkphp的model中为我们提供了很方便获取平均值、最大值、最小值、数据条数的方法。下边就用代码演示这些函数的用法:

$res1 = User::count();//获取总记录数

dump($res1);

$res2 = User::where("id", ">", 90)//获取id>90的记录数

->count();

dump($res2);

$res3 = User::max('num');//获取num字段中的最大值

dump($res3);

$res4 = User::where("id", ">", 90)//获取id>90的记录中num值最大的那个记录

->max('num');

dump($res4);

//其余的还有sum(),avg()等方法的使用都是这样,就不一一写了

四、模型获取器

在我们的实际应用中,我们经常会存在这样的场景,比如说我们存用户的性别,我们可能在数据库中只使用0,1,20或1,2,3的方式来存用户的性别。0:男1:女2:未知。我们在数据库中存的是0,1,2而我们在页面中展示的是男女和未知,那么在获取这个数据的过程中,我们就使用获取器,可以自动的将我们的数据转化成我们想要的显示格式

app/index/model/User.php

<?php

namespace app\index\model;

use think\Model;

class User extends Model{

public function getSexAttr($val){//注意这个方法名的写法是固定的

//dump($val);//我们在这里先直接打印这个$val,可以看到输出的是int(0),也就是说我们能直接获取到我们当前获取的数据的value值,那么我们就可以对其进行判断

switch ($val) {

case '1':

return "男";

break;

case '2':

return "女";

break;

default:

return "未知";

break;

}

}//写完这个函数之后,刚才输出的0,现在就会输出  未知

app/index/controller/Index.php

<?php

namespace app\index\controller;

use think\Controller;

use app\index\model\User;//使用我们刚刚新建的那个模型

//use think\Loader;//通过引入think下的Loader类

class Index extends Controller

{

public function index()

{

//首先我们先看一下怎么常规的获取到一条记录的sex字段值

$res = User::get(80);

echo $res->sex;

//那么现在我们如果想让0:未知 1:男 2:女    那么这个时候我们需要在模型中编写一个函数

dump($res->toArray());//此时会打印出id=80的这条记录,我们会发现sex显示的是 未知

//那么,如果我们想获取到原始数据,可以使用getData()

dump($res->getData());

}

一、模型修改器+自动完成

将这两个放在一起学习,是因为这两个有很多的相似之处,下边看一下修改器

控制器Index.php

public function index()

{

//首先我们向数据库中添加一条数据

$res = User::create([

'username'  => 'liangyu',

'password'  => 'liangyu',//注意,我这里没有对其加密,后边我会让它自动完成修改,也就是要说的修改器

'email'     => 'liangyu@qq.com',

'num'       => 520

]);

dump($res->id);

//密码没有加密,那么我们如何通过修改器让它进行自动的修改,这个时候就需要在模型中编写代码

}

模型User.php

public function setPasswordAttr($val){

return md5($val);//定义了这个方法之后,它会自动传递password给$val

//这个时候,当我们再进行数据插入的时候,它就会对密码自动的进行加密

}

//当然我们还可以传递第二个参数$data,它接收的是,我们插入的这条数据的所有元素(之前说的那个自动将0在输出的时候打印为“未知”,那个getSexAttr的方法,也可以传递第二个参数$data,表示的含义是一样的)

public function setPasswordAttr($val, $data){

return $val . $data['email'];//这个就表示,将密码+email整体当做最终密码,当然还可以对整体进行加密,这样更安全

//return md5($val . $data['email']);

}

然后我们说一下自动完成:

控制器Index.php

public function index()

{

//首先我们向数据库中添加一条数据

$res = User::create([

'username'  => 'liangyu',

'password'  => 'liangyu',

'email'     => 'liangyu@qq.com',

'num'       => 520

]);

dump($res->id);

}

模型User.php

//如果想使用自动完成,那么就需要在模型中声明

protected $auto = [//数组中的内容,就是我们要自动的字段

'time'

];//这个$auto是在我们进行数据添加和更新的时候都会发生变化,都会发生的操作。它的方法和我们的修改器是一样的

public function setTimeAttr(){//首先,我们修改一下自己的数据库,在我们的数据库中添加一个time字段

return time();

}//这个时候,刷新数据库,新添加的这条数据就有了time()

控制器:Index.php

public function index()

{

//首先我们向数据库中添加一条数据

$res = User::create([

'username'  => 'liangyu',

'password'  => 'liangyu',

'email'     => 'liangyu@qq.com',

'num'       => 520

]);

// $userModel = new User;

// $userModel->get(101);

// $userModel->sex = 1;

// $res = $userModel->save();

dump($res->id);

}

模型User.php

namespace app\index\model;

use think\Model;

class User extends Model{

//如果想使用自动完成,那么就需要在模型中声明

protected $auto = [//数组中的内容,就是我们要自动的字段

'time'

];//这个$auto是在我们进行数据添加和更新的时候都会发生变化,都会发生的操作。它的方法和我们的修改器是一样的

//另外,我们还可以声明一个$insert数组,这个数组,它只在数据插入的时候有效

protected $insert = [

'time_insert'

];

//同样我们还可以添加$update数组,它是在数据更新的时候发生改变

$protected $update = [//我们在数据库中首先使用之前学过的修改记录的值,进行修改,那么该修改器会被自动调用

'time_update'

];

public function setTimeAttr(){//首先,我们修改一下自己的数据库,在我们的数据库中添加一个time字段

return time();

}//这个时候,刷新数据库,新添加的这条数据就有了time()

public function setTimeInsertAttr(){//这个时候,我们先去给我们的数据表添加一个time_insert字段

return time();//插入时间

}//这样我们再刷新一下我们的页面,机会看见数据表中新添的记录中有了time_insert值

public function setTimeUpdateAttr(){

return time();

}

//这种修改器函数的命名是set+字段名(驼峰命名法)+Attr()

}

二、模型时间戳+软删除

时间戳是做什么使用的呢?

比如说我们对数据进行新增或更新的操作时,我们往往需要在数据库中记录我们的插入时间和更改时间。通过前边的知识我们知道,我们可以使用自动完成的方式来实现这个功能,但是,我们大多数的数据库会有这样的字段,如果我们每一个都要这样去编写这样自动更新或自动完成的操作,那么我们的代码就会变得很臃肿,我们实现起来也不是很方便。所以thinkphp的model类,为我们提供了自动的时间戳功能,它会将我们数据的更新时间和创建时间记录到数据库中。

软删除

在我们对数据进行删除的操作,我们往往不会将这条数据真正的从数据库中删除,而是将它的某一个字段设置为一个特定的值,代表这个字段已经被删除,或者代表这条记录已经被删除。下边用代码演示一下:

首先我会将之前的那个表删除掉,重新创建一个表,因为之前的表字段太多,模拟起来不方便(表名不变)

表结构

控制器:Index.php

namespace app\index\controller;

use think\Controller;

use app\index\model\User;//使用我们刚刚新建的那个模型

//use think\Loader;//通过引入think下的Loader类

class Index extends Controller

{

public function index()

{

//第一种方式

//如果我们想全局的开启添加时间和更新时间,时间戳的自动完成这个操作,那么我们可以修改配置文件(database.php中找到auto_timestamp,将它的值设置为true)

//然后我们现在开始插入数据

$res = User::create([

'name'     =>  'shulv',

'password' =>  md5('liangyu')

]);

dump($res);//当我们刷新页面的时候就会发现,create_time和update_time字段已经有值了

//但是,并不是所有的表都有新增时间和更新时间的字段,所以一般情况下不建议直接在配置文件中进行修改。因为它如果修改的话,如果你的一个表中不存在时间戳的字段,那么程序可能就会报错,所以我们还是将它设置为false

//这个时候我们进入对应的模型(User.php)中添加一个属性$autoWriteTimestamp

//我们再进行一下修改的操作

$user = User::get(0);

$user->name = 'liangyu';

$res = $user->save();

dump($res);//此时我们会发现数据库中id=0的这条记录的两个时间戳字段的值也发生了更新

/*

现在有一个问题就是,如果我们数据库中的两个时间戳字段名不是create_time和update_time,比如说我给它们改成create_at和update_at,那么此时我们再刷新的时候,他就会报错,说update_time和update_time不存在。因为我们在使用配置的时候,它的默认配置就是update_time,所以我们需要在model中继续申请一个属性

*/

}

}

模型:User.php

namespace app\index\model;

use think\Model;

class User extends Model{

protected $autoWriteTimestamp = true;//利用这个属性来开启时间戳功能。这个时候我们再更新页面,那两个时间戳字段也会被添加进去

protected $createTime = 'create_at';//这里直接写上我们的字段名

protected $updateTime = 'update_at';//这个时候我们再刷新浏览器就不会报错了,时间也会被更新

//当然我们还可以将$createTime或$updateTime设置为false,便是关闭该项,那么它会使用默认值(0),就不会去更新这个字段了

}

软删除

控制器:Index.php

namespace app\index\controller;

use think\Controller;

use app\index\model\User;//使用我们刚刚新建的那个模型

//use think\Loader;//通过引入think下的Loader类

class Index extends Controller

{

public function index()

{

//在说软删除的时候,我们先向数据库中添加一个delete_time字段(允许为null,null代表这条数据没有被删除)

//如果我们想使用软删除,我们需要在模型中引入traits\modelSoftDelete(去看模型User.php)

//在模型中引入traits\modelSoftDelete之后,就可以直接在控制器中进行删除了

$res = User::destroy(0);

dump($res);

//这个时候我们在数据表中可以看见id=0的字段并没有被真正的删除,它的delete_time字段名变成了时间戳,说明这条数据在指定的时间点被删除(软删除)。这个时候当你尝试获取刚刚被软删除的记录时,返回的是null,也就是说不能再获取了。如果你确实需要获取到我们包含软删除的这些记录,那么我们就可以使用下边这样的方式

$res = User::withTrashed(true)->find(0);//这个时候就能得到了

dump($res);

dump($res->getData());//可以获取原始数据

//还有一种方式就是,比如说我们软删除的记录都放在了垃圾箱里,那么我们要获取这些被软删除的数据,就可以这样

$res = User::onlyTrashed()->select();//返回的是数组,我们可以通过foreach遍历

dump($res);

//那么,如果我们想对数据进行恢复,可以直接使用update方法,将delete_time的值设置为null即可

//当我们不想软删除这个字段名为delete_time时,我们还是使用更改create_time那种在model中声明变量的方式进行更改

//那么如果我们真正的想删除某一个记录时应该怎么做呢?

$res = User::destroy(0, true);//传递第二个参数为true即可

dump($res);

//还可以通过先获取,再删除的方式

$user = User::get(0);

$res = $user->delete(0, true);

dump($res);

}

}

模型:User.php

namespace app\index\model;

use think\Model;

use traits\modelSoftDelete;

class User extends Model{

use SoftDelete;

protected $autoWriteTimestamp = true;//利用这个属性来开启时间戳功能。这个时候我们再更新页面,那两个时间戳字段也会被添加进去

protected $createTime = 'create_at';//这里直接写上我们的字段名

protected $updateTime = 'update_at';//这个时候我们再刷新浏览器就不会报错了,时间也会被更新

//当然我们还可以将$createTime或$updateTime设置为false,便是关闭该项,那么它会使用默认值(0),就不会去更新这个字段了

protected $updateTime = 'delete_at';

}

《TP5.0学习笔记---模型篇》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. ChemDraw Std 14如何标记同位素

    ChemDraw软件是一款专业高效的化学绘图工具,能够绘制各种复杂的结构方程式,在基础化学.有机化学.材料化学等领域得到广泛应用.而ChemDraw Std 14 作为ChemDraw 的最新版本,增 ...

  2. IPV6设置

    C:\Windows\System32\drivers\etc 目录下修改hosts文件. 网上有更新的ipv6 hosts文件,复制下来~ 别人不断更新的: https://raw.githubus ...

  3. brew 接口的原理

    请查看相关文档的第9章 该文档可以csdn silentjesse帐号下的资源去下载 http://download.csdn.net/detail/silentjesse/5859077

  4. [java] jstack 查看死锁问题

    package com.xwolf.java.thread.ch2; /** * Created by Administrator on 2016/1/4 0004. */ public class ...

  5. swift - UISegmentedControl 的用法

    一.创建控件,并监听控件选择值 /*选项除了文字还可以是图片 as关键字的作用就是字面意思:类型转换*/ let items = ["选项一", "选项二", ...

  6. Python 爬虫知识点 - 淘宝商品检索结果抓包分析(续二)

    一.URL分析 通过对“Python机器学习”结果抓包分析,有两个无规律的参数:_ksTS和callback.通过构建如下URL可以获得目标关键词的检索结果,如下所示: https://s.taoba ...

  7. python2.0_s12_day14_jQuery详解

    jquery的中文介绍文档:http://www.php100.com/manual/jquery/jQuery之基本选择器jQuery中提供的用于获取标签的方法都有哪些? jQuery提供的 &qu ...

  8. round()

    round() 用于对一个数值进行四舍五入,如果接收两个参数,则第二个参数表示保留多少位小数 In [1]: round(1.5324) Out[1]: 2.0 In [2]: round(1.532 ...

  9. 使用 XPath

    XPath 简介: (1) 前面我们爬取一个网页,都是使用正则表达式来提取想要的信息,但是这种方式比较复杂,一旦有一个地方写错,就匹配不出来了,因此我们可以使用 XPath 来进行提取(2) XPat ...

  10. SYN攻击处理

    针对SYN攻击的几个环节,提出相应的处理方法: 方式1:减少SYN-ACK数据包的重发次数(默认是5次): sysctl -w net.ipv4.tcp_synack_retries=3 sysctl ...