博客

  • php 实现 远程资源上传到企业微信素材

    企业微信上传素材
    官方给的文档不是很清晰,百度了一堆,依然没有解决问题,最后使用第三包的解决问题
    Guzzle6
    文档链接:https://guzzle-cn.readthedocs.io/zh_CN/latest/overview.html
    公司的需求是oss远程的图片资源上传到企业微信,具体来看代码吧

    实例

    use GuzzleHttp\Client; //引入Guzzle Client
    
    
    public function ossToTemporary($path,$access_token)
    {
    $client = new Client(["timeout" => 2.0]);
    $path = "https://bcy-scrm.oss-cn-hangzhou.aliyuncs.com/activity/IaYJSUfDSFSbDWLWZCYFOaHaQdTEbMEd";//远程图片资源
    $url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?type=image&access_token=$access_token";//企业微信上传的图片素材的接口token自己获取
    $file_name = md5(time());
    $response = $client->request('POST', $url, [
                'multipart' => [
                    [
                        'name' => 'media',
                        "filename"=>$file_name,
                        'contents' =>file_get_contents($path),
                        'headers' => [
                            'Content-Type' => 'image/jpg'
                        ]
                    ]
                ]
            ]);
     // 注意参数 filename 必须有 Content-Type 根据自己的需要 参考企业微信的文档,如果这里不指定,将默认为    application/octet-stream 普通文件
    return json_decode((string) $response->getBody(),true);
    }
    
    
    //ps:Guzzlehttp - 如何获得Guzzle 6的回应?
    


    ————————————————
    版权声明:本文为CSDN博主「m0_37067360」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/m0_37067360/article/details/105725706

  • MySQL 报错1055

    一、问题描述

    SELECT * FROM tbluser GROUP BY sex

    当我以这条语句进行数据库查询的时候,报了个错:

    1055 – Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column  'ceb.tbluser.uid' which is not functionally dependent on columns in GROUP BY clause;  this is incompatible with sql_mode=only_full_group_by

    在网上查询之后,发现是在MySQL5.7之后,sql_mode中默认存在ONLY_FULL_GROUP_BY,SQL语句未通过ONLY_FULL_GROUP_BY语义检查所以报错。

    ONLY_FULL_GROUP_BY:ONLY_FULL_GROUP_BY要求select语句中查询出来的列必须是明确的(其他语句也是一样)。

    以  SELECT name FROM tbluser GROUP BY age  为例:name 必须是聚集函数或者在group by后的表达式age中,并且age中必须包含主键,否则也会报错。
      什么意思呢?也就是说要么前面的条件是个聚集函数,要么 GROUP BY 后面就必须包含主键。

    但是这样的话, 就很容易出现问题。因为大家习惯的mysql语句,都会有group by 字段。但是查的时候如果用不到这个字段,一般是不会写进去的。况且很多自动生成的sql 里面都会这样。你的sql 很有可能会出大问题。

    二、一劳永逸

    设置sql_mode
      可以通过修改配置文件的方式设置sql_mode,这样在数据库重启之后sql_mode的值也不会改变。 首先找到my.ini文件。

    打开该文件,在 [mysqld] 下面加上:

    sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

    我这里是只去掉了ONLY_FULL_GROUP_BY。如果放在**[mysqld]**里不起作用,那就加在最下面。

      然后重启一下mysql服务就行了。

    另外附加一些在网上看到的几种常见的sql_mode的介绍:

    • ONLY_FULL_GROUP_BY:出现在select语句、HAVING条件和ORDER BY语句中的列,必须是GROUP BY的列或者依赖于GROUP BY列的函数列。
    • NO_AUTO_VALUE_ON_ZERO:该值影响自增长列的插入。默认设置下,插入0或NULL代表生成下一个自增长值。如果用户希望插入的值为0,而该列又是自增长的,那么这个选项就有用了。
    • STRICT_TRANS_TABLES:在该模式下,如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做限制
    • NO_ZERO_IN_DATE:这个模式影响了是否允许日期中的月份和日包含0。如果开启此模式,2016-01-00是不允许的,但是0000-02-01是允许的。它实际的行为受到 strict mode是否开启的影响1。
    • NO_ZERO_DATE:设置该值,mysql数据库不允许插入零日期。它实际的行为受到 strictmode是否开启的影响2。
    • ERROR_FOR_DIVISION_BY_ZERO:在INSERT或UPDATE过程中,如果数据被零除,则产生错误而非警告。如果未给出该模式,那么数据被零除时MySQL返回NULL
    • NO_AUTO_CREATE_USER:禁止GRANT创建密码为空的用户
    • NO_ENGINE_SUBSTITUTION:如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常
    • PIPES_AS_CONCAT:将”||”视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似
    • ANSI_QUOTES:启用ANSI_QUOTES后,不能用双引号来引用字符串,因为它被解释为识别符

      ————————————————
      版权声明:本文为CSDN博主「琪丶琪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
      原文链接:https://blog.csdn.net/qq_37253891/article/details/99731476

  • tp6框架下比较isset() 和 !empty()

     tp6框架下比较isset() 和 !empty()

    isset(值) !empty(值)
    '' true false
    false true false
    null false false
    0 true false
    '0' true false
    1 true true

     

  • MySQL 中直接生成数据字典方法(需在设计时为表、字段写好备注)

    只需将最后一行的 TABLE_SCHEMA 后的值修改为自己的表名即可。

    在 Navicat 中查询后可以通过 导出结果 功能直接导出 Excel 表格,导出时记得勾上包含标题行~

    SELECT
        a.TABLE_NAME AS '表名',
        b.TABLE_COMMENT AS '表备注',
        a.COLUMN_NAME AS '字段名',
        a.COLUMN_TYPE AS '数据类型',
        a.IS_NULLABLE AS '是否可空',
    IF
        ( a.COLUMN_DEFAULT = '', '空字符串', IFNULL( a.COLUMN_DEFAULT, '无' ) ) AS '默认值',
        a.COLUMN_COMMENT AS '字段备注'
    FROM
        information_schema.COLUMNS AS a
        JOIN information_schema.TABLES AS b ON a.TABLE_SCHEMA = b.TABLE_SCHEMA 
        AND a.TABLE_NAME = b.TABLE_NAME 
    WHERE
        a.TABLE_SCHEMA = 'Database_Name' # 这里修改为数据库名
        # 单表时加上下方条件
        # AND a.TABLE_NAME = 'Table_Name' # 这里修改为表名
    ————————————————
    版权声明:本文为CSDN博主「至天」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/maxsky/article/details/85131950

  • yii migrate 建表步骤

    建表步骤:
    1、进入容器
    docker exec -it crm /bin/bash
    2、建migrate文件
    php yii migrate/create create_modules   并写好字段
    3、注册到库中
    php yii migrate
    4、执行gii 生成model文件
    域名/gii
    5、SeedController中书写填充数据
    /**
         * 行业数据填充
         * @return bool
         * @throws Exception
         */
        public function actionIndustry()
        {
            $delete_num = Industry::deleteAll();
            echo 'delete ' . $delete_num . ' industry' . PHP_EOL;
            $created_by = $this->admin()->getId();
            $columns = [‘name’, ‘created_by’, ‘created_at’, ‘updated_at’];
            $now = time();
            $data = [
                [‘直播’, $created_by, $now, $now],
                [‘物流’, $created_by, $now, $now],
                [‘游戏’, $created_by, $now, $now],
                [‘金融’, $created_by, $now, $now],
                [‘电商’, $created_by, $now, $now],
            ];

            $query = Industry::find()->createCommand()->batchInsert(Industry::tableName(), $columns, $data);
            echo $query->getRawSql() . PHP_EOL;
            $query->query();
            echo 'industry seed success' . PHP_EOL;
            return true;
        }
    6、执行填充命令
     php yii seed/industry
     
     
     

  • yii2 事务的用法

    方法一:

    $transaction = Yii::$app->db->beginTransaction();
    try {
        /*
        * 业务代码段
        */
        $transaction->commit();
    }catch (\Exception $exception){
        $transaction->rollBack();
        throw $exception;
    }

    方法二:

    Models::getDb()->transaction(function ($db) use ($data) {
        /*
      * 业务代码段
      */
    });
  • php获取当前毫秒时间戳

    最近在做一个智能家居项目的后台,需要实时上传用户对智能设备的配置信息到服务器,以便实现同步,因此对于时间的精确度要求比较高,最开始直接是用php的time()函数来获取时间戳,获取的时间精确到秒级别,如果客户端同时操作的话还是有可能产生冲突,因此建议将时间戳精度提高到毫秒级别,但是在php没有自带的函数能获取毫秒时间戳,但提供了一个microtime()函数,如果调用时不带可选参数,本函数以 "msec sec" 的格式返回一个字符串,其中 sec 是自 Unix 纪元(0:00:00 January 1, 1970 GMT)起到现在的秒数,msec 是微秒部分。字符串的两部分都是以秒为单位返回的。

    microtime()函数的详细说明,可以到w3chool上面看看《PHP microtime() 函数》。

    <?php
    echo microtime();
    //输出结果是
    //0.25139300 1138197510
    

     注意了,它的结果是分两部分的,也就是前半部分是毫秒(但是单位是秒),后半部分是秒。
    现在,我们依据这个做下修改,如下:

    <?php
    list($msec, $sec) = explode(' ', microtime());
    $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    

    这样就可以了,$msectime就是当前的毫秒数!可以将这两行封装成一个函数方便使用。

    <?php
    //返回当前的毫秒时间戳
    function msectime() {
      list($msec, $sec) = explode(' ', microtime());
      $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    
      return $msectime;
    }
    

    注意:sprintf('%.0f', $num) 是输出不含小数部分的浮点数

    事情还没有结束,我把时间戳改成毫秒级别后,再次更新数据库数据时,却提示超出范围,原来之前我在数据库中是用int型来存储time()函数获取的秒级别的时间戳,存储范围是够的,改成毫秒级别的,就得改成BIGINT类型了。

    整数类型         字节          范围(有符号)            范围(无符号)                用途 

    TINYINT           1字节        (-128,127)                       (0,255)                    小整数值 

    SMALLINT          2字节     (-32 768,32 767)                    (0,65 535)                 大整数值 

    MEDIUMINT         3字节    (-8 388 608,8 388 607)               (0,16 777 215)             大整数值 

    INT或INTEGER      4字节   (-2 147 483 648,2 147 483 647)       (0,4 294 967 295)            大整数值 

    BIGINT            8字节   (-9 233 372 036 854 775 808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值 

     
    来源:https://www.cnblogs.com/opensmarty/p/11377624.html

  • docker容器php镜像安装pdo、pdo_mysql扩展

    php镜像提供了docker-php-ext-install快捷方式

    #pdo
    docker-php-ext-install pdo
    #pdo_mysql
    docker-php-ext-install pdo_mysql

     

     

    原文链接:https://blog.csdn.net/yl096815/article/details/107178142/

  • 如何增加php内存?

    运行PHP程序,通常会遇到“Fatal Error: Allowed memory size of xxxxxx bytes exhausted”的错误, 这个意味着PHP脚本使用了过多的内存,并超出了系统对其设置的允许最大内存。解决这个问题,首先需要查看你的程序是否分配了过多的内存,在程序没有问题的情况下,你可以通过一下方法来增加PHP的内存限制(memory_limit)。

    检查php的内存限制值
    为了查看这个值,你需要建立一个空的php文件,比如view-php-info.php。然后将一下代码贴到里面。
    <?php
    phpinfo();
    ?>

    将这个脚本放到你的Web服务器上,然后在浏览器中调用它。这时你可以看到你的PHP环境配置的信息,其中有一部分是关于“memory_limit”的

    注:你可以用这种方法来查看php的其他参数设置,不仅仅是memory_limit。

    memory_limit应该设为多少?

    这个完全依赖于你的应用的要求。比如Wordpress,运行起核心代码需要32MB。Drupal 6则要求这个值最小为16MB,并推荐设置为32MB。如果你又安装不少的插件(plugins),尤其是那些要进行图像处理的模块,那么你可能需要128MB或更高的内存。

    如何设置memory_limit?

    方法1:.htaccess

    说明: 这种方法只有在php以Apache模块来执行时才生效。 在你的网站的根目录下找到“.htaccess”文件,如果没有,可以自己创建一个。然后把以下配置放入其中php_value memory_limit 128M ; 可以将128M改为任何你想设置的值。

    方法2:运行时修改php的内存设置
    在你的php代码中增加以下命令行即可。

    ini_set('memory_limit','128M');

    memory_limit修改失败

    方法3:php.ini
    最简单或常用的方法是修改php.ini
    1.首先找到对你的网站生效的php.ini文件 由于有多个地方都可以设置php的参数,找到正确的配置文件,并进行更改是首先要做的一步。如果你上面的方法建立了php文件来查看其配置参数,则你可以找到“Loaded Configuration File”这一项,以下是个例子:

    对于Linux用户,你可以通过执行“php -i | grep Loaded Configuration File”来找到对应的配置文件。而Windows用户,你可以尝试修改你的php安装目录下的php.ini。

    2.编辑php.ini 在php.ini中,找到“memory_limit”这一项,如果没有,你可以在文件的尾部自己增加这个参数。以下是一些设置范例
    memory_limit = 128M ; 可以将128M改为任何你想设置的值,保存文件。

    3.重启web 服务器 如果是web服务器使用Apache, 则执行:
    httpd restart

    有些情况下,你可能不被允许私修改php.ini。比如如果你购买了虚拟主机服务,但是你的服务商确禁止你修改这个文件。那么,你可以需要考虑用其他方法来增加memory_limit的值。

    如果你使用虚拟主机,有可能会出现memory_limit的值修改失败。这个需要联系你的服务商帮你处理。

     

    本文来源php中文网:https://www.php.cn/php-ask-430035.html

  • Redis 使用

    Redis 命令

    Redis 命令用于在 redis 服务上执行操作。

    要在 redis 服务上执行命令需要一个 redis 客户端。Redis 客户端在我们之前下载的的 redis 的安装包中。

    1、启动 redis 客户端

    $ redis-cli
    redis 127.0.0.1:6379>
    redis 127.0.0.1:6379> PING
    PONG

    在以上实例中我们连接到本地的 redis 服务并执行 PING 命令,该命令用于检测 redis 服务是否启动。


    2、在远程服务上执行命令

    如果需要在远程 redis 服务上执行命令,同样我们使用的也是 redis-cli 命令。

    语法

    $ redis-cli -h host -p port -a password

    实例

    以下实例演示了如何连接到主机为 127.0.0.1,端口为 6379 ,密码为 mypass 的 redis 服务上。

    $redis-cli -h 127.0.0.1 -p 6379 -a "mypass"
    redis 127.0.0.1:6379>
    redis 127.0.0.1:6379> PING
    PONG