Yii2中事务的使用实例代码详解_php实例_脚本之家

by admin on 2019年11月26日

WordPress 从 2.5 的版本开始,增加了一个 shortcode API ,类似于 BBS 上的
BBCode , shortcode 也可以很方便的为文章或页面增加功能,并且 shortcode
的比起 BBCode 更加灵活和强大。下面 Kayo 为大家介绍一下 shortcode 。

最近突然发现博客的评论楼层有点问题,之前一直设置的是“在每个页面顶部显示新的评论”,也就是所谓的倒序显示评论,但是主题只支持顺序的评论楼层好,于是楼层和楼层号之间对不上。搜了一下在zww.me发现有实现的代码,但是放到博客之后无法正常工作,比如限制分页显示为25条的时候,文章只有一条评论时也显示的25楼。折腾了一下搞定了,做个记录,也供大家参考。

作为主题的制作者, 除了实现功能, 展示界面, 还有责任使主题灵活多变,
以满足更多人不同的需求.可能一些朋友曾为选用双栏主题 而烦恼过. 下面我们以
Classic 主题为例, 谈谈如何在主题中方便地切换单侧边栏和双侧边栏.
最后我会提供修改后的主题.

本文实例讲述了thinkPHP分页功能。分享给大家供大家参考,具体如下:

前言

一.shortcode 简介shortcode
可以让开发者通过以函数的形式创建宏内容来生成内容,或许这个概念看上去有点模糊,但实际上它是一个很简单而实用的功能,只要会编写基本的
PHP 函数,即可使用 shortcode ,下文会以实际的例子来说明 shortcode
的使用方法。

在主题文件 functions.php中找到$GLOBALS[‘comment’] =
$comment;在后面加上下面的代码:

添加管理选项后台处理首先, 我们要修改 function.php,
主要的处理工作都在这个文件里面, 如果主题没有这个文件, 就创建一个吧.
(没有 function.php 说明主题不支持 Widget, 可不是一个好习惯哦,
还是赶紧新建一个吧)我的处理包括 3 大块: 获取选项, 初始化,
标签页操作界面. 这里只创建一个公告栏, 包括两个选项 . 如果要添加更多选项,
也只需要代码中 3 个 TODO 的位置上追加一些代码而已. 当然,
你还需要改一下选项名称, 将 Classic 和 classic 全部之换掉.

interface ServiceInterFace:

一般我们做业务逻辑,都不会仅仅关联一个数据表,所以,会面临事务问题。

二.shortcode 形式shortcode
支持封闭标签和自闭标签,并且支持在标签内使用参数,至于 shortcode
具体是何种形式,这就决定于开发者怎样编写这个 shortcode 了。

/* 主评论计数器 */ global $commentcount,$wpdb, $post; if { //初始化楼层计数器 if ( get_option === 'desc' ) { //倒序 $comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = $post->ID AND comment_type = '' AND comment_approved = '1' AND !comment_parent"); $cnt = count;//获取主评论总数量 $page = get_query_var;//获取当前评论列表页码 $cpp=get_option;//获取每页评论显示数量 if  == 1 || ($page > 1 && $page == ceil { $commentcount = $cnt + 1;//如果评论只有1页或者是最后一页,初始值为主评论总数 } else { $commentcount = $cpp * $page + 1; } }else{ //顺序 $page = get_query_var-1; $cpp=get_option;//获取每页评论数 $commentcount = $cpp * $page; } }/* 主评论计数器 end */ if ( !$parent_id = $comment->comment_parent ) { $commentcountText = ''; if ( get_option === 'desc' ) { //倒序 $commentcountText .= --$commentcount . '楼'; } else { switch  { case 0: $commentcountText .= '沙发!'; ++$commentcount; break; case 1: $commentcountText .= '板凳!'; ++$commentcount; break; case 2: $commentcountText .= '地板!'; ++$commentcount; break; default: $commentcountText .= ++$commentcount . '楼'; break; } } $commentcountText .= ''; } }

要公告栏在首页上显示, 需要修改一下 index.php, 这个比较简单,
只是通过一些判断语句决定东西要不要显示出来而已. 当然,
你可以进行其他操作, 关键是获取到选项的值,
并对它们进行处理.其实可以分为两步:

StaticService 静态服务类:abstract AbProduct 抽象商品管理类:errorNum; switch{ case 0: $data['status'] = 0; $data['message'] = '收藏成功'; break; case 1: $data['status'] = 1; $data['message'] = '收藏失败'; break; case 2: $data['status'] = 2; $data['message'] = '已收藏'; break; case 3: $data['status'] = 3; $data['message'] = '未登陆'; break; case 4: $data['status'] = 4; $data['message'] = '缺少参数'; break; default: $data['status'] = 200; $data['message'] = '未知错误'; } return $data; }

数据库事务
,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID属性。事务是数据库运行中的一个逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。

[myshortcode]Some Content[/myshortcode] // 封闭标签[myshortcode] // 自闭标签[myshortcode title="example"] // 带有一个参数的自闭标签[myshortcode]内容[/myshortcode] // 标签内可以填写文本或 HTML[myshortcode]Content [myshortcodesecond] more content[/myshortcodesecond] // 也可以嵌套使用标签

然后在合适的位置加上以下代码输出楼层号

获取选项 (对每个 PHP 文件, 获取一次就行了,
可以在文件顶部执行)对选项进行处理

MemberModel 会员模型:

准备

三.shortcode 例子在使用 shortcode 前,首先必须在主题的 functions.php
文件中定义 shortcode ,例如:

修改之后的代码应该是这样的(以官方最新的 wp_list_comments:

可以使用管理项来控制侧边栏的数量, 在主题文件中获取侧边栏的数量,
对不同的数量作出不同的处理, 以达到在不同数量侧边栏之间切换的目的.

userId = getUserInfo; } /** * 实例化本类 * @return MemberModel */ public static function getInstance() { return StaticService::getInstance; } /** * 获取登录用户信息 * @param string $data 查询条件 * @return array */ public function getUser { if{ return $this->where("password"=>md5; if{ return TRUE; }else { return FALSE; } } /** * 校验用户的账号或者密码是否正确 * @param $data['username'] 用户名 * @param $data['password'] 密码 * return true or false */ public function checkUserPasswd{ $type = CheckType; $condition[$type] = array('eq',$data['username']); $condition['password'] = array('eq',md5; return $this->where; } /** * 网页登录校验token * @param token string * return bool */ public function checkToken{ return $this->autoCheckToken; } /** * 后台封号/解封 * param int $user_id */ public function changeStatus{ if{ return true; }else{ return false; } } protected function _before_check{ if(isset && empty{ $this->error['msg'] = '请输入用户名'; return false; } if(isset && empty{ $this->error['msg'] = '请输入昵称'; return false; } if(isset && empty{ $this->error['msg'] = '请输入真名'; return false; } if && empty{ $this->error['msg'] = '请输入邮箱'; return false; } if(isset && empty{ $this->error['msg'] = '请输入手机号码'; return false; } if(isset && empty{ $this->error['msg'] = '请输入密码'; return false; } if(isset && empty{ $this->error['msg'] = '请上传头像'; return false; } return true; }}

数据库引擎为innodb

function myshortcode_function($atts, $content = null){ // $atts 代表了 shortcode 的各个参数,$content 为标签内的内容 extract(shortcode_atts(array( // 使用 extract 函数解析标签内的参数 "title" => '标题' // 给参数赋默认值,下面直接调用 $ 加上参数名输出参数值 ), $atts)); // 返回内容 return ' '. $title .'  '. $content .'  ';} add_shortcode("msc", "myshortcode_function"); // 注册该 shortcode,以后使用 [msc] 标签调用该 shortcode
get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = $post->ID AND comment_type = '' AND comment_approved = '1' AND !comment_parent"); $cnt = count;//获取主评论总数量 $page = get_query_var;//获取当前评论列表页码 $cpp=get_option;//获取每页评论显示数量 if  == 1 || ($page > 1 && $page == ceil { $commentcount = $cnt + 1;//如果评论只有1页或者是最后一页,初始值为主评论总数 } else { $commentcount = $cpp * $page + 1; } }else{ //顺序 $page = get_query_var-1; $cpp=get_option;//获取每页评论数 $commentcount = $cpp * $page; } } /* 主评论计数器 end */ if ( !$parent_id = $comment->comment_parent ) { $commentcountText = ''; if ( get_option === 'desc' ) { //倒序 $commentcountText .= --$commentcount . '楼'; } else { switch  { case 0: $commentcountText .= '沙发!'; ++$commentcount; break; case 1: $commentcountText .= '板凳!'; ++$commentcount; break; case 2: $commentcountText .= '地板!'; ++$commentcount; break; default: $commentcountText .= ++$commentcount . '楼'; break; } } $commentcountText .= ''; } } extract; if ( 'div' == $args['style'] ) { $tag = 'div'; $add_below = 'comment'; } else { $tag = 'li'; $add_below = 'div-comment'; }?> <  >      %s says:'), get_comment_author_link ?> comment_approved == '0') : ?>  
       $add_below, 'depth' => $depth, 'max_depth' => $args['max_depth']))) ?>     
// 侧边栏数量, 默认为单侧边栏$options['sidebar'] = 1;// 获得最新提交的值$options['sidebar'] = $_POST['sidebar'];  >  > .

ProductModel 商品模型:

本文使用的yii版本为2.0.5,只要是2.0以上就没有问题

把上面的代码添加到 functions.php 中,一个简单的 shortcode
便创建好了,我们可以通过 [msc][/msc]标签调用该 shortcode ,如:

添加 Widget 支持

where; } /** * 商品列表 * @param string $limit 查询条数 * @param array $data 查询条件 * @return array 二维数组 */ public function getProList{ $condition['onsale'] = array('eq', $data['onsale']); //是否上架 $condition['status'] = array('eq', $data['status']); //状态 $condition['type'] = array; //分类 if && isset{ $return =$this->where->limit->order->select(); }else{ $return =$this->where; } return $return; } /** * 添加商品 * @param array $data * @return int */ public function addProduct{ return $this->add; } /** * 删除商品 * */ public function delProduct{ $condition['id'] = array; return $this->where; } /** * 修改商品 * @param string|int $id * @param array $data * @return */ public function editProdcut{ $condition['id'] = array; return $this->where->save; } public function getProductInfo{ if || !isset($product['product_id'])){ return array(); } $info = $this->getProOne($product['product_id']); $product['name'] = $info['name']; $product['store_id'] = $info['store_id']; $product['price'] = $info['price']; $product['m_price'] = $info['m_price']; return $product; }}

运行环境为PHP7.0.0,Mysql5.6

[msc title="欢迎"]这是独立博客 Kayo's Melody ,欢迎来到本博客[/msc]

因为要在单侧边栏和双侧边栏中切换, 所以我们需要对不同的两种模式定义两个
Widget 初始化的分支.这里比较特殊, 为了在代码中正确获取 Widget 信息,
就算是单侧边栏也需要起一个别名. 就像代码中的 Sidebar_single.
当侧边栏个数为 1 时, 登记 Sidebar_single. 当侧边栏个数为 2 时, 登记
Sidebar_top 和 Sidebar_bottom.

ProductManage 商品管理类:

Yii中的事务

在文章或页面内容中输入上面的调用,可以在相应的位置输出一段欢迎语句,在
style.css 中定义相应的 CSS ,即可为短代码赋予样式。

// Widgets$options = get_option; // 单侧边栏if(function_exists && $options['sidebar'] == 1) { register_sidebar(array( 'name' => 'Sidebar_single', 'before_widget' => '
getCollectList; $showpage = create_pager_html($list['total'],$page,$limit); $this->assign; $this->display(); } public function cancelCollect(){ $ids = field; $return = ProductManage::getInstance()->cancelProductCollect; exit; }}
/*** 测试事务*/public function actionTest(){//创建事务$tr = Yii::$app->db->beginTransaction();try {for{$test = new Areas();$test->name = 'name'.$i;$test->sort=1;if{echo "save $i | ";}}$test = new Areas();$test->name = 'ab'.$i;$test->sorta=1; //写入不存在的字段if{"save fail"; //如果没有写入就输出}//提交$tr->commit();} catch  {//回滚$tr->rollBack();echo "rollback";}}

save 1 | save 2 | save 3 | rollback

Kayo 简略的介绍了 WordPress 的短代码 功能,主要是介绍了 shortcode
的主要概念和使用方法。在本文中, Kayo 将会更加详细的介绍一下 shortcode
中较为重要的 API ,希望有助于各位开发较为复杂的 shortcode 。

‘, ‘after_widget’ => ‘

functions.php 分页函数:

注意,因为最后的数据没有插入成功,触发了事务的回滚,所以数据表没有新增数据产生。

四.函数 add_shortcode

‘, ‘before_title’ => ‘

 $maxpage) ? $maxpage : $total; $page = intval; if ($page < 1 || $page > $total) $page = 1; $pages = '上一页'; if ($page > 4 && $page <= $total - 4) { $mini = $page - 3; $maxi = $page + 2; } elseif  { $mini = 2; $maxi = $total - 2 < 7 ? $total - 2 : 7; } elseif  { $mini = $total - 7 < 3 ? 2 : $total - 7; $maxi = $total - 2; } for ($i = 1; $i <= $total; $i++) { if  { $pages .= '' . $i . ''; } else { $pages .= '' . $i . ''; } if  { $i = $total - 2; $maxi = 0; } if (($i == 2 or $total - 2 == $i) && $total > 10) { $pages .= ''; } if  { $i = $mini; $mini = 0; } } $pages .= '下一页共' . $totalcount . '条 / ' . $total . '页 '; return $pages;}

触发事务回滚的原因是代码出现了异常。

该函数用于注册一个 shortcode ,它有两个参数:短代码名与 shortcode
处理函数名,引用上文的例子:

‘, ‘after_title’ => ‘

‘ )); // 双侧边栏} else if(function_exists && $options[‘sidebar’] ==
2) { register_sidebar(array( ‘name’ => ‘Sidebar_bottom’,
‘before_widget’ => ‘

‘, ‘after_widget’ => ‘

‘, ‘before_title’ => ‘

更多关于thinkPHP相关内容感兴趣的读者可查看本站专题:《ThinkPHP入门教程》、《thinkPHP模板操作技巧总结》、《ThinkPHP常用方法总结》、《codeigniter入门教程》、《CI框架进阶教程》、《Zend
FrameWork框架入门教程》及《PHP模板技术总结》。

处理数据失败

function myshortcode_function($atts, $content = null){ // $atts 代表了 shortcode 的各个参数,$content 为标签内的内容 extract(shortcode_atts(array( // 使用 extract 函数解析标签内的参数 "title" => '标题' // 给参数赋默认值,下面直接调用 $ 加上参数名输出参数值 ), $atts)); // 返回内容 return ' '. $title .'  '. $content .'  ';} add_shortcode("msc", "myshortcode_function"); // 注册该 shortcode,以后使用 [msc] 标签调用该 shortcode

‘, ‘after_title’ => ‘

‘ )); register_sidebar(array( ‘name’ => ‘Sidebar_top’,
‘before_widget’ => ‘

‘, ‘after_widget’ => ‘

‘, ‘before_title’ => ‘

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

一般来讲,我们的运行中的代码是不会出现这种明显的异常,这种异常会在开发测试过程中消灭掉。

msc 即为短代码名,以后在写文章或页面时可以直接使用 [msc][/msc]
标签调用该短代码,而 “myshortcode_function”
即为例子中的短代码处理函数的名称。下面重点分析短代码处理函数。

‘, ‘after_title’ => ‘

‘ ));}

修改侧边栏结构

首先要明确, 我们现在需要双侧边栏结构. 怎样将双侧边栏变为单侧边栏呢?
只要将前一个侧边栏的结束标签和后一个侧边栏的开始标签删除,
两个侧边栏就合并为一个侧边栏了. 单纯的文字很难将我的想法和实现表达出来,
你可以接着看下面的代码和示例图片.

OK, 这就是侧边栏代码结构了. 它可以完美得实现单双侧边栏间的切换.
但它是怎么工作的呢? 我将在后面用图片列出它的 6
种可能出现的状态.因为主题已经支持 Widget 了, 所以代码中 function_exists
=== true, 则 !function_exists === false.记得添加 Widget
支持时写的代码吗? 侧边栏为 1 时 sidebar_single 有效, 侧边栏为 2 时,
sidebar_top 和 sidebar_bottom 有效. 这是贯穿整个思路的关键.

红色: 表示选中代码的值是 false, 不通过 绿色: 表示选中代码的值是 true,
通过 蓝色: 表示选中部分将被选用的 widgets 所取代 灰色:
表示选中部分代码将会失效

状态一: 单侧边栏, 没使用 Widget

状态二:双侧边栏, 没使用 Widget

状态三: 单侧边栏, 使用 Widget

状态四: 双侧边栏, 顶部侧边栏使用 Widget

状态五: 双侧边栏, 底部侧边栏使用 Widget

状态六: 双侧边栏, 顶部和底部侧边栏都使用 Widget

而真正造成数据需要回滚的是我们的某个业务出现问题,导致没有写入部分的数据。

五.短代码处理函数

/*** 测试事务*/public function actionTest(){//创建事务$tr = Yii::$app->db->beginTransaction();try {for{$test = new Areas();$test->name = 'name'.$i;$test->sort=1;if{echo "save $i | ";}}$test = new Areas();$test->name = null; //数据库设计name不能为空,人为造成写入失败。$test->sort=1; //写入不存在的字段if{echo "save fail"; //如果没有写入就输出}//提交$tr->commit();} catch  {//回滚$tr->rollBack();echo "rollback";}}

shortcode 处理函数是一个 shortcode 的核心, shortcode 处理函数类似于
Flickr,它们都接受特定参数,并返回一定的结果。 shortcode
处理器接受两个参数, $attr 和 $content , $attr 代表 shortcode
的各个属性参数,从本质上来说是一个关联数组,而 $content 代表 shortcode
标签中的内容。

运行结果如下,数据库插入了三条数据。

如上面的例子,若在文章内作出调用,输出一段欢迎语句:

save 1 | save 2 | save 3 | save fail

[msc title=”欢迎”]这是独立博客 Kayo’s Melody
,欢迎来到本博客[/msc]当文章显示时, WordPress 会注册所有的 shortcode
,如上面的 [msc] ,若 shortcode 中有属性参数和内容, WordPress
会把它们分离出来并解析,然后传递给该 shortcode
的短代码处理函数,处理后以处理函数输出的结果代替短代码原本的内容显示在文章内。

也就是说,如果因为业务逻辑导致某个数据表没有写入数据,也没有出现对应的回滚。

这时属性参数会并解析会关联数组并传递给 $attr ,如上面的例子中 $attr
的值为如下的一个关联数组:

/*** 测试事务*/public function actionTest(){//创建事务$tr = Yii::$app->db->beginTransaction();try {for{$test = new Areas();$test->name = 'name'.$i;$test->sort=1;if{echo "save $i | ";}}$test = new Areas();$test->name = null; //数据库设计name不能为空,人为造成写入失败。$test->sort=1; //写入不存在的字段if{throw new \yii\db\Exception(); //手动抛出异常,再由下面捕获。}//提交$tr->commit();} catch  {//回滚$tr->rollBack();echo "rollback";}}
array

运行结果如下,数据库没有插入新数据,事务被回滚。

在输出结果时,可以直接使用 $参数名 的形式进行输出,如例子中的情况即以
$title 输出该属性值。

save 1 | save 2 | save 3 | rollback

六.shortcode_atts

分散的数据处理

shortcode_atts
是一个很实用的函数,它可以为你需要的属性参数设置默认值,并且删除一些不需要的参数。

由于实际项目的复杂程度,导致我们的数据库操作分散在不同的Model中。

shortcode_atts() 包含两个参数 $defaults_array 与 $atts , $attr
即为属性参数集合, $defaults_array
是代表需要设置的属性默认值,举个例子:

所以,实际项目的代码不会是上面的样子。

$result = shortcode_atts( array( 'title' => '新标题', 'description' => '描述内容'), $atts );$attr 依然为array

由发号器得到用户的uid,发号器对应数据表增加一位数字

这时 $result 的结果为

把名字、性别、签名和上一步的uid写入用户信息表

array( 'title' => '新标题', 'description' => '描述标题')

初始化余额表没有传入uid导出没有写入数据

‘title’ 由于在 $defaults_array 有不同的值,因此以这个新的值为准更新了
‘title’ ,同时也增加了 ‘description’ 这个值。值得注意的是,
shortcode_atts() 会过滤 $defaults_array 中没有的属性,假如 $attr
中还有一个 ‘ohter’ 的属性,那么 $result 的结果仍然是上面的结果,因为
$defaults_array 中并没有 ‘other’
这个属性。当然,这里说的值只是属性的默认值,真正输出的值还是 shortcode
调用时填写的值。

//Controller/*** 测试事务-注册用户*/public function actionReg(){//获取请求$request = Yii::$app->request;//设定返回格式$response = Yii::$app->response;$response->format = \yii\web\Response::FORMAT_JSON; //返回json//测试代码,去掉验证身份步骤$name = $request->get;$gender = $request->get;$sign = $request->get;//测试代码,省略参数校验步骤$tr = Yii::$app->db->beginTransaction();try {//得到uid$uid = App::getSeNo();UserProfile::add($uid, $name, $gender, 1, $sign);$user_balance = UserBalance::initUserBalance; //提交数据} catch  {//回滚$tr->rollBack();return $e->getMessage(); //返回自定义异常信息}return $user_balance;}//UserProfile/*** 添加用户信息* @param $user_id* @param $nikename* @param $gender* @param $user_type* @param string $intro* @return UserProfile* @throws \Exception*/public static function add($user_id, $nikename, $gender,$user_type,$intro="") {$model = new UserProfile();$model->gender = $gender;$model->nikename = $nikename;$model->user_id = $user_id;$model->user_type=$user_type;$model->intro=$intro;$model->update_time = time();$insert =$model->insert{throw new Exception;}return $model;}//UserBalance/*** 初始化用户的可提现余额* @param $user_id*/public static function initUserBalance{$info=self::find()->where(['user_id'=>$user_id])->one{$model=new UserBalance();$model->user_id = $user_id;$model->price= "0";$model->update_time=time();$insert = $model->insert{throw new Exception;}$info=$model;}return $info->attributes;}

{"id":124,"user_id":1473179883,"price":"0","update_time":1473179883}

七.进一步解析属性与设置属性默认值

如果把初始化用户余额部分的user_id没有传递成功,返回的结果如下

extract()
函数用于进一步解析属性并设置属性默认值,其中一个功能是把各属性参数值赋予给一个形如
“$参数名” 的变量保存起来,方便调用,使用该函数配合 shortcode_atts()
就可以很安全的输出结果。这点的具体使用可以参见本文第一点“一.函数
add_shortcode”的例子。

"没有初始化用户余额"

另外,属性名中的大写字母在传递给处理函数前会先转化为小写字母,因此建议在编写属性名时直接使用小写字母。

我们可以针对具体情况定位到错误所在位置,及时修改。

事务

从上面的实际代码可以看出,创建了事务,只要在范围内,就算是引入的别的Model也能把异常NG返回,完成回滚操作。

一般情况下,整个Yii应用使用了同一个数据库连接,或者说是使用了单例。

而在yii\db\Connection中,又对事务对象进行了缓存:

class Connection extends Component{// 保存当前连接的有效Transaction对象private $_transaction;// 已经缓存有事务对象,且事务对象有效,则返回该事务对象// 否则返回nullpublic function getTransaction(){return $this->_transaction && $this->_transaction->getIsActive() ? $this->_transaction : null;}// 看看启用事务时,是如何使用事务对象的public function beginTransaction($isolationLevel = null){$this->open();// 缓存的事务对象有效,则使用缓存中的事务对象// 否则创建一个新的事务对象if (($transaction = $this->getTransaction {$transaction = $this->_transaction = new Transaction;}$transaction->begin;return $transaction;}}

因此,可以认为整个Yii应用,使用了同一个 Transaction 对象,也就是说,
Transaction::_level 在整个应用的生命周期中,是有延续性的。
这是实现事务嵌套的关键和前提。

以上所述是小编给大家介绍的Yii2中事务的使用实例代码详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图