html vc doc,doc.html

VCMINI框架在线文档

body {

margin: 0;

padding: 0;

color: #3b3b3b;

font-family: 'YaHei Consolas Hybrid';

}

#hideBar {

width: 16px;

height: 100%;

position: fixed;

top: 0;

left: 183px;

background-color: #ddd;

z-index: 3;

}

#titleList {

width: 170px;

height: 100%;

margin: 0;

padding: 0 10px 0 20px;

position: fixed;

top: 0;

left: 0;

background-color: #ddd;

box-shadow: 5px 0 5px #888;

display: block;

z-index: 2;

overflow-y: auto;

}

#titleList li {

margin-top: 8px;

padding-bottom: 10px;

color: #444;

font-weight: bold;

text-align: center;

border-bottom: 1px #bbb solid;

list-style: none;

overflow-x: hidden;

text-overflow: ellipsis;

white-space: nowrap;

}

#titleList li a {

font-size: 18px;

}

#titleList li a:link {

color: #444;

}

#titleList li a:visited {

color: #444;

}

#titleList li a:hover {

text-shadow: 1px 1px 1px #3b3b3b;

cursor: pointer;

}

#logo {

width: 160px;

margin: 15px auto 15px auto;

border-bottom: 1px #3b3b3b solid;

display: block;

}

#contentList {

height: 100%;

padding: 0 20px;

position: fixed;

top: 0;

left: 0;

margin-left: 205px;

background-color: #eee;

overflow-y: auto;

z-index: 1;

}

.contentGroup {

padding: 20px 0;

border-bottom: 1px #ccc solid;

}

.contentGroup ul {

font-size: 18px;

}

.title {

margin: 0;

margin-bottom: 10px;

font-size: 25px;

font-weight: bold;

}

.content {

margin: 10px 0;

font-size: 20px;

}

.stepTitle {

font-size: 20px;

font-weight: bold;

}

.stepContent {

font-size: 18px;

list-style: decimal;

}

.stepContent li {

margin: 10px 0;

}

.syntax {

max-width: 1000px;

margin: 10px 0;

color: red;

font-size: 18px;

font-weight: bold;

overflow-x: auto;

display: block;

}

a {

text-decoration: none;

}

pre {

margin: 10px 10px;

padding: 5px 10px;

border: 1px #666 solid;

border-radius: 5px;

line-height: 35px;

background-color: #ddd;

display: inline-block;

}

框架简介 准备工作 框架配置 添加控制器 添加视图 链接静态文件 引入页面模板 引入js脚本 引入样式表 快速引入 获取前端数据 获取后端数据 输出后端信息 可用全局常量 开启/关闭防盗链 添加访问黑名单 使用日志 自定义错误 使用公共函数 载入类库 载入包 参数化查询与数据 连接/断开数据库 连接多个数据库 数据库query操作 数据库exec操作 数据库select操作 数据库update操作 数据库insert操作 数据库delete操作 使用数据操作模型 作者总结语

框架简介

VCMINI是一个入门级的轻量框架,它没有丰富的类库,从某种程度上说VCMINI不是一个好的MVC框架,但是它能够帮助你更好实现你的项目,使得你的资源能够统一管理,使得前后端传值变得简单,它拥有单一入口的路由功能和最基本的数据库操作类(未来版本将加入多类型数据库的支持),意味着你不应该抱着快速开发的想法来使用它,但它适合新手进行中小型项目的开发,可以为你带来一些方便,事实上只是因为作者水平太差 =~=。

支持VCMINI框架运行环境配置如下(已经过测试):

  • Apache2.0+/Nginx1.1+/IIS5.1+
    等多个主流web服务器引擎
  • PHP5.2+
    足够低的PHP版本要求,支持PHP7(如果你使用PHP5.6,你可能需要在php.ini把 always_populate_raw_post_data 设为 -1)
  • MySQL5.1+
    目前仅支持MySQL,未来会支持更多类型数据库

准备工作

在使用之前可能需要做一些准备工作,内容如下(内容可能不够准确或过时,如未及时更新最新方法,可自行搜索资料进行部分准备工作)

一、修改框架配置文件(如果你将框架文件放在服务器根目录则跳过此项)

  • 打开框架根目录中的config.php
  • 找到
    'basePath' => '/'
  • 修改
    /
    为放置框架的相对路径,如框架文件放在服务器根目录则无需修改,如框架文件放在服务器根目录的XXX文件夹中,此处应修改为
    /XXX/
    结果为
    'basePath' => '/XXX/'
  • 保存config.php
  • 更多配置项解析请点 框架配置

二、安装服务器引擎、添加PHP模块并启动(已安装和配置的跳过)

主流的服务器引擎有三种,Apache、Nginx、IIS,只提供支持框架运行的版本与官方下载链接,具体安装方法请自行查找,其它类型服务器引擎可在网上寻找安装教程和下载

安装配置完毕后启动服务器

三、安装数据库服务器并启动(已安装跳s过)

* 目前VCMINI只支持MySQL数据库,其它数据库支持会陆续添加

只提供支持框架运行的版本与官方下载链接,具体安装方法请自行查找

安装配置完毕后启动数据库服务器并配置数据库用户和密码、新建项目用的数据库(如果你要在框架中连接mysql的话)

四、开启服务器URL重写功能

  • Windows Apache 开启方法
    • 找到
      httpd.conf
      文件并打开,一般在Apache安装目录的conf文件夹中(以真实安装路径为准)
    • 找到
      #LoadModule rewrite_module modules/mod_rewrite.so
    • 将此行最前面的
      #
      去掉,如果不存在此行配置则添加进去
    • 找到以下内容,并将
      AllowOverride None
      设置为
      All
      AllowOverride All
      ,如果不存在则添加进去

      <Directory />

      Options +Indexes +FollowSymLinks +ExecCGI

      AllowOverride All

      Order allow,deny

      Allow from all

      Require all granted

      </Directory>

    • 保存
      httpd.conf
      文件
    • 重启服务器,如果使用集成环境可直接用集成工具重启,如为纯净安装则需要启动
      cmd
      ,切换路径到到Apache的安装目录的bin文件夹,在cmd界面中输入
      httpd -k restart
      (也可将此路径添加到系统环境变量方便在任何路径下调用httpd.exe)
  • Linux Apache 开启方法
    • Ubuntu系列系统
      • 在命令行运行
        sudo a2enmod rewrite
        开启rewrite模块
      • 找到
        apache2.conf
        文件并打开,一般在
        /etc/apache2/apache2.conf
        (以真实安装路径为准)
      • 找到以下内容,并将
        AllowOverride None
        设置为
        All
        AllowOverride All
        ,如果不存在则添加进去

        <Directory />

        Options FollowSymLinks

        AllowOverride All

        Require all granted

        </Directory>

      • 保存
        apache2.conf
        文件
      • 在命令行运行
        sudo service apache2 restart
        sudo /etc/init.d/apache2 restart
        重启Apache服务器 (以真实安装路径为准)
    • Redhat系列系统
      • 找到
        httpd.conf
        文件并打开,一般在
        /etc/httpd/conf/httpd.conf
        (以真实安装路径为准)
      • 找到
        #LoadModule rewrite_module modules/mod_rewrite.so
      • 将此行最前面的
        #
        去掉,如果不存在此行配置则添加进去
      • 找到以下内容,并将
        AllowOverride None
        设置为
        All
        AllowOverride All
        ,如果不存在则添加进去

        <Directory />

        Options FollowSymLinks

        AllowOverride All

        Require all granted

        </Directory>

      • 保存
        httpd.conf
        文件
      • 在命令行运行
        service httpd restart
        重启Apache服务器
  • Windows Nginx 开启方法
    • 找到
      nginx.conf
      文件并打开,一般在Nginx安装目录的conf文件夹中
    • 找到这段代码块

      location / {

      #省略已有内容

      }

    • 在代码块中加入

      if (!-f $request_filename) {

      rewrite (.*) {BASE}index.php;

      }

      ,{BASE}为放置VCMINI框架的位置,如果VCMINI被布置在二级目录

      /VCMINI
      中,那么{BASE}应该是
      /VCMINI/
      ,如果VCMINI被布置在根目录
      /
      中那么{BASE}应该是
      /
      ,结果为

      if (!-f $request_filename) {

      rewrite (.*) /index.php;

      }

    • 保存
      nginx.conf
      文件
    • 重新载入Nginx服务器配置,如果使用集成环境可直接用集成工具重启,如为纯净安装则需要启动
      cmd
      ,切换路径到到Nginx的安装目录,在cmd界面中输入
      nginx -s reload
      来重新载入配置(也可将此路径添加到系统环境变量方便在任何路径下调用nginx.exe)
  • Linux Nginx 开启方法
    • Ubuntu系列系统
      • 找到
        nginx.conf
        文件并打开,一般在
        /usr/local/nginx/conf/nginx.conf
        (以真实安装路径为准)
      • 找到这段代码块

        location / {

        #省略已有内容

        }

      • 在代码块中加入

        if (!-f $request_filename) {

        rewrite (.*) {BASE}index.php;

        }

        ,{BASE}为放置VCMINI框架的位置,如果VCMINI被布置在二级目录

        /VCMINI
        中,那么{BASE}应该是
        /VCMINI/
        ,如果VCMINI被布置在根目录
        /
        中那么{BASE}应该是
        /
        ,结果为

        if (!-f $request_filename) {

        rewrite (.*) /index.php;

        }

      • 保存
        nginx.conf
        文件
      • 重新载入Nginx服务器配置,在命令行运行
        sudo /usr/local/nginx/sbin/nginx -s reload
        重新载入配置文件 (以真实安装路径为准)
    • Redhat系列系统
      • 与Ubuntu系列系统配置方法一样
  • 其它服务器引擎的配置请根据网上教程操作,篇幅原因不做赘述

>至此,准备工作就完成了,你可以通过访问 主页 ,查看是否配置成功,如果成功则会跳转到主页面,否则会出现404错误

框架配置

你可以根据需求更改config.php配置文件

  • basePath
    : 框架所在的相对路径
  • debug
    : 是否开启调试(非调试模式将不显示部分错误)
  • logVisit
    : 是否开启访问日志记录(默认关闭)
  • logEvent
    : 是否开启事件日志记录
  • safetyChain
    : 是否开启防盗链功能
  • homePage
    : 主页控制器名称(默认Home)
  • errorTemplate
    : 显示错误信息的页面模板
  • barSuffix
    : 标题的后缀(可以为空)
  • keyWords
    : 网站关键字(用空格分割关键字)
  • descriptions
    : 网站简介(用空格分割关键字)
  • database
    : 数据库配置,可以写入多个配置数组,配置数组需要包含以下元素
    • dbType : 数据库类型(目前仅支持mysql)
    • dbHost : 数据库地址(本地为localhost)
    • dbPort : 数据库端口号(默认3306)
    • dbName : 数据库名称(已存在的数据库名称)
    • dbUser : 数据库用户名(不建议使用root用户)
    • dbPwd : 数据库密码
  • fileInfo
    : 文件类型配置,可以写入多个文件类型,通过配置文件类型使得文件链接更加方便,结构如下所示
    • 类型名
      : 访问链接附带的类型,如JavaScript类型的链接为http://www.xxx.com/Files/JavaScript/Jquery
      • suffix
        : 文件后缀,如js是js脚本的后缀
      • path
        : 文件路径(相对于框架目录的pubs文件夹的路径)
      • mime
        : 文件MIME类型,如text/javascript是js脚本的mime类型
  • resLink
    : 远程资源链接,可以写入不同的文件类型的远程链接,每次访问文件链接时都会检查是否存在于远程链接,如果存在则从远程链接中获取文件返回,结构如下所示
    • 类型名
      : 远程链接所指向的文件类型,需要与文件类型配置中相对应才能生效
      • 文件名 => 远程链接
        : 文件名通过链接访问文件时尾部文件名,如http://www.xxx.com/Files/JavaScript/Jquery,远程链接即被获取的远程地址的文件链接,如http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js

>至此,框架配置就基本完成了

添加控制器

我将引导你创建一个简易的控制器,控制器可以独立存在运行

控制器文件放置路径为

apps/controllers/
  • 在控制器目录中创建一个控制器文件,如
    Test.php
  • 写入

    <?php

    class Test extends Controller {

    public function index($uri) {

    echo 'This is a Test Controller!';

    }

    }

  • 保存
    Test.php
    文件
  • 访问该控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试
  • 如果访问出现了
    This is a Test Controller!
    则添加控制器成功

添加视图

载入视图语法:$this->load->view(视图文件名称)

我将引导你创建一个简易的控制器控制视图输出实例页面,视图必须只能由控制器来输出,控制器与视图可不同名称,组成的将是真正的页面【在阅读此部分前你需要把 添加控制器 部分的实践内容完成】

视图文件放置路径为

apps/views/
  • 打开控制器目录中的
    Test.php
    文件
  • 将index方法块中的代码清空写入
    $this->load->view('TestView');
  • 保存
    Test.php
    文件
  • 在视图目录中创建一个视图文件,如
    TestView.php
  • 在TestView.php中写入

    <!DOCTYPE html>

    <html>

    <head>

    <meta http-equiv='content-type' content='text/html' charset='utf-8'>

    <title>This is a Test Page</title>

    <style type='text/css'>

    html {

    color: #fff;

    background-color: #3b3b3b;

    text-align: center;

    }

    p {

    margin-top: 100px;

    font-size: 40px;

    font-weight: bold;

    }

    </style>

    </head>

    <body>

    <p>Welcome to VCMINI Frame!</p>

    </body>

    </html>

  • 保存
    TestView.php
    文件
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试
  • 如果访问出现了
    Welcome to VCMINI Frame
    则成功添加了一个完整页面

链接静态文件

链接模板: http://域名目录/Files/文件类型名/文件名

我将引导你如何链接静态文件

静态文件放置路径为

pubs/
,这个目录中存放各种类型的静态文件,由文件夹分类,每个类型的文件所在路径是在配置文件中配置好的,配置文件类型方法请参考 框架配置
  • 随意找一张png格式的图片,这张图片将作为本次的实验对象,它可以是存放在你电脑上的也可以是网上下载的,这里我找了一张
    logo.png
  • 通过查看配置文件的文件类型信息,我们知道png图片的路径为
    pubs/images/png/
  • logo.png
    放入该路径中
  • 访问Files控制器(Files控制器是已附带的),如 http://localhost/Files/Png/logo (实际以部署所在的域名或ip与目录为准),其中
    Png
    指的是文件类型定义中的类型名(一般首字母大写),其中
    logo
    就是这个
    logo.png
    图片的文件名,不包括后缀
  • 如果访问后页面出现
    logo.png
    这个图像则成功引入了图片文件

* 不仅png图片能够使用这种引入方法,其它静态文件也一样,只需要添加文件到目录然后更改链接中的文件类型名和文件名称即可

引入页面模板

引入模板语法: [template|模板文件名]

我将引导你如何引入页面模板【在阅读此部分前你需要把 添加视图 部分的实践内容完成】

页面模板文件放置路径为

apps/views/templates/
  • 在完成了添加视图的步骤情况下在模板目录创建一个
    TestTemplate.php
  • 写入
    <h1>Good!</h1>
  • 保存
    TestTemplate.php
    文件
  • 打开视图目录中的
    TestView.php
    ,在body块中加入
    [template|TestTemplate]
  • 保存
    TestView.php
    文件
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试
  • 如果访问后在Welcome to VCMINI Frame下方出现了
    Good!
    则成功添加了模板

* VCMINI框架中附带了一个Meta.php的模板文件,你可以修改它引入meta标签,里面的[keyWords]和[descriptions]会自动填入网站关键字与网站介绍

引入js脚本

语法: [js|脚本文件名1/链接1,脚本文件名2/链接2,...]

我将引导你如何引入js脚本文件【在阅读此部分前你需要把 引入页面模板 部分的实践内容完成】

JavaScript文件放置路径为

pubs/scripts/javaScript/
(实际以文件类型信息定义路径为准)

在VCMINI框架中在页面引入JavaScript脚本有两种方式

  • 在页面的head标签中写入script标签,将src指定为js文件的路径(路径需要使用VCMINI中的静态文件链接,如 <script type='text/javascript' src='http://www.xxx.com/Files/JavaScript/TestJS'></script> ,如不了解可参考 链接静态文件)
  • (推荐)使用以下方法引入
    • 在js目录中创建一个
      TestJS.js
    • 在TestJS.js中写入
      alert('JavaScript already running!');
    • 保存
      TestJS.js
    • 打开视图目录下的TestView.php文件
    • head
      标签中写入
      [js|TestJS]
    • 保存
      TestView.php
      文件
    • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试
    • 如果访问后出现了弹框显示
      JavaScript already running!
      则引入js成功

* 只要是视图部分都可使用此语法引入js文件

引入样式表

语法: [css|样式文件名1/链接1,样式文件名2/链接2,...]

我将引导你如何引入css样式表文件【在阅读此部分前你需要把 引入页面模板 部分的实践内容完成】

css样式表文件放置路径为

pubs/scripts/styleScript/
(实际以文件类型信息定义路径为准)

在VCMINI框架中在页面引入css样式表有两种方式

  • 在页面的head标签中写入style标签,将href指定为css文件的路径(路径需要使用VCMINI中的静态文件链接,如 <script type='text/css' href='http://www.xxx.com/Files/StyleScript/TestCSS'></style> ,如不了解可参考 链接静态文件)
  • (推荐)使用以下方法引入
    • 在css目录中创建一个
      TestCSS.css
    • 在TestCSS.css中写入

      body {

      background-color: #666;

      }

    • 保存
      TestCSS.css
    • 打开视图目录下的
      TestView.php
      文件
    • head
      标签中写入
      [css|TestCSS]
    • 保存
      TestView.php
      文件
    • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试
    • 如果访问后文字部分背景颜色变为
      较亮的颜色
      则引入css成功

* 只要是视图部分都可使用此语法引入css文件

快速引入

为了方便前端页面的构建,VCMINI提供了几个语句用于快速的引入一些标签块

  • [base]
    引入根目录(配置文件中的basePath)字符串,用于前端构造链接,如根目录为/temp/,则[base]Files/Png/logo 将被解释为 /temp/Files/Png/logo ,构造出一个能够被浏览器解释的链接
  • [title|页面标题名称]
    引入title标签,会附带上配置文件中配置的标题后缀,后缀设为空字符串则输出无后缀标题
  • [favicon|图标名称/链接]
    用于引入设置图标的link标签

获取前端数据

获取POST数据语法:getPost(post数据变量名)
获取GET数据语法:getGET(get数据变量名)
获取文件信息语法:getFile(file input的name值)

getPost
getGet
函数很简单,可直接使用

getFile
函数用来获取上传的文件信息,假设前端file input内容如下
 
   

<input type='file' name='TestFile' id='fsile'>


那么就可以使用

getFile('TestFile')
获取到文件信息数组,文件信息数组内容有如下元素
  • name
    被上传的文件名
  • type
    被上传文件的MIME类型
  • size
    被上传文件的大小
  • tmp_name
    被上传的文件所在临时目录

* 上传的文件不会直接保存,而是会存储在一个临时空间,一旦脚本执行完毕临时文件将被清除,如果要保存就需要将临时空间里的文件使用php函数move_uploaded_file移动到目标存储目录中,这个临时空间的路径就在获取到的文件信息的

tmp_name

获取后端数据

语法:[JsData]
语法:$this->load->view(视图文件名称, 后端数据)

在开发过程中我们经常需要把后端的数据或数据库查询处理等的数据送到前端显示,这里将引导你完成这个操作【在阅读此部分前你需要把 引入样式表 部分的实践内容完成】

  • 打开控制器目录的
    Test.php
    文件
  • 将index方法块中的代码替换为

    $params = array(

    'data1' => '123',

    'data2' => '456'

    );

    $this->load->view('TestView', $params);

  • 保存
    Test.php
    文件
  • 打开js目录的
    TestJS.js
    文件并清空
  • 写入
    alert(jsParams.data1 + '\n' + jsParams.data2);
  • 保存
    TestJS.js
    文件
  • 打开视图目录的
    TestView.php
    文件
  • 在[js|TestJS]前面插入一行
    [JsData]
    (必须在[js|TestJS]之前,否则将出现变量未定义错误)
  • 保存
    TestView.php
    文件
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,如果访问后出现弹框显示

    123

    456

    则获取成功

* 此语句在页面模板中不生效

输出后端信息

语法:[msg]
语法:showMsg(字符串/数字/数组)

为了调试方便,VCMINI提供了函数来支持后端消息输出到前端控制台(Console),我将引导你如何引入页面模板【在阅读此部分前你需要把 添加视图 部分的实践内容完成】

  • 打开控制器目录的
    Test.php
  • 在index方法块中的载入视图语句前面插入

    showMsg('Test Msg');

    showMsg($params);

  • 保存
    Test.php
    文件
  • 打开视图目录的
    TestView.php
    文件
  • 在head标签块中插入
    [msg]
  • 保存
    TestView.php
    文件
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,访问后按F12调出浏览器(建议chrome或firefox)的调试工具,如果在console选项卡中看见输出类似

    [\home\vcmini\www\apps\controllers\Test.php:10]

    Test Msg

    ----------------

    [\home\vcmini\www\apps\controllers\Test.php:11]

    array (

    'data1' => '123',

    'data2' => '456',

    )


    的内容则调用输出后端消息函数成功

* 参数可为字符串或数字或数组,其它类型数据需自行转换为字符串再输出

可用全局常量

VCMINI内有一些全局常量是可用的,如下所列

  • BASEDIR
    框架根目录(如果框架放在服务器根目录下此常量应为
    /
    )
  • BASEPATH
    框架根路径,是完整的绝对路径,如
    /home/vcmini/www/
  • APPSPATH
    框架apps目录完整绝对路径
  • CONPATH
    框架控制器目录完整绝对路径
  • VIEWPATH
    框架视图目录完整绝对路径
  • TEMPPATH
    框架页面模板目录完整路径
  • SYSPATH
    框架sys目录完整绝对路径
  • CLSPATH
    框架类文件目录完整绝对路径
  • CONFPATH
    框架配置文件(非主配置文件)完整绝对路径
  • PUBSPATH
    框架静态文件目录完整绝对路径
  • PROTOCOL
    当前所采用的协议类型,默认HTTP/1.1

开启/关闭防盗链

VCMINI框架中附带有基础的基于Session的防盗链功能,受保护的目录是静态文件目录

盗链指的是,假设你的站点中放置有你的图片资源,别人浏览了你的站点觉得你的站点中文章的图片挺不错,就直接复制图片链接贴到了自己的站点上,这样会导致以下问题

  • 文件将在其它站点被随意传播
  • 由于对方复制的不是你的文件而是链接到你服务器上文件的链接,这样其他人访问对方的网站加载到这个文件时实际上是从你的服务器上加载过去的,大量的访问会导致服务器性能的消耗甚至宕机

VCMINI框架中的防盗链机制可以达到使对方无法长期通过复制的链接访问到你的资源且其他人无法直接通过对方的链接访问你的资源,对方复制的链接被访问会产生403无权限访问错误

防盗链功能默认是开启的,你可以在配置文件将
safetyChain
设置为
false
来关闭它

添加访问黑名单

语法1:127.0.0.1 匹配完整ip
语法2:127.0.0.* 匹配前三位且第四位为任意数ip(任意位都可使用此方法)
语法3:127.0.0.[22-66] 匹配前三位且第四位为22到66之间数字的ip(任意位都可使用此方法)

VCMINI框架中附带有基础的基于IP地址的黑名单功能,黑名单能够阻止指定IP(如183.55.39.236)或指定IP(如183.55.39.*或183.55.39.[0-255])段的人无法访问你的站点,可用于防范那些恶意在你的站点中乱发信息捣乱的人或者屏蔽一部分地区或人的访问

黑名单文件所在路径为

sys/configs/banIP.php
,我将引导你操作这个黑名单文件
  • 打开
    banIP.php
    文件
  • 在新的一行里写入
    127.0.0.1
  • 保存
    banIP.php
    文件
  • 这里就成功将本地ip添加进了黑名单,你自己将无法访问了这个站点了,还有另外两种写法,参考上面的语法

使用日志

_log(字符串/数字/数组)

VCMINI框架中附带有基础的日志记录功能,日志记录主要能够记录错误日志和访问日志,访问日志的记录默认关闭(记录比较频繁访问量过多可能会产生大量log),一般记录的是错误日志,如果有访问者访问你的站点因为框架原因出错,错误日志中将会记录此次错误信息

日志文件放置路径为

sys/logs/

日志文件是一天记录为一个单独文件,文件的命名即为日志日期,错误日志与访问日志共同记录于同一个文件,无用日志可时常清理,打开日志文件后一行就是一条log记录了记录事件发生事件的访问ip以及发生的错误的详细情况,除此之外还提供了_log函数能够手动调用记录日志,语法如上

自定义错误

语法:showError(错误类型, 错误标题, 错误消息, 错误码, 错误模板名称, 是否隐藏错误来源, 自定文件路径, 自定行号);

VCMINI中的错误提示都使用了此函数,你也可以调用此函数输出错误内容,错误页面模板是可以自行定义的,VCMINI中自带了默认的default.php模板

错误模板放置路径为

sys/errorPages/
  • 打开控制器目录的
    Test.php
    文件
  • 在index方法块的第一行写入
    showError('error', 'Test Title', 'TestContent');
    或者
    showError('warning', 'Test Title', 'TestContent', 200, 'default', false, 'test', 66);
  • 保存
    Test.php
    文件
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,第一个语句访问后出现了一个报错页面,标题为
    Test Title
    ,内容为
    Test Content
    则输出自定义错误成功,更多用法请参照语法尝试

第一个参数有error与warning两种,具体与模板文件内的css定义有关,可参考错误模板目录的default.php制作你的错误模板,可通过修改配置文件修改全局错误模板

使用公共函数

VCMINI框架中定义了少量的公共函数,如下

  • getCookie(cookie变量名)
    用于获取对应变量名的cookie值
  • delCookie(cookie变量名)
    用于删除对应变量名的cookie值
  • getRawInput()
    用于获取php://input中的数据
  • setStatus(HTTP状态码)
    用于设置HTTP状态码,如setStatus(404)设置header为404 Not Found
  • getCurlHttpCode(URL地址)
    访问地址并返回HTTP状态码,如getCurlHttpCode('http://www.baidu.com/'),返回200,URL不可为调用该函数的文件,否则导致死循环
  • getConfig()
    获得配置文件数组
  • getConfigItem(配置项名称)
    获得配置项的值,如getConfigItem('barSuffix')获得配置中的标题后缀
  • setConfigItem(配置项名称, 配置项值)
    临时设置配置项的值,不会影响配置文件本身的值,如setConfigItem('barSuffix','VCMINI'),设置配置项的标题后缀为VCMINI
  • isDebug()
    判断是否开启了调试模式(配置项中的debug)
  • getClientIP()
    获取客户端IP地址
  • isSession(session变量名)
    判断是否存在某个session变量
  • getSession(session变量名, 是否不解开jsonz字符串)
    获取session值,如假设test是一个json字符串存在Session中,getSession('test', true)得到一个json字符串,如果不加true或设为false那么将得到一个经过decode的数组,如果test是个普通变量则直接返回session值
  • setSession(session变量名, session变量值)
    ,设置session变量,如setSession('test', 'HelloWorld')
  • delSession(session变量名)
    删除session变量,如果session变量名为
    -all-
    则会清除所有session变量
  • isResAllow()
    判断资源是否允许访问,允许返回true反之false
  • resLock()
    锁定静态资源,将无法访问静态文件资源
  • resUnlock()
    解锁静态资源,将解除锁定能够访问静态文件资源
  • convertGBK(字符串)
    将字符串内容转换为GBK编码
  • convertUTF8(字符串)
    将字符串内容转换为UTF-8编码

载入类库

$this->load->lib(类文件名称, 构造函数参数, 类文件路径[留空则为默认路径])

实际应用中肯定少不了引入其它类文件,我将引导你进行加载类库操作

类库文件放置路径为

sys/libs/
  • 假设类库路径中存在这样一个名为
    TestLib.php
    类文件,内容为

    <?php

    class TestLib {

    public function __construct($params) {

    $this->text = $params['text'];

    }

    public function test() {

    _log($this->text);

    }

    }

  • 打开控制器目录的
    Test.php
  • 在index方法块的第一行写入
    $TestLib = $this->load->lib('TestLib', array('text' => 'HelloWorld'));
  • 再输入一行
    $TestLib->test();
  • 保存
    Test.php
    文件
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,到日志目录查看今日日志,如果末尾多了一条
    HelloWorld
    的log信息则调用类方法成功

此方法不支持需要依赖其它类或有继承关系的类,如需支持请参考 载入包 方法

载入包

$this->load->package(包名称, 依赖文件名数组, 构造函数参数[留空则为空数组], 包文件夹路径[留空则为默认路径])

当一个类中有多个引入的文件或存在继承关系的情况下,使用载入类库方法将比较复杂,这时将使用载入包函数解决这种问题

包文件放置路径为

sys/packages/包名称/
  • 假设现在有一个名为
    TestPackage
    的包,那么在包目录中应该存在一个名为TestPackage的文件夹,该文件夹中存在一个主类文件TestPackage.php(主类名称必须与文件夹名包名一致)和一个依赖文件TestRelyon.php,这两个类存在继承关系,TestPackage类继承了TestRelyon类,两个文件的内容如下
    TestPackage.php

    <?php

    class TestPackage extends TestRelyon {

    }


    TestRelyon.php

    <?php

    class TestRelyon {

    public function test() {

    _log('Package Test');

    }

    }

  • 打开控制器目录的
    Test.php
    文件
  • 在index方法块第一行写入
    $TestPackage = $this->load->package('TestPackage', array('TestRelyon'));
  • 在下一行写入
    $TestPackage->test();
  • 保存
    Test.php
    文件
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,到日志目录查看今日日志,如果末尾多了一条
    Package Test
    的log信息则调用引入包以及调用类方法成功

参数化查询与返回数据

VCMINI中有简化数据库操作的类,基于PDO进行参数化查询,操作类中涉及的函数会在之后向导一一介绍,这里主要说明参数化查询应用与数据库操作后的数据返回类型,注意加了AL后缀的都是返回全部匹配的数据而为加AL后缀的都是只返回一行匹配数据

参数化查询的一大好处就是可以防止SQL注入问题,大大提高了安全性与可靠性,使用参数化查询时sql语句中的参数位置都需要使用英文的问号

?
来代替参数原本的位置,如
select * from test where id=?;
其中的问号就是参数所在位置,而这个参数数据就需要通过一个数组传入,如
array(66)
这就代表了一个由一个数字元素的一维数组,而
数组参数的顺序就是参数在SQL语句中从左至右的顺序
,具体使用语法请参考接下来的数据库操作向导

以下是返回的数据类型解释,实际应用请参照接下来的数据库操作向导

  • AS/AS-AL
    此参数表示返回一个正常的表结构数组(常用)
  • LINE
    此参数表示返回操作所影响的行数
  • NAMED/NAMED-AL
    此参数表示将匹配结果集中的每一行作为一个由列名索引的数组返回。如果结果集中包含多个名称相同的列,返回一个包含值的数组
  • NUM/NUM-AL
    此参数表示返回一个按顺序排号的数据数组
  • LAZY
    此参数表示将结果的每一行作为一个对象返回,此对象的变量名对应着列名
  • COL/COL-AL
    此参数表示将结果的下一行返回所需要的那一列
  • BOTH/BOTH-AL
    此参数表示将匹配结果的每一行作为一个由列号和列名索引的数组返回,从第 0 列开始
  • OBJ/OBJ-AL
    此参数表示将结果的每一行作为一个属性名对应列名的对象返回
  • BOUND/BOUND-AL
    此参数表示返回 true 且将结果集中的列值分配给通过 PDOStatement::bindParam() 或 PDOStatement::bindColumn() 方法绑定的 PHP 变量
  • CLASS/CLASS-AL
    此参数表示返回一个所请求类的新实例,映射列到类中对应的属性名
  • INTO/INRO-AL
    此参数表示更新一个请求类的现有实例,映射列到类中对应的属性名

连接/断开数据库

实例化语法:$db = $this->load->database(数据库配置名[可选,默认采用default配置])
连接语法:$db->connect(是否使用长连接[可选])
关闭语法:$db->disconnect()

在实际应用中数据库是不可或缺的,我将引导你如何在VCMINI框架中连接与断开数据库连接,目前仅支持MySQL的操作

* 在这之前请务必已经新建了一个至少拥有一个表的数据库且加入一些测试数据并已经在配置文件中对default的配置进行了修改,具体配置方法请参考 框架配置 的 database

  • 打开控制器目录的
    Test.php
    文件
  • 将index方法块中的内容清空
  • 在方法块第一行写入
    $TestDB = $this->load->database();
    (这个函数来自Loader加载器,有一个可选参数,如果你在配置文件中新增了一个配置内容而不是修改了default配置内容,此处应提供一个参数为你新增配置项的名称,此函数返回一个对应配置的数据库操作类实例,如新增了Test配置则为$this->load->database('Test');)
  • 在下一行写入
    $TestDB->connect();
    (这里可以提供一个参数,即是否使用长连接,默认为false,如果提供的参数是true则使用长连接,如$TestDB->connect(true),长连接能够使得该数据库连接持久化存在,当下次发生连接时连接速度将会很快,但相应的也会更消耗服务器内存,对于一些常用的部分建议用持久化连接)
  • 保存
    Test.php
    文件
  • 如果配置文件中的数据库配置正确,那么访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,没有出现错误只是
    空白页面
    的话就成功完成了数据库的连接,下一步进行数据库连接的断开
  • 再次打开
    Test.php
    文件
  • 在index方法块最后一行写入
    $TestDB->disconnect();
  • 再次访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,依然与上面情况一致的话则成功

至此,数据库的连接与断开操作已经完成,如果你的页面结果是需要来自同一服务器的不同数据库或不同服务器的不同数据库或不同类型的数据库(目前只支持单一类型mysql),那么可以参考下面的连接多个数据库向导

连接多个数据库

你的站点上的某些页面的数据可能需要来自不同数据库甚至不同服务器的数据库的数据杂合,这时使用这个功能会比较适合,至于使用到的语法则和 连接/断开数据库 的语法一样

* 在此之前你需要在配置文件的database中加入一个新的数据库配置信息,信息内容与default相仿,你可以尝试新建多一个至少拥有一个表的数据库且加入一些测试用数据,此时将新的数据库配置信息的dbName更改为新建的数据库名称保存即可

  • 假设配置文件中的database内容如下

    'database' => array(

    'default' => array(

    'dbType' => 'mysql',

    'dbHost' => 'localhost',

    'dbPort' => 3306,

    'dbName' => 'vcmini1',

    'dbUser' => 'vcmini',

    'dbPwd' => '123456'

    ),

    'Test' => array(

    'dbType' => 'mysql',

    'dbHost' => 'localhost',

    'dbPort' => 3306,

    'dbName' => 'vcmini2',

    'dbUser' => 'vcmini',

    'dbPwd' => '123456'

    )

    ),


    这里面有

    default
    Test
    两个数据库配置信息
  • 假设现在需要连接这两个数据库并分别取出他们的数据,
    vcmini1
    vcmini2
    数据库中都有一个叫
    test
    的数据表
  • 打开控制器目录中的
    Test.php
    文件
  • 将index方法块中的代码清空,写入以下代码

    $TestDB1 = $this->load->database();

    $TestDB2 = $this->load->database('Test');

    $TestDB1->connect(true);

    $TestDB2->connect(true);

    $result1 = $TestDB1->select('test');

    $result2 = $TestDB2->select('test');

    $TestDB1->disconnect();

    $TestDB2->disconnect();

    $params = array(

    'data1' => $result1,

    'data2' => $result2

    );

    showMsg($params);

    $this->load->view('TestView', $params);


    此示例必须已完成上面其它项目的实践内容才可用

  • 保存
    Test.php
    文件
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,访问后按F12打开调试工具,在控制台选项卡中如果看到类似以下内容(数据是自己定义的那些数据),则操作成功

    [D:\phpStudy\WWW\temp\apps\controllers\Test.php:18]

    array (

    'data1' =>

    array (

    0 =>

    array (

    'Id' => '1',

    'attrName' => 'testName1',

    'attrVal' => 'testVal1',

    ),

    ),

    'data2' =>

    array (

    0 =>

    array (

    'Id' => '1',

    'attrName' => 'testName2',

    'attrVal' => 'testVal2',

    ),

    ),

    )

数据库query操作

语法:$TestDB->query(SQL语句, 绑定的参数[可选,默认空数组], 返回的数据结果类型[可选,默认'AS-AL'])

我将引导你如何使用VCMINI框架中数据库query函数来执行SQL语句并返回数据结果

  • 打开控制器目录的
    Test.php
    文件
  • 将index方法块内的代码清空,写入以下代码

    $TestDB = $this->load->database();

    $TestDB->connect(true);

    $result = $TestDB->query('SELECT * FROM test where id=?', array(1), 'AS-AL');

    $TestDB->disconnect();

    showMsg($result);

    $this->load->view('TestView');


    此示例必须已完成上面其它项目的实践内容才可用

  • 保存
    Test.php
    文件
  • 其中query函数的第二个参数就是绑定到SQL上的参数,代表把数字1绑定到id=那也就是
    SELECT * FROM test WHERE id=1
    ,第三个参数与 参数化查询与返回数据 中的返回数据类型的AS-AL相对应,此参数可选,默认为AS-AL,此处语句意思为查询test表中所有字段且id为1的数据(语句可根据实际测试数据进行更改)
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,访问后按F12打开调试工具,在控制台选项卡中如果看到类似以下内容(数据是自己定义的那些数据),则操作成功

    [D:\phpStudy\WWW\temp\apps\controllers\Test.php:10]

    array (

    0 =>

    array (

    'Id' => '1',

    'attrName' => 'testName1',

    'attrVal' => 'testVal1',

    ),

    )

数据库exec操作

语法:$TestDB->exec(SQL语句)

与query不同的是它能够执行所有的SQL语句并且只返回影响的行数而非数据结果

  • 打开控制器目录的
    Test.php
    文件
  • 将将index方法块内的代码清空,写入以下代码

    $TestDB = $this->load->database();

    $TestDB->connect(true);

    $TestDB->exec('CREATE DATABASE testdb');

    $TestDB->disconnect();

  • 保存
    Test.php
    文件
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,访问后查看数据库列表,如果出现了一个名为
    testdb
    的数据库,则执行新建数据库语句成功

* 由于此函数并没有参数化查询处理,为了安全请尽量不要使用外来数据作为它的参数

数据库select操作

语法:$TestDB->select(表名称, 查询字段[默认*], where子句[默认为空], 绑定的参数[可选,默认空数组], 返回的数据结果类型[可选,默认'AS-AL'], 构造SQL的参数数组[可选])

我将引导你如何使用VCMINI框架中数据库select函数来查询数据,语法中第四个参数的值为构造SQL的参数数组,可用参数如下所示

  • distinct
    查询结果是否过滤掉重复记录,指定为true则为是,反之不指定即可
  • sort
    需要排序的字段和升降序指定,如id asc 就是按字段id正序排序,也可以指定多个字段进行排序,实际用法与SQL的order by子句用法相同
  • limit
    数据截段,如
    8,5
    代表截取第八个结果开始数获取五个结果

接下来就可以开始使用select函数查询数据库了,如下

  • 打开控制器目录中的
    Test.php
    文件
  • 将index方法块中的代码清空并写入以下代码

    $TestDB = $this->load->database();

    $TestDB->connect(true);

    var_dump($TestDB->select('test', '*', 'id=?', array(1)));

    $TestDB->disconnect();


    此示例必须已完成上面其它项目的实践内容才可用

  • 保存
    Test.php
    文件
  • 其中select函数的第三个参数为where子句,代码中意义为
    select * from test where id=1;
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,访问后如果出现类似以下的var_dump内容则执行select函数成功

    array(1) {

    [0]=> array(3) {

    ["Id"]=> string(1) "1"

    ["attrName"]=> string(9) "testName1"

    ["attrVal"]=> string(6) "testVal1"

    }

    }

数据库update操作

语法:$TestDB->update(表名称, 需要修改的字段, where子句[默认为空], 绑定的参数[可选,默认空数组], 构造SQL的参数数组[可选])

我将引导你如何使用VCMINI框架中数据库update函数来更改数据,此函数执行后仅返回影响的行数,语法中第五个参数的值为构造SQL的参数数组,可用参数如下所示

  • ignore
    是否忽略执行错误(一般用于避免修改后存在重复值报错的情况,只会忽略错误),指定为true则为是,反之不指定即可

接下来就可以开始使用update函数修改数据库数据了,如下

  • 打开控制器目录的
    Test.php
    文件
  • 将index方法块中的代码清空并写入以下代码

    $TestDB = $this->load->database();

    $TestDB->connect(true);

    echo $TestDB->update('test', 'attrVal=?', 'attrName=?',

    array('TestContent', 'testName1'));

    $TestDB->disconnect();


    此示例必须已完成上面其它项目的实践内容才可用

  • 保存
    Test.php
    文件
  • 以上代码的参数与select函数用法接近,可直接参考
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,访问后如果出现数字1则修改操作成功,如果数字为0则表示没有修改数据。实际代码以实际的测试数据为准

数据库insert操作

$TestDB->insert(表名称, 被插入的字段, 绑定的参数[可选,默认空数组], 构造SQL的参数数组[可选])

我将引导你如何使用VCMINI框架中数据库insert函数来插入数据,此函数执行后仅返回影响的行数,语法中第四个参数的值为构造SQL的参数数组,可用参数如下所示

  • ignore
    是否忽略执行错误(一般用于避免修改后存在重复值报错的情况,只会忽略错误),指定为true则为是,反之不指定即可

* insert函数中的绑定参数和其它函数有所不同,它可以是一个一维数组也可以是一个二维数组也就是说它可以是

array('test1', 'test2')
也可是
array(array('test1', 'test2'), array('test3', 'test4'))
,假设test数据表中仅有两个字段,那么前者就是往数据表的两个字段分别添加了一行数据,后者就是往数据表的两个字段分别添加了两行数据

接下来就可以开始使用insert函数往数据库插入数据了,如下

  • 打开控制器目录的
    Test.php
    文件
  • 将index方法块中的代码清空并写入以下代码

    $TestDB = $this->load->database();

    $TestDB->connect(true);

    echo $TestDB->insert('test', 'attrName, attrVal',

    array(array('testName2', 'testVal2'), array('testName3', 'testVal3')));

    $TestDB->disconnect();


    此示例必须已完成上面其它项目的实践内容才可用

  • 保存
    Test.php
    文件
  • 以上代码意义是往test表中的attrName和attrVal两个字段插入两条数据
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,访问后如果出现数字2则插入操作成功,如果数字为0则表示没有插入数据。实际代码以实际的测试数据为准

除此之外,操作类还提供了另一个插入函数insertFromTable,此函数用于将另一个表的数据插入到指定表中

语法:$TestDB->insertFromTable(被插入的数据表, 被插入的字段, 数据源表, 数据源表字段, where子句, 绑定的参数[可选,默认空数组], 构造SQL的参数数组[可选])

此函数用法如下

  • 打开控制器目录的
    Test.php
    文件
  • 将index方法块中的代码清空并写入以下代码

    $TestDB = $this->load->database();

    $TestDB->connect(true);

    echo $TestDB->insertFromTable('test', 'attrName,attrVal', 'test2', 'attrName,attrVal',

    'id=?', array(1));

    $TestDB->disconnect();


    此示例必须已完成上面其它项目的实践内容才可用

  • 保存
    Test.php
    文件
  • 以上代码的意义是将test2表中id为1的attrName与attrVal的数据插入到test表的指定字段中
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,访问后如果出现数字则插入操作成功,如果数字为0则表示没有插入数据。实际代码以实际的测试数据为准

数据库delete操作

$TestDB->delete(表名称, where子句, 绑定的参数[可选,默认空数组], 构造SQL的参数数组[可选])

我将引导你如何使用VCMINI框架中数据库delete函数来删除数据,此函数执行后仅返回影响的行数,语法中第四个参数的值为构造SQL的参数数组,可用参数如下所示

  • ignore
    是否忽略执行错误(一般用于避免修改后存在重复值报错的情况,只会忽略错误),指定为true则为是,反之不指定即可
  • 打开控制器目录的
    Test.php
    文件
  • 将index方法块中的代码清空并写入以下代码

    $TestDB = $this->load->database();

    $TestDB->connect(true);

    echo $TestDB->delete('test', 'id=?', array(1));

    $TestDB->disconnect();


    此示例必须已完成上面其它项目的实践内容才可用

  • 保存
    Test.php
    文件
  • 以上代码的意义是将test表中id为1的那行数据删除
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,访问后如果出现1则删除操作成功,如果数字为0则表示没有删除数据。实际代码以实际的测试数据为准

使用数据操作模型

$this->load->Model(模型名称, 模型路径[可选,可使用默认路径], 提供的参数[可选,默认为空数组])

在以上向导中我们已经尝试过使用数据库操作函数,而这个模型(Model)是数据处理模型,假如你需要制作一个个人博客,博客中有比如评论、回复、发布等操作,而这些都需要与数据库打交道,此时只通过控制器来对数据库操作处理这些请求就有些鸡肋了,你可能会在多个页面中使用到这些功能,为了达到数据处理的复用,也就有了模型这种东西,你可以在任一控制器中载入模型,然后直接调用模型的方法即可完成数据库操作并获得返回的数据,这样就无需在多个控制器中编写同样的数据库操作代码,那么,载入模型示例如下

模型文件放置路径为

apps/models/
  • 进入模型目录创建一个名为
    TestModel.php
    的文件
  • 写入以下代码

    <?php

    class TestModel extends Model {

    public function testMethod() {

    $TestDB = $this->load->database();

    $TestDB->connect(true);

    $result = $TestDB->select('test');

    $TestDB->disconnect();

    return $result;

    }

    }

  • 保存
    TestModel.php
    文件
  • 打开控制器目录的
    Test.php
    文件
  • 将index方法块中的代码清空写入以下代码

    $TestModel = $this->load->Model('TestModel');

    $result = $TestModel->testMethod();

    var_dump($result);

  • 保存
    Test.php
    文件
  • 访问Test控制器,如 http://localhost/Test (实际以部署所在的域名或ip与目录为准),或者点击 这里 测试,访问后如果var_dump输出了
    test数据表的数据结构
    则载入模型并操作成功

* 更多的操作只需要将之前的各种数据库操作向导中的语法应用在模型中使用即可,然后控制器只需要负责调用模型来获得数据并传送给前端处理显示

作者总结语

VCMINI这个框架最初是开发提供给自己替换自己个人博客的自制框架用的,功能上是绝对的比不上任一比较流行的框架的甚至有些不太像框架,但它的学习成本是非常低的,它是一个更加贴近于初学者的MVC框架,如果你希望了解一个MVC框架最基本的工作原理,也许它能给你答案,同样你也可以使用它做一些小项目小网站,以下是我的联系方式,欢迎给我建议哦!

 
   

QQ:912121616

Wechat:aidoukj

Email:vinlic@vinlic.com

/

一键复制

编辑

Web IDE

原始数据

按行查看

历史

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值