zoukankan      html  css  js  c++  java
  • Yii2中mongodb使用ActiveRecord的数据操作

    概况

     Yii2 一个高效安全的高性能PHP框架。mongodb 一个高性能分布式文档存储NOSQL数据库。

    关于mongodb与mysql的优缺点,应该都了解过。

    mysql传统关系数据库,安全稳定、数据完整、资源文档完善、使用群体多、支持事物,V5.7后支持原生Json速度不逊mongodb、分布式主从集群刚刚的……

    mongodb新兴NOSQL数据库,Bson文档存储,支持原生Javascript、性能优异百千万数据不在话下、内置GridFS Sharding海量存储、热数据持久化、分片部署……

    参考:http://www.wtoutiao.com/p/19an83a.html

    那到底mysql与mongodb性能对比如何呢,什么时候选择mysql什么时候选择mongodb呢,网上有很多自己search吧,这里我们讲的是,将mongodb加入Yii2的扩展中,并使用经典的ActiveRecord操作数据。

    等等,再说下什么是ActiveRecord

    ActiveRecord之前呐,先要知道ORM(Object Relational Mapping 对象关系映射)用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的"虚拟对象数据库"。ActiveRecord就是一个典型的ORM。Yii2 提供了DAO (Data Access Objects 数据访问对象) ,可以方便的用$db->createCommand()完成任何数据库相关的任务,包括复杂的业务SQL语句。甚至执行速度比ActiveRecord快很多,但是在这个金(敏)钱(捷)社(开)会(发)时代,开发速度才是我们解决的最主要问题。Yii2的ActiveRecord中,每个AR类代表一个数据表,其字段作为AR类的属性,一个AR实例代表在表中的一行。常见的CRUD操作被作为AR类的方法执行。 我们使用更面向对象的方法处理我们的数据,so,开发速度就开到5挡了!

    一.mongodb安装

    1.Windows安装

    下载最新的mongodb   地址:https://www.mongodb.com/download-center    本人使用版本V3.2

    一路"下一步"完成安装。mongd为服务端,mongo为客户端。打开终端切换到bin目录

    终端中输入:

    mongod --logpath C:datadbConfmongodb.log --logappend --dbpath C:datadb --journal --bind_ip 127.0.0.1  --serviceName MongoDB --port 9898 --install

    参数说明:

    -logpath C:datadbConfmongodb.log   #设置日志path
    --dbpath C:datadb  #设置db path
    --journal   #设置数据存储格式
    --bind_ip 127.0.0.1  #防止其他ip访问 
    --port 9888   #27017修改端口
    --install      #install Windows service

    其中bind_ip与port很重要,记得一定要修改,嗯!秘密噢!

    当使用了--install后会安装到Windows的系统服务中,如果要卸载mongodb服务,使用

    sc  delete mongodb

    在Windows服务中开启mongodb服务

    在终端中输入

    mongo --port 9898

    出现如下表示成功

    2.Linux安装

    同理下载Linux版mongodb

    wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.3.tgz

    解压

    tar -zxvf mongodb-linux-x86_64-3.4.3.tgz

    移动目录到/usr/local/mongodb

    mv mongodb-linux-x86_64-3.4.3/ /usr/local/mongodb

    新建db,与log文件路径,因为mongodb数据存储在data的db目录,但安装启动不会自动生成。我们把data新建在mongodb的同级目录(放哪你自己决定)

    mkdir -p data/db
    mkdir -p data/dbconf

    启动服务

    cd bin/

    ./mongod --logpath /usr/local/mongodb/data/dbconf/mongodb.log --logappend --dbpath /usr/local/mongodb/data/db --bind_ip 127.0.0.1,201.104.104.104 --port 9898

    查看data/dbconf/mongodb.log 显示失败

    2017-03-30T09:45:14.324+0800 I CONTROL  [initandlisten] MongoDB starting : pid=513 port=9898 dbpath=/usr/local/mongodb/data/db 64-bit host=u23dk88fzrZ
    2017-03-30T09:45:14.324+0800 I CONTROL  [initandlisten] db version v3.4.3
    2017-03-30T09:45:14.324+0800 I CONTROL  [initandlisten] git version: f07437fb5a6cca07c10bafa78365456eb1d6d5e1
    2017-03-30T09:45:14.324+0800 I CONTROL  [initandlisten] allocator: tcmalloc
    2017-03-30T09:45:14.324+0800 I CONTROL  [initandlisten] modules: none
    2017-03-30T09:45:14.324+0800 I CONTROL  [initandlisten] build environment:
    2017-03-30T09:45:14.324+0800 I CONTROL  [initandlisten]     distarch: x86_64
    2017-03-30T09:45:14.324+0800 I CONTROL  [initandlisten]     target_arch: x86_64
    2017-03-30T09:45:14.324+0800 I CONTROL  [initandlisten] options: { net: { bindIp: "127.0.0.1,201.104.104.104", port: 9898 }, storage: { dbPath: "/usr/local/mongodb/data/db" }, systemLog: { destination: "file", path: "/usr/local/mongodb/data/dbconf/mongodb.log" } }
    2017-03-30T09:45:14.347+0800 E NETWORK  [initandlisten] listen(): bind() failed Cannot assign requested address for socket: 201.104.104.104:9898
    2017-03-30T09:45:14.347+0800 E NETWORK  [initandlisten] Failed to set up sockets during startup.
    2017-03-30T09:45:14.347+0800 E STORAGE  [initandlisten] Failed to set up listener: InternalError: Failed to set up sockets
    2017-03-30T09:45:14.347+0800 I NETWORK  [initandlisten] shutdown: going to close listening sockets...
    2017-03-30T09:45:14.347+0800 I NETWORK  [initandlisten] removing socket file: /tmp/mongodb-9898.sock
    2017-03-30T09:45:14.347+0800 I NETWORK  [initandlisten] shutdown: going to flush diaglog...
    2017-03-30T09:45:14.347+0800 I CONTROL  [initandlisten] now exiting
    2017-03-30T09:45:14.347+0800 I CONTROL  [initandlisten] shutting down with code:48

    因为没有让防火墙放行端口9898,开放端口

    iptables -A INPUT -p tcp -m tcp --dport 9898 -j ACCEPT

     插曲:linux用的是Centos7,默认使用的firewall防火墙必须启用iptables 链接:http://www.linuxidc.com/Linux/2015-05/117473.htm 、    http://blog.csdn.net/smstong/article/details/39317277

    然后我们使用客户端mongo连接

    ./mongo --port 9898

    已经链接成功。

    要以守护进程的形式运行mongodb,要添加fork参数:

    ./mongod --logpath /usr/local/mongodb/data/dbconf/mongodb.log --logappend --dbpath /usr/local/mongodb/data/db --bind_ip 127.0.0.1,201.104.104.104 --port 9898  --fork

    3.安装php mongodb扩展

    下载地址:http://pecl.php.net/package/mongodb

    *注 pecl提供了两个package 一个是 http://pecl.php.net/package/mongodb 另外一个是  http://pecl.php.net/package/mongo, 目前后者不在更新已经提示:This package has been superseded, but is still maintained for bugs and security fixes.

    Windows版的扩展就不多说了,找到对应的php版本.dll就可以了,我用的是php7.0.8

    修改php.ini 加入ext=php_mongodb.dll

    说说Linux版本扩展的安装

    这个是mongodb官网安装插件的说明:https://github.com/mongodb/mongo-php-driver-legacy

    下载最新版: 2017-03-20

    wget http://pecl.php.net/get/mongodb-1.2.8.tgz

     解压:

     tar vxzf mongodb-1.2.8.tgz 

    进入目录,此时就要注意了如果php是自己编译安装,在编译mongo之前的要带上php的配置path

    使用phpize命令添加外挂模块, 什么是phpize? 链接: http://www.2cto.com/kf/201111/110140.html

    /usr/local/php/bin/phpize
    ./configure --with-php-config=/usr/local/php/bin/php-config
    make
    make install

     

    貌似php7.0.8下编译一直提示:/usr/local/php/bin/php: symbol lookup error: /home/wwwroot/tools/mongodb-1.2.8/modules/mongodb.so: undefined symbol: OPENSSL_init_ssl

    解决php安装mongodb.so 扩展提示 :mongodb.so: undefined symbol: OPENSSL_init_ssl  

    非php7.0.8版本编译报错,找了好久问题是安装openssl版本的问题

    首先我们查看phpinfo,看php -i 显示的openssl支持的多少版本

    OpenSSL support enabled
    OpenSSL Library Version OpenSSL 1.0.1e-fips 11 Feb 2013
    OpenSSL Header Version OpenSSL 1.0.1e-fips 11 Feb 2013
    Openssl default config /etc/pki/tls/openssl.cnf

     然后在终端查看openssl版本

    OpenSSL 1.1.0  25 Aug 2016

    问题就在这,因为我yum update过openssl,导致php编译版本与系统现有版本不一致,使mongodb make的时候提示openssl保存有问题。

    解决办法:

    恢复之前的openssl版本在编译mongodb

    通过find / -name openssl

    /usr/bin/openssl                   OpenSSL 1.0.1e-fips 11 Feb 2013
    /usr/local/bin/openssl             OpenSSL 1.1.0  25 Aug 2016
    /usr/local/include/openssl          -------
    /usr/local/ssl/bin/openssl         OpenSSL 1.0.2c 12 Jun 2015
    /usr/local/ssl/include/openssl     --------
    /usr/local/share/doc/openssl       --------
    /usr/include/openssl               --------
    /usr/lib64/openssl                 --------
    /etc/pki/ca-trust/extracted/openssl--------

    要让终端默认使用1.0.1e版本,(Linux终端bash默认/usr/local/bin

    /usr/local/bin/
    mv openssl openssl1.1.0
    cp /usr/bin/openssl ./

    修改/usr/local/include/openssl目录中的.h文件为1.0.1e版本的文件,约72个*.h文件 (可查看opensslv.h文件获取版本)

    终端访问:

    # openssl version
    OpenSSL 1.0.1e-fips 11 Feb 2013

    修改php.ini

    extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20151012/mongodb.so

     因php由php-fpm控制,因此需要重启php-fpm,使php.ini配置生效。重启php-fpm

    参考  Linux 安装基于(PHP5.5)memcache扩展

    service php-fpm stop 
    ./php-fpm -c /usr/local/php/etc/php2.ini

    二. Yii2 配置mongodb-extensions

     可通过composer安装或手动安装

    1.通过composer安装

    官网安装说明:http://www.yiiframework.com/doc-2.0/ext-mongodb-index.html

    命令行切换到项目vendor同级目录执行

    php composer.phar require –prefer-dist yiisoft/yii2-mongodb “^2.1

    漫长等待……  执行完成后composer.json文件和在vendoryiisoft下有对应的目录生成

    "yiisoft/yii2-mongodb": "~2.1.0"

    2.通过手动安装

    下载地址:https://github.com/yiisoft/yii2-mongodb

    下载后添加到 /vendor/yiisoft/yii2-mongodb

    打开 vendoryiisoftextensions.php 在最底部添加:

     'yiisoft/yii2-mongodb' => 
      array (
        'name' => 'yiisoft/yii2-mongodb',
        'version' => '2.1.0',
        'alias' => 
        array (
          '@yii/mongodb' => $vendorDir . '/yiisoft/yii2-mongodb',
        ),
      ),

    打开  vendorcomposerautoload_psr4.php 在最底部添加:

    'yii\mongodb\' => array($vendorDir . '/yiisoft/yii2-mongodb'),

    3.配置main文件

    main-local.php 配置连接mongodb

      'mongodb' => [
                'class' => 'yiimongodbConnection',
          //'class' => 'backendmodelscoremongodbMconnection',
          # 有账户的配置
                //'dsn' => 'mongodb://demofancyecommerce:fdaVBDFS#fdfdtyg423DF23#$@localhost:27017/demofancyecommerce',
          # 无账户的配置
          'dsn' => 'mongodb://127.0.0.1:9898/mongo_test',
          //'dsn' => 'mongodb://10.10.10.252:10001/erp,mongodb://10.10.10.252:10002/erp,mongodb://10.10.10.252:10004/erp?replicaSet=terry&readPreference=primaryPreferred',
                  ],

    4. 设置gii

    设置gii生成器配置

        $config['bootstrap'][] = 'mongogii';
        $config['modules']['mongogii'] ['class']= 'yiimongodbmodelGenerator';
        $config['modules']['mongogii']['allowedIPs'] =['127.0.0.1','201.104.104.104',"::1"];

    三. ActiveRecord操作数据

    这步我们要将用ActiveRecord进行数据的CURD操作

    1.导入测试数据

    如果你是在Windows下操作,强烈建议你用MongoVUE管理工具,很NB的一个mongodb管理工具。 好,将mysql中的数据入mongodb。

    如果服务器Linux设置仅127.0.0.1可连接mongod服务端,可以参考SecureCRT端口映射转发,转发到本地对应的端口,使用 localhost:port 连接

    查看插入的集合数据

     2.生成models

    在上一步,我们已经配置了mian文件和gii,同时也给测试库的customer集合插入测试数据,现在用gii来生成models

    直接访问项目域+mongogii

    生成的路径在models/Customer.php 为了区分与comm里面的,我们将模型改名为MCustomer.php,查看代码

    namespace appmodels;
    
    use Yii;
    
    /**
     * This is the model class for collection "customer".
     *
     * @property MongoDBBSONObjectID|string $_id
     * @property mixed $id
     * @property mixed $name
     * @property mixed $province
     * @property mixed $city
     * @property mixed $town
     * @property mixed $address
     * @property mixed $lng
     * @property mixed $lat
     * @property mixed $create_time
     */
    class MCustomer extends yiimongodbActiveRecord {
    
        /**
         * @inheritdoc
         */
        public static function collectionName() {
            return ['mongo_test', 'customer'];
        }
    
        /**
         * @inheritdoc
         */
        public function attributes() {
            return [
                '_id',
                'id',
                'name',
                'province',
                'city',
                'town',
                'address',
                'lng',
                'lat',
                'create_time',
                'status',
            ];
        }
    
        /**
         * @inheritdoc
         * 参考 YII2,rules规则
         */
        public function rules() {
            return [
                [['name', 'province', 'city', 'town', 'address'], 'required'],
                [['id', 'name', 'province', 'city', 'town', 'address', 'lng', 'lat', 'create_time', 'status'], 'safe'],
                [['province', 'city', 'town'], 'integer'],
                [['name'], 'string', 'max' => 20],
            ];
        }
    
        /**
         * @inheritdoc
         */
        public function attributeLabels() {
            return [
                '_id' => 'ID',
                'id' => 'Id',
                'name' => 'Name',
                'province' => 'Province',
                'city' => 'City',
                'town' => 'Town',
                'address' => 'Address',
                'lng' => 'Lng',
                'lat' => 'Lat',
                'create_time' => 'Create Time',
            ];
        }
    
    }

    其中rules规则是自己加的,因为mongogii仅生成‘safe’规则,rules验证规则可参考: http://www.phpxs.com/post/3443/

     

    3.控制器方法

     MVC中Models已经有了,就剩Controller与View了,而最主要的就是Controller了,因为逻辑都放在控制器中了(按照大神的建议,逻辑代码应该放到Models里面)。

    其他什么都别说 然后我们吃着火锅一起唱这歌!!!上代码!!!

    MongoController.php

    /**
     * mongo controller
     */
    
    namespace appcontrollers;
    
    use Yii;
    
    class MongoController extends BaseController {
    
        public $pageSize = 10;
    
        /**
         * Index 列表首页
         */
        public function actionIndex() {
            $search = $this->post('search');
            $orderField = $this->post('orderField');
            $orderDirection = $this->post('orderDirection');
            $where = [];
            $orderby = 'id desc';
            ##################### search  ##############################  
            if ($search['name']) {  # 模糊搜索
                $where['name'] = ['$regex' => $search['name']];
            }
            if ($search['id']) {  # int 类型匹配
                $where['id'] = intval($search['id']);
            }
            ###################### orderby      #################################### 
            if ($orderField && $orderDirection) {
                $orderby = $orderField . " {$orderDirection}";
            }
            ###############   page    #####################
            if ($this->post('pageSize')) {
                $this->pageSize = $this->post('pageSize');
            }
            $_GET['page'] = '';
            if ($this->post('pageCurrent')) {
                $_GET['page'] = $this->post('pageCurrent');
            }
    
            #######################  data     ####################
            $data = appmodelsMCustomer::find()->where($where)->orderBy($orderby);
            $count = $data->count();
            $pagesize = $this->pageSize;  // 分页大小
            $pages = new yiidataPagination(['totalCount' => $count, 'pageSize' => $pagesize]);
            $model = $data->offset($pages->offset)->limit($pages->limit)->all();
            $pagge = $this->render('//' . 'default/page', ['pageSize' => $pagesize, 'pageTotal' => $count, 'page' => $_GET['page']]);
            return $this->display([
                        'alist' => $model,
                        'pages' => $pages,
                        'search' => $search,
                        'pagge' => $pagge,
            ]);
        }
    
        /**
         * 删除操作
         */
        public function actionDel() {
            $id = self::post('id'); # field id  与字段类型必须对应  (int)
            $_id = self::post('_id'); # mongoid
            # by _id
            $model = appmodelsMCustomer::findOne($_id);
            if ($model) {
                $model->delete(); # 物理删除 
            }
            # by id
            if ($id) {
                $model = appmodelsMCustomer::find()->where(["id" => intval($id)])->one();
                if ($model) {
                    $model->status = 3; # 状态删除
                    $model->save();
                }
            }
    
            if (!$model->errors) {
                self::UICallback(200, '删除成功');
            }
        }
    
        /**
         * 编辑、 新增 操作
         */
        public function actionEdit() {
            $id = $this->query('id');
            $model = appmodelsMCustomer::find()->where(["id" => intval($id)])->one();
            if (!$model) {
                $model = new appmodelsMCustomer();
            }
            return $this->display('edit', [
                        'model' => $model,
            ]);
        }
    
        /**
         * 编辑新增  保存save 操作
         */
        public function actionDataSave() {
            $_id = self::post('_id');
            $post = Yii::$app->request->post();
            # 获取省市区县及address, 通过百度解析为lng、lat经纬度保存-- 演示暂无
            $post['create_time'] = strtotime($post['create_time']);
            if ($_id) { # 编辑
                $model = appmodelsMCustomer::findOne($_id);
                $model->attributes = $post;
                $model->save();
            } else { # 新增
                $model = new appmodelsMCustomer();
                $model->attributes = $post;
                $model->save();
                #$id= $model->attributes['id']; # 获取插入数据的mongoid
            }
            if ($model->errors) {
                self::UICallback(300, '保存失败', ['node' => $model->errors]);
            } else {
                self::UICallback(200, '保存成功', ['closeCurrent' => TRUE, 'tabid' => 'monnn']);
            }
        }
    
    }

    views/mongo里面代码:

    index.php

    <?php
    use yiiootstrapActiveForm;
    ?>
    <div class="bjui-pageHeader">
        <?php
        $form = ActiveForm::begin([
                    'id' => 'pagerForm',
                    'method' => 'post',
                    'options' => ['data-toggle' => 'ajaxsearch']
        ]);
        ?>
        <input type="hidden" name="pageSize" value="${model.pageSize}" placeholder="">
        <input type="hidden" name="pageCurrent" value="${model.pageCurrent}">
        <input type="hidden" name="orderField" value="">
        <input type="hidden" name="orderDirection" value="">
        <div class="bjui-searchBar">
            <label>客户姓名:</label>
            <?php echo yiihelpersHtml::input('text', 'search[name]', $search['name'], ['size' => 12, 'placeholder' => '客户姓名']) ?>  &nbsp; &nbsp;
            <label>客户id:</label>
            <?php echo yiihelpersHtml::input('text', 'search[id]', $search['id'], ['size' => 12, 'placeholder' => '客户ID信息']) ?>  &nbsp; &nbsp;
            <button type="submit" class="btn-default" data-icon="search">查询</button>&nbsp;&nbsp;
            <a href="/mongo/edit"   class="btn btn-green" data-id="mongo_data" data-toggle="navtab" data-title="新增客户"  data-icon="plus">客户</a>
    
        </div>
        <?php ActiveForm::end(); ?>
    </div>
    <div class="bjui-pageContent tableContent">
        <table data-toggle="tablefixed" data-width="100%" data-nowrap="true">
            <thead>
                <tr>
                    <th data-order-field="id" >ID</th>
                    <th data-order-field="name">姓名</th>
                    <th>位置</th>
                    <th>经纬度</th>  
                    <th width="370">操作</th>
                </tr>
            </thead>
            <tbody>
                <?php
                if (!empty($alist)) {
                    foreach ($alist as $key => $value) {
                        ?> 
                        <tr data-id="">
    
                            <td><?php echo $value['id']; ?></td> 
                            <td><?php echo $value['name']; ?></td> 
                            <td><?php echo $value['city']; ?><?php echo $value['address']; ?></td> 
                            <td><?php echo $value['lng']; ?>,<?php echo $value['lat']; ?></td> 
                            <td> 
                                <a href="/mongo/edit?id=<?php echo $value->id;?>"   class="btn btn-orange" data-id="mongo_data" data-toggle="navtab" data-reload-warn="本页已有打开的内容,确定将刷新本页内容,是否继续?" data-title="查看客户信息"  data-icon="edit">查看</a> &nbsp;&nbsp;
                                <a href="/mongo/del"  data-toggle="doajax"  data-data="_id=<?php echo $value->{'_id'}?>&id=<?php echo $value['id'] ?>&_csrf=<?php echo Yii::$app->request->csrfToken; ?>"  class="btn btn-red row-del" data-confirm-msg="确定要删除该行信息吗?" data-icon="remove">删</a>
                            </td>
                        </tr>
                        <?php
                    }
                }
                ?>
            </tbody>
        </table>
    </div>
    <?php
    echo $pagge;

    edit.php

    <?php
    
    use yiihelpersHtml;
    use yiiootstrapActiveForm;
    ?>
    <div class="bjui-pageContent">
        <?php $form = ActiveForm::begin([ 'action' => '/mongo/data-save', 'options' => ['data-alertmsg' => 'false', 'data-toggle' => 'validate']]); ?> 
        <?php echo Html::hiddenInput('_id', $model->{'_id'}); ?>
        <table class="table table-condensed table-hover" width="100%">
            <tbody>
    
                <tr> 
                    <td colspan="2">
                        <label for="name" class="control-label x85">姓名:</label>
                        <?php echo Html::input('text', 'name', $model->name, ['data-rule' => "required", 'placeholder' => '姓名']); ?>
                    </td>
                </tr> 
                <tr>
                    <td>
                        <label for="j_custom_birthday" class="control-label x85">现居地址:</label>
                        <?php echo $this->AreaSelect(['name' => 'province', 'chkval' => $model['province'], 'area' => 'province', 'data-rule' => 'required', 'doption' => '请选择省份', 'data-nextselect' => '#employee_j_form_city', 'data-refurl' => '/comm/area?id={value}']); ?>-
                        <?php echo $this->AreaSelect(['name' => 'city', 'chkval' => $model['city'], 'area' => 'city', 'data-rule' => 'required', 'doption' => '请选择城市', 'parentid' => $model['province'], 'id' => 'employee_j_form_city', 'data-nextselect' => '#employee_j_form_town', 'data-refurl' => '/comm/area?id={value}']); ?>-
                        <?php echo $this->AreaSelect(['name' => 'town', 'chkval' => $model['town'], 'area' => 'town', 'data-rule' => 'required', 'doption' => '请选择区县', 'data-emptytxt' => '请选择区县', 'parentid' => $model['city'], 'id' => 'employee_j_form_town']); ?>
    
                    </td>
                    <td >
                        <label for="address" class="control-label x85">详细地址:</label>
                        <?php echo Html::input('text', 'address', $model->address, ['data-rule' => "required", 'id' => 'address', 'size' => 25, 'placeholder' => '详细地址']); ?>
                    </td>
                </tr>
    
    
                <tr>
                    <td colspan="2">
                        <label for="url" class="control-label x85">登记时间:</label>
                        <?php echo Html::input('text', 'create_time', $model->create_time ? date("Y-m-d", $model->create_time) : '', ['data-rule' => "required", 'data-toggle' => 'datepicker', 'data-pattern' => 'yyyy-MM-dd H:m', 'placeholder' => '登记时间', 'data-min-date' => date('Y-m-d')]); ?> 
                    </td> 
                </tr> 
    
            </tbody>
        </table>
        <?php ActiveForm::end(); ?>
    </div>
    <div class="bjui-pageFooter">
        <ul>
    
            <li><button type="button" class="btn-close" data-icon="close">取消</button></li>
            <li><button type="submit" class="btn-default" data-icon="save">保存</button></li>
    
        </ul>
    </div>

    效果:

  • 相关阅读:
    Python函数篇(2)-递归函数、匿名函数及高阶函数(已更新)
    Python函数篇(1)-函数中的形参与实参(已更新)
    Pyhton基础篇(6)-非基本数据类型 --集合(已更新)
    Pyhton基础篇(5)-基本数据类型-列表、元组、字典(已更新)
    Pyhton基础篇(4)-基本数据类型-字符串详解(已更新)
    Pyhton基础篇(3)-Pycharm安装及运算符(已更新)
    Pyhton基础篇(2)-变量、用户输入及条件语句(已更新)
    Pyhton基础篇(1)-第一个Pyhton程序(已更新)
    gallery的3D效果的实现
    android 图片二维码识别和保存(一)
  • 原文地址:https://www.cnblogs.com/dcb3688/p/4608028.html
Copyright © 2011-2022 走看看