目标:基于自定义的mvc框架开发的案例(项目)

项目周期    需求分析

典型的业务逻辑:    电子商务:商城(京东),B2C,C2C(淘宝),团购,秒杀,代购

内容管理:新浪门户类,优酷视频管理,博客文章管理,微博

论坛:

我们的需求,商品管理案例!参考ecshop应该出现的商品管理的基本功能实现。

安装ecshop

ecshop,使用率非常高,电子商务平台(网上商城系统)。

上传拷贝php源代码        创建数据    基本配置

下载ecshop的源代码,解压,将upload目录拷贝(上传)到web目录:建议改成ecshop的名字

使用浏览器,访问到ecshop目录中的index.php即可。自动跳转到安装界面(如果需要重新安装,也可以请求到该地址)

检查环境,典型的需要:mysql扩展,gd扩展(图片处理扩展)

1

 

extension=php_gd2.dll

配置信息

数据库服务器部分:

管理员信息:

安装测试数据:

等待安装完毕:

Tips:建议选择PHP5.3X版本

设计

数据结构的设计

编码的设计

典型的编码,分成两大方向:二次开发,基于框架开发

二次开发:在已有的产品(业务逻辑都已经实现)上做修改,升级的开发方式。

优点:速度快,通用业务逻辑已经被实现。

缺点:定制型差。

典型的产品:

电子商务:ecshop,ecmall,shopex,zen-cart,oscommerce ,麦进斗

内容管理:dedecms,帝国cms,phpcms,drupal,wordpress

论坛:phpwind,discuz

框架开发:

框架,没有实现业务逻辑,只实现了底层代码。

优点:不用写重复的底层功能代码,直接用即可,定制性强。

缺点:周期较长。

典型的框架:ThinkPHP,Yii,Ci,Zend-framework,symphony

编码的实现    30%

测试,调试

上线,生产环境

升级,维护

HTML+PHP混编的编程方式

PHP代码与HTML代码 出现在同一文件中。

典型的是:

上面是PHP先实现所有的业务逻辑,下边再是HTML决定显示样式。

或者直接利用PHP echo ,输出需要的HTML代码。

PHP Code

1
2
3
4
5
6
7
8
9

 

echo '<table>';
while ($row = mysql_fetch_assoc($result)) {
    echo '<tr>';
    echo '<td>',$row['Database'],'</td>';
    echo '<td>','<a href="table.php?dbname=',urlencode($row['Database']),'">查看表
    </a>','<a href="">删除库</a> ','</td>';
    echo '</tr>';
}
echo '<table>';

显示与逻辑相分离

将负责数据处理,业务逻辑处理的PHP代码,与负责显示效果处理的HTML(CSS,JS)等分开来进行管理。

典型的实现:将负责显示的HTML相关部分,拆分到独立的HTML中,在PHP处理完业务逻辑后,再将HTML代码加载到该文件中。

简单的说就是把原来混编的代码分开到2个页面。这2个页面要组合起来才能实现和原来一个混编文件一样的效果。

比如:match_list.html(展示)match_list.php(逻辑) require './match_list.html';

什么是模板template

template:参见match_list.html

使用html相关代码负责显示结构,使用动态代码php实现数据的展示,该类型的文件,在项目中,称之为模板文件,template.

要求:浏览器用户请求,必须请求负责逻辑功能的PHP文件才可以。

如何限制浏览器用户不能请求到html模板文件?

典型的实现方式2种:

  1. 将不允许用户浏览器访问到的文件,直接放置在网站的文档根目录之外(常用)。
  2. 将所有的模板文件集中到摸个目录中,在利用Apache的对访问权限的控制,设置某些目录是不可以访问的。

    典型的可以利用Apache的分布式配置文件.htaccess来实现。

    一:利用Apache的主配置文件httpd.conf来开启某个目录的对.htaccess文件的支持

    如下的配置段

    <Directory>

1
2

 

#表示对htdocs这个目录进行配置
<Directory "E:/Server/Apache/htdocs">

AllowOverride来允许目录中的.htaccess文件可用

1
2
3
4
5

 

#表示对htdocs这个目录进行配置
<Directory "E:/Server/Apache/htdocs">
#AllowOverride值为ALL,表示完全允许
    AllowOverride All
</Directory>

Tips:针对目录的设置,在当前目录及其后代目录都会生效。

二:利用.htaccess来设置目录的访问权限

在指定目录内,创建一个.htaccess    templates目录内:增加Deny from All

1
2

 

.htaccess
Deny from All

MVC的分层方式

场景:分析读取数据的部分,PHP的实现逻辑

典型的,数据的处理(增删改查),可能会在不同的业务逻辑中,反复的出现。应该将相同的数据处理部分,提取出来,需要的时候调用。

在业务逻辑处理,将数据处理的部分,单独拿出来。

PHP+HTML混编文件由HTML(显示部分)和PHP(业务逻辑部分)构成,业务逻辑部分又可以划分为业务流程和数据处理部分。

以上的项目的拆分分工方式称之为mvc的设计理想。

M:Model,模型,实现主要的业务逻辑,数据的处理

V: View,视图,主要负责显示部分

C:Controller,控制器,控制整体的流程进度

如果按照MVC来设计项目

用户浏览器去请求某个功能的控制器。

该控制还需要通过当前所要完成的功能,去调用模型来得到数据处理。

该控制还需要判断当前是否需要显示,去调用视图层模板来完成显示。

参考代码:控制(match_list.php)

1
2
3
4
5
6
7
8
9
10

 

<?php
//比赛列表的控制器文件,Controller
header('Content-Type:text/html; charset=utf-8');

//需要比赛数据
//调用模型match_data.php获得数据
require './match_data.php';

//调用视图,显示结果
require './template/match_list.html';

模型(match_data.php)

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

 

<?php
//完成比赛的数据处理,Model,模型

//引入mysqldb类
require './MySQLDB.class.php';
//实例化对象
$db = new MySQLDB(array('pass'=>'1234abcd', 'dbname'=>'itcast'));
//搜索
if (!empty($_POST)) {
    //搜索
    //判断$_POST内的数据,去拼凑sql中的where条件部分
    $where = 'where ';
    //拼凑名字部分
    $where .= "p1.stu_name like '%{$_POST['name']}%' or p2.stu_name like '%{$_POST['name']}%'";
} else {
    //查询所有的比赛信息
    $sql = "select p1.stu_id as p1_id, p2.stu_id as p2_id, p1.stu_name as p1_name, m.match_result, p2.stu_name as p2_name, m.match_time from `match` as m left join player as p1 on m.player1=p1.stu_id left join player as p2 on m.player2=p2.stu_id;";
    $rows = $db->fetchAll($sql);
}

视图(match_list.html)

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14

 

<!-- 比赛列表的视图模板文件,view,视图层功能文件 -->
比赛公告板
<hr>
<?php if (!empty($rows)) :?>
    <?php foreach($rows as $row) :?>
    <a href="player.php?id=<?php echo $row['p1_id'];?>"><?php echo $row['p1_name'];?></a>   
    <?php echo $row['match_result'];?>  
    <a href="player.php?id=<?php echo $row['p2_id'];?>"><?php echo $row['p2_name'];?></a> 
    <?php echo $row['match_time'];?>
    <br>
    <?php endForeach;?>
<?php else:?>
    对不起,没有记录!
<?php endIf;?>

分层的目的在于管理代码和代码重用。

mvc设计思想

mvc框架,基于mvc设计思想实现的框架,称之为MVC框架。

Model,模型部分

模型类

典型的模型的应该如何实现?

模型,完成主要的业务逻辑处理(数据的处理)

典型的模型时:为需要操作的每类数据表,会独立的建立一个模型类进行管理。

基于该表的每个操作,应该对当前模型类的一个方法。

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

 

<?php
//MatchModel.class.php
/**
 * 用于操作match表的模型类
 */
class MatchModel {

/**
     * 用于获取比赛列表的方法
     *
     * @return array 当前的列表需要的二维数组数据
     */
    public function getList() {
        //引入mysqldb类
        require './MySQLDB.class.php';
        //实例化对象
        $db = new MySQLDB(array('pass'=>'root', 'dbname'=>'itcast'));   
        //查询所有的比赛信息
        $sql = "select m.match_id, p1.stu_id as p1_id, p2.stu_id as p2_id, p1.stu_name as p1_name, m.match_result, p2.stu_name as p2_name, m.match_time from `match` as m left join player as p1 on m.player1=p1.stu_id left join player as p2 on m.player2=p2.stu_id;";
        return $db->fetchAll($sql);
    }
}

控制器中,需要得到模型对象,调用相应方法,才能获得相应数据。

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12
13

 

<?php
//match_list.php
//比赛列表的控制器文件,Controller
header('Content-Type: text/html; charset=utf-8');

//需要比赛数据
//调用比赛Match模型获得数据
require './MatchModel.class.php';
$model_match = new MatchModel;
$rows = $model_match->getList();

//调用视图,显示结果
require './template/match_list.html';

练习:删除比赛

增加一个链接请求到删除比赛的流程控制的控制器文件。

修改列表视图,template/match_list.html

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

 

<!-- 比赛列表的视图模板文件,view,视图层功能文件 -->
比赛公告板
<hr>
<?php if (!empty($rows)) :?>
    <?php foreach($rows as $row) :?>
    <a href="player.php?id=<?php echo $row['p1_id'];?>"><?php echo $row['p1_name'];?></a>   
    <?php echo $row['match_result'];?>  
    <a href="player.php?id=<?php echo $row['p2_id'];?>"><?php echo $row['p2_name'];?></a> 
    <?php echo $row['match_time'];?>

<a href="match_del.php?id=<?php echo $row['match_id'];?>">删除</a>//增加删除链接
    <br>
    <?php endForeach;?>
<?php else:?>
    对不起,没有记录!
<?php endIf;?>

控制器

增加match_del.php控制器文件并完成相应功能的调用:

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12

 

<?php
//match_del.php
header('Content-Type: text/html; charset=utf-8');
//比赛删除的控制器

//调用模型将数据删除
require './MatchModel.class.php';
$model_match = new MatchModel;
$model_match->delById($_GET['id']);

//调用视图展示删除结果(直接跳转到列表功能即可)
header('Location: match_list.php');

模型

为MatchModel增加一个delById的方法

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

 

/**
     * 利用id删除
     *
     * @param $match_id
     *
     * @return bool
     */
    public function delById($match_id) {
        //引入mysqldb类
        require './MySQLDB.class.php';
        //实例化对象
        $db = new MySQLDB(array('pass'=>'root', 'dbname'=>'itcast'));

//删除语句
        $sql = "delete from `match` where match_id='{$match_id}'";
        return $db->query($sql);
    }

视图    该功能没有视图参与

基础模型类

为其他模型类提供基础代码的模型的基础类

Model.class.php

PHP Code

1
2
3
4
5
6
7

 

<?php
/**
 * 基础模型类
 */
 class Model {
 
 }

其他模型类

PHP Code

1
2
3
4
5
6
7
8
9

 

<?php
//MatchModel.class.php
require './Model.class.php';
/**
 * 用于操作match表的模型类
 */
 class MatchModel extends Model {
 
 }

在基础模型类中,增加可以获得MySQLDB类对象的方法

PHP Code

1
2
3
4
5
6
7
8
9

 

<?php
 class Model {
    protected function initDB() {
        //引入mysqldb类
        require './MySQLDB.class.php';
        //实例化对象
        $db = new MySQLDB(array('pass'=>'root','dbname'=>'itcast'));
    }
 }

应该在每次实例化模型类对象时,就完成MySQLDB类对象的初始化工作。

增加基础模型类的构造方法:

在初始化mysqlDB类对象保存到当前的一个属性上,可以保证在模型对象中都可以使用该属性:

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14

 

<?php
 class Model {
    protected $db;//初始化成功的MySQLDB类的对象
    public functin __construct() {
        //初始化数据库操作对象
        $this->initDB();
    }
    protected function initDB() {
        //引入mysqldb类
        require './MySQLDB.class.php';
        //实例化对象
        $this->db = new MySQLDB(array('pass'=>'root','dbname'=>'itcast'));
    }
 }

模型中,使用$this->db即可操作到当前mysqlDB类对象。

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

 

//MatchModel.class.php
    /**
     * 利用id删除
     *
     * @param $match_id
     *
     * @return bool
     */
    public function delById($match_id) {
        //引入mysqldb类
        require './MySQLDB.class.php';
        //实例化对象
        $db = new MySQLDB(array('pass'=>'root', 'dbname'=>'itcast'));

//删除语句
        $sql = "delete from `match` where match_id='{$match_id}'";
        return $this->db->query($sql);//$this->db
    }

最终结构模型:

view,视图层

利用模板引擎技术,搭建性能,语法更加快速,简洁的视图层语法。

Smarty,就是模板引擎技术

使用PHP的流程控制的标签语法,来完成模板部分

PHP Code

1
2
3
4
5
6
7
8
9
10
11

 

<?php if (!empty($rows)) :?>
    <?php foreach($rows as $row) :?>
    <a href="player.php?id=<?php echo $row['p1_id'];?>"><?php echo $row['p1_name'];?></a>   
    <?php echo $row['match_result'];?>  
    <a href="player.php?id=<?php echo $row['p2_id'];?>"><?php echo $row['p2_name'];?></a> 
    <?php echo $row['match_time'];?>
    <br>
    <?php endForeach;?>
<?php else:?>
    对不起,没有记录!
<?php endIf;?>

Controller,控制器

将同一个模块的操作,整理到一个控制器文件内,将控制器语法oop化

增加模块的控制器文件,module

PHP Code

1
2
3
4
5
6
7
8
9

 

<?php
//match_controller.php
//所有的关于比赛模块功能代码

//比赛列表

//比赛删除

//其他比赛功能

一个文件多个功能,如何判断,当前用户浏览器,需要执行哪个功能?

要求用户在请求时,携带能够标识当前操作的参数才可以,入股没有参数,则认为是默认动作:

例如:

列表:    match_controller.php?a=list

删除:    match_controller.php?a=del

默认:    match_controller.php?a=list

PHP Code

1
2

 

//先确定用户所传递的参数
$action = isset($_GET['a']) ? $_GET['a'] : 'list';

判断action的值:

PHP Code

1
2
3
4
5

 

if ($action == 'list') {
    echo 'match list<br>';
}elseif ($action == 'del') {
    echo 'match delete<br>';
}

在相应的部分执行正确的控制器代码即可:

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

 

if ($action == 'list') {
    //echo 'match list<br>';
    //需要比赛数据
    //调用比赛Match模型获得数据
    require './MatchModel.class.php';
    $model_match = new MatchModel;
    $rows = $model_match->getList();
    //调用视图,显示结果
    require './template/match_list.html';

//比赛删除
elseif ($action == 'del') {
    //echo 'match delete<br>';
    //调用模型将数据删除
    require './MatchModel.class.php';
    $model_match = new MatchModel;
    $model_match->delById($_GET['id']);
    //调用视图展示删除结果(直接跳转到列表功能即可)
    header('Locaton: match_list.php');
}

将来模板内生成的连接地址,就成为controller.php?a=action

1
2
3
4
5
6

 

//match_list.html
<a href="MatchController.php?a=del&id=<?php echo $row['match_id'];?>">删除</a>

//match_controller.php
//调用视图展示删除结果(直接跳转到列表功能即可)
header('Location: match_controller.php?a=list');

Tips:三个模块

模板(muban),Template,结构有html代码充当,而数据由动态代码(PHP)充当的负责展示文件。

模型(moxing),Model,mvc中负责处理数据,完成业务逻辑的部分

模块(mokuai),Module,几个相关的功能的集合,一个包含了多个动作的控制器文件。

控制器类

将模块的控制器类文件,由一个类的对象来实现。

结果:

模块控制器文件    控制器类文件

每个功能        控制器类一个方法

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

 

<?php
/**
 * 比赛管理模块的控制器类
 */
 class MatchController {
    /**
     * 比赛列表动作
     */
     public function listAction() {
     }
     
     /**
      * 比赛删除动作
      */
     public function delAction() {
     }
 }

实现原来的业务逻辑即可

现在的执行功能就是调用控制器对象的方法,如何调用?

实例化控制类对象,一句当前的请求参数调用对象方法。

增加一个额外的用于实例化控制器类对象的代码,调用控制器对象方法

入口文件

进入到项目内,使项目的代码可以运转起来

PHP Code

1
2
3
4
5
6
7
8
9
10
11

 

<?php
//index.php
//项目的入口文件
require './MatchController.class.php';
//得到控制器类对象
$controller = new MatchController;
//根据请求a参数,决定调用哪个方法
$a = isset($_GET['a']) ? $_GET['a'] : 'list';
$action = $a.'Action';//拼凑方法名
//调用
$controller->$action();//可变方法名

练习,学生列表

控制器

增加一个学生管理模块的控制器类

内增加一个学生列表list功能

PHP Code

1
2
3
4
5
6

 

<?php
class StudentController {
    public function listAction() {
    
    }
}

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12

 

<?php
class StudentController {
    public function listAction() {
        //载入学生模型
        require './StudentModel.class.php';
        $model_student = new StudentModel;
        //得到学生列表数据
        $list = $model_stuent->getList();
        //调用一个学生列表视图模板,展示页面
        require './template/student_list.html';
    }
}

模型

增加一个学生模型类

StudentModel.class.php

PHP Code

1
2
3
4
5
6
7

 

<?php
require './Model.class.php';
class StudentModel extends Model {
    public function getList() {
        return $this->db->fetchAll('select * from student');
    }
}

视图

增加学生类表模板文件

student_list.html

PHP Code

1
2
3
4
5
6

 

<h1>学生列表</h1>
<?php foreach($list as $row) : ?>
    <?php echo $row['stu_name'];?>
    <?php echo $row['gender'];?>
    <?php echo $row['height'];?>
<?php endForeach; ?>

请求到该工作,则可以执行

增加一个入口文件

student.php

PHP Code

1
2
3
4
5
6

 

<?php
//项目入口文件
require './StudentController.class.php';
//得到控制器类对象
$controller = new StudentController;
//根据请求a参数,决定调用哪方法

单一入口

此时,会出现功能几乎完全一致,只有当前需要的控制器类不一样的入口文件。

使用一个入口文件,实现对所有的控制器类的加载,实例化工作(单一入口)

确定,入口文件需要的控制器类名即可,类似于参数a,在增加一个请求的参数c,表示,当前浏览器用户,需要看到的控制器名。

学生列表:index.php?c=Student&a=list

比赛列表: index.php?c=Match&a=del

入口文件的处理

PHP Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

 

<?php
//项目的入口文件
//确定请求的参数
//根据c,确定当前的控制器类标识
$c = isset($_GET['c']) ? $_GET['c'] : 'Match';
//根据请求a参数,决定调用哪个方法
$a = isset($_GET['a']) ? $_GET['a'] : 'list';
//载入控制器类文件,并得到控制器类对象
$controller_name = $c.'Controller';
require './'.$controller_name.'.class.php';
//得到控制器类对象
$controller = new $controller_name;//可变类名
//得到当前的方法
$action_name = $a.'Action';//拼凑方法名
//调用
$controller->$action_name();//可变方法名

测试:localhost/six/index.php?c=Student&a=list localhost/six/index.php?c=Match&a=list

PHP Code

1
2
3

 

<a href="index.php?c=Match&a=del&id=<?php echo $row['match_id'];?>">删除</a>

header('Location: index.php?c=Match&a=list');

强调:

有了单一入口,就要求,用户的所有的请求都要从单一入口文件请求到。

项目的布局

目录分成2个目录

体现框架代码和业务逻辑代码的区别

将基础模型,mysqlDB类定义文件放在框架代码:

将业务逻辑相应的控制器,模型,视图文件分别放在application目录中

入口文件,通常放置在站点根目录:

修改项目中使用的路径

PHP Code

1
2
3
4
5
6
7
8
9

 

目录结构
    /index.php   入口文件
    /application 应用程序目录
        /model      模型类目录
        /view       视图类目录
        /controller 控制器类目录
    /framework   框架代码目录
        /Model.class.php    基础模型类
        /MySQLDB.class.php  mysql数据库的操作类

从零开始之ecshop基础篇(17)的更多相关文章

  1. 2000条你应知的WPF小姿势 基础篇<1-7>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师,对C#和WPF有着极深的热情.最为出色的是他维护了两个博客:2,000Things You Should Know ...

  2. cocos2dx基础篇(17) 音乐音效SimpleAudioEngine

    [3.x]     (1)获取单例:sharedEngine() 改为 getInstance()     (2)实现了:音量的调节.     (3)修改了播放音效 playEffect() 的参数: ...

  3. 【Unity|C#】基础篇(17)——字符串处理(String/StringBuilder)

    [学习资料] <C#图解教程>(第25章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu. ...

  4. C#多线程之基础篇3

    在上一篇C#多线程之基础篇2中,我们主要讲述了确定线程的状态.线程优先级.前台线程和后台线程以及向线程传递参数的知识,在这一篇中我们将讲述如何使用C#的lock关键字锁定线程.使用Monitor锁定线 ...

  5. 2000条你应知的WPF小姿势 基础篇<15-21>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师,对C#和WPF有着极深的热情.最为出色的是他维护了两个博客:2,000Things You Should Know ...

  6. [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析

    [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析 标签: webkit内核JavaScriptCore 2015-03-26 23:26 2285 ...

  7. 《量化投资:以MATLAB为工具》连载(1)基础篇-N分钟学会MATLAB(上)

    http://blog.sina.com.cn/s/blog_4cf8aad30102uylf.html <量化投资:以MATLAB为工具>连载(1)基础篇-N分钟学会MATLAB(上) ...

  8. c# 扩展方法奇思妙用基础篇八:Distinct 扩展(转载)

    转载地址:http://www.cnblogs.com/ldp615/archive/2011/08/01/distinct-entension.html 刚看了篇文章 <Linq的Distin ...

  9. DOM系列---基础篇

    DOM系列---基础篇   DOM (Document Object Model) 即文档对象模型, 针对 HTML 和 XML 文档的 API (应用程序接口) .DOM 描绘了一个层次化的节点树, ...

随机推荐

  1. EXT layout

    1.Vbox createCenterPanel: function () { var pan = Ext.create('Ext.Panel', { height: '100%', title: ' ...

  2. sqlite支持的数据库类型

    http://www.sqlite.org/datatype3.html 默认只支持:NULL,INTEGER,REAL,TEXT,BLOB

  3. ListView设置setFooterDividersEnabled无效的原因

    参考文章:http://gundumw100.iteye.com/blog/1169065 我的情况: 高度设置为了wrap_content, 且外边有一个FrameLayout(只包含了listvi ...

  4. QWizard中运行时默认按钮显示英文问题

    QWizard中运行时默认按钮在编译前设计界面的时候是显示中文的,运行的时候就变成英文了.. 后来是发现国际化的时候有问题,解决办法如下: 在main.cpp里加: QTranslator* tran ...

  5. pytest学习笔记(二)

    继续文档的第二章 (一)pytest中可以在命令行中静态/动态添加option,这里没什么好讲的,略过... 这里面主要讲下如何试用skip/xfail,还有incremental(包含一些列的测试步 ...

  6. 慕课网-安卓工程师初养成-4-7 Java循环语句之 while

    来源: http://www.imooc.com/code/1420 生活中,有些时候为了完成任务,需要重复的进行某些动作.如参加 10000 米长跑,需要绕 400 米的赛道反复的跑 25 圈.在 ...

  7. sendmessage和postmessage的区别

    BOOL   PostMessage(          HWND   hWnd,             //   handle   of   destination   window        ...

  8. VC获取并修改计算机屏幕分辨率(MFC)

    //检测当前分辨率 int Width = GetSystemMetrics(SM_CXSCREEN); int Height = GetSystemMetrics(SM_CYSCREEN); DEV ...

  9. springMVC导出 CSV案例

    导出csv 第一步 Controller类里调用 OrderParamsVo 传入的参数 orderService.findBuyCSV 查询到要导出的信息 /** * 购买订单CSV * Order ...

  10. Linux操作系统下三种配置环境变量的方法——转载

    来源:赛迪网 作者:millio       现在使用linux的朋友越来越多了,在linux下做开发首先就是需要配置环境变量,下面以配置java环境变量为例介绍三种配置环境变量的方法. 1.修改/e ...