本网站主要记录/总结本人工作、生活中的经验与心得

1.PHP安装wxwork-finance-sdk

php读取企微会话存档内容时,需要通过sdk进行解密。但由于企微官方并没有php版本的sdk可以直接使用,只提供了c语言版本的源代码,因此需要自己手动进行编译成php扩展。

下面记录我如何进行将安装php版本的企微会话存档sdk的步骤。

我使用的环境是:centos7.8,php7.4(php安装路径/www/server/php/74)

1.先从github把php7-wxwork-finance-sdk下载源代码包到一个文件夹中

2.再从企微官网下载C版本的最新sdk到同一个文件夹中

3.将以上代码放到服务器中,我存档的路径为:/www/server/php/74/src/wxwork-finance-sdk

4.进入/www/server/php/74/src/wxwork-finance-sdk目录,然后执行

    /www/server/php/74/bin/phpize

    ./configure --with-php-config=/www/server/php/74/bin/php-config --with-wxwork-finance-sdk=/www/server/php/74/src/wxwork-finance-sdk

    make && make install
                    

5.找到php配置文件(php.ini),在配置文件末尾追加一行

    extension = /www/server/php/74/lib/php/extensions/no-debug-non-zts-20190902/wxwork_finance_sdk.so
                    

6.重启php服务,通过php -m查看扩展是否安装成功。如果安装成功,则到此结束。如果失败,继续往下看。

7.如果php -m查看出现报错:free(): invalid pointer,可能是由于Intl扩展导致。此时需要重新编译安装php,并取消Intl扩展。

8.如果是宝塔环境下安装的php环境,可以通过以下步骤重新编译安装php。

9.进入/www/server/panel/install/,复制一份php.sh为rphp.sh,然后执行

    sed -i 's/--enable-intl/--disable-intl/g' rphp.sh
                    

10.在宝塔管理面板,软件商店的已安装中,卸载对应的php版本(以php7.4为例)

11.在服务器中执行

    sh /www/server/panel/install/rphp.sh install 7.4
                    

12.等待编译安装,在配置文件php.ini末尾添加扩展,并重启服务。此时应该大功告成。

2.如何通过cid实现企微获客加粉的投流转化回传

广告cid的技术,简单来说就是用户在点击广告的时候,广告平台会产生一个字符串,也就是cid,并且这个cid会跟随整个广告链路,包括后续的电商订单,获客加粉。在订单数据/加粉数据入库时,可以获取到这个cid,然后将其回传给广告平台,广告平台就会自动进行转化归因。

当然,并不是所有链路都能成功带上cid参数的,有些是广告平台cid参数未生成;有些是电商平台禁止三方的cid,只允许使用自家平台的cid等,这些都会导致cid参数丢失,从而无法完成后续的广告回传。但也是有方法应对的。这个时候,就需要投放广告的时候,填写监测链接,一般填写点击的监测链接即可(注意服务器需要能扛得住监测数据的入库,可以考虑将监测数据先存入缓存,再批量入库)。此时就可以通过订单的下单时间,监测链接的时间,再配合其他字段进行cid的匹配,可获取到比较精准的cid,然后完成cid回传。

那么如何通过cid技术,完成企业在广告平台投放广告,以获得更多的客户呢?

首先,使用企微获客加粉的方式,目前主要用两种途径:获客助手和客服对话。其中获客助手需要付费(首次会赠送50个免费额度),目前企微官方的收费标准是一个名额一元,获客助手的额度有效期三个月;而客服对话方式则免费,也不需要开通会话存档服务

获客助手,是企微官方推出的客户可多终端一步直接添加好友的方案,简化了从广告到微信的转化流程,链路短,稳定,转化率高。流程是:客户点击广告 -> 进入中间落地页,点击加粉按钮(如果不用中间页,此步可省略) -> 打开微信,完成加粉

使用起来也比较简单:

    1. 购买获客助手使用量
    2. 登录企微创建获客链接
    3. 在获客链接中追加自定义参数,自定义参数为广告平台的宏
    4. 将追加了自定义参数的获客链接填写到广告计划的直达链接。如果使用中间落地页方式,则落地页按钮打开的链接为追加自定义参数的获客链接
    5. 搭配监测链接,毕竟获客链接的自定义参数长度有限制,基本超出cid的长度。
    6. 系统获取到企微的外部联系人,并成功匹配到cid后,回传给广告平台。
                    

获客助手方式虽然比较高效简单,但毕竟需要付费。而客服对话方式,则是免费方案,但中间链路多了1~2步。流程是:客户点击广告 -> 进入中间落地页,点击加粉按钮 -> 自动打开微信客服(客户无需操作) -> 微信客服自动发送已配置二维码加粉页面地址的欢迎语(客户无需操作) -> 客户点击欢迎语 -> 微信内打开加粉页面(客户无需操作) -> 长按识别二维码,完成加粉。此方案可以实现客户聊天后再回传cid到广告平台进行归因,以避免误点广告的低质量粉导致的回传转化,导致更多的广告消耗。

客服对话加粉方式的步骤:

    1. 登录企业微信管理后台,开通微信客服功能,并完成客服账号的创建
    2. 设置好欢迎语内容,欢迎语需带有广告落地页的链接
    3. 复制客服链接,并追加自定义的广告参数宏
    4. 将追加了自定义参数的客服链接,填写到广告落地页中,即落地页按钮打开的目标地址为追加自定义参数的客服链接
    5. 在客户与上下游 -> 加客户 -> 联系我,完成二维码客服的配置
    6. 搭配监测链接
    7. 系统获取外部联系人,匹配到cid后,回传给广告平台
                    

以上就是使用cid完成企微加粉的两种方式,每个方式都有自己的特点,需看情况选择。

3. php部分功能的函数封装

在工作中,经常会遇到一些重复性的功能,比如校验身份证是否正确,校验手机号是否正确,校验密码复杂度,随机生成指定长度的字符串等。

当然,这些功能在网络上大部分都已经实现,也有不少优秀的开源库可以直接使用。但如果每次需要使用的时候,都要花费时间去寻找;或者自己从零开始编写;或者仅仅因为一个小功能而引入一个庞大的第三方库,总有些得不偿失的感觉。因此,将部分常用的功能,以函数的方式总结归档起来,方便日后使用。

    校验身份证的合法性
    function isValidIdNum($id) {
        $pattern = "/^[1-9]\d{5}(18|19|20|21|22)?\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|[Xx])$/";
        if (preg_match($pattern, $id)) {
            // 验证校验码
            $weights = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
            $checkcodes = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
            $sum = 0;
            for ($i = 0; $i < 17; $i++) {
                $sum += $id[$i] * $weights[$i];
            }
            $mod = $sum % 11;
            if ($id[17] == $checkcodes[$mod]) {
                return true;
            }
        }
        return false;
    }


    校验手机号是否正确
    function isValidPhoneNum($phone){
        $pattern = '/^1[3-9]\d{9}$/';
        if (!preg_match($pattern, $phone)) {
            return false;
        }
        return true;
    }


    校验密码复杂度(必须同时存在大写字母 + 小写字母 + 数字 + 特殊符号 + 至少8位)
    function checkStringComplexity($string) {
        $pattern = '/(?=.*[a-zA-Z])(?=.*\d)(?=.*[#@!~%^&*])[a-zA-Z\d#@!~%^&*]{8,}/';
        if (!preg_match($pattern, $string)) {
            return false;
        }
        return true;
    }
    
                    

(待续...)

4. 获取日期位于本月的第几周,且给出该周的起止日

在某个项目中,遇到这么一个需求:给定一个具体到年月日的日期,计算出该日期在所属月份中,属于第几周。要求:该月份的第一个星期一是本月的时间,则这周为第一周。比如2024-12的第一周从2024-12-02开始;2024-10月的第一周从2024-10-07开始;2024-07月的第一周从2024-07-01开始。最简单的场景是,电商的周报,可以查看到每个月每周的起止日,属于第几周。

如果能获取到该日期所属月份的第一周从几号开始,那么后面就比较容易获取到该月份每周的起止日。但查看了php内置函数后,目前并未能直接通过date()函数获得理想的结果。网上也并没有找到相应的实现。

分析来看,(①)每个月最多就是5周,所以获取某个日期是第几周,那么返回的只能是1~5这几个数。(②)第一周的星期一,对应的数字肯定是小于或等于7的。(③)因此逻辑是:计算该日期所属月份的第一天在一周中的序号数a。如果a = 1,表示1号刚好是第一周的星期一,前面有0天隶属于上个月的最后一周;如果a = 0,表示2号才是第一周的星期一,前面有1天隶属于上个月的最后一周;如果是其他数值,则有8 - a天隶属于上个月的最后一周。然后用该月份的总天数减去a,再除于7即可得到给定日期在月份中属于第几周。④至于给定日期所在周的起止,就比较简单了。

经过不断测试,终于实现出来了,代码如下:

    /**
     * 获取日期位于本月的第几周 1~5
     *
     * @param $date
     * @return array 0表示不计算到本月
     */
    function getWeekNum($date)
    {
        $firstDate = date('Y-m-01', strtotime($date));
        $firstWeekday = date('w', strtotime($firstDate));
        if ($firstWeekday == 1) {
            $prefix = 0;
        } elseif ($firstWeekday == 0) {
            $prefix = 1;
        } else {
            $prefix = 8 - $firstWeekday;
        }

        $thisWeekDay = date('w', strtotime($date));
        if ($thisWeekDay == 1) {
            $weekStart = $date;
        } elseif ($thisWeekDay == 0) {
            $weekStart = date('Y-m-d', strtotime($date) - 86400 * 6);
        } else {
            $weekStart = date('Y-m-d', strtotime($date) - ($thisWeekDay -1) * 86400);
        }

        $daysInMonth = date('j', strtotime($date));
        $remain = max($daysInMonth - $prefix, 0);
        $num = ceil($remain / 7);


        return [
            'weekNum' => $num,
            'weekStart' => $weekStart,
            'weekEnd' => date('Y-m-d', strtotime($weekStart) + 86400 * 6),
        ];
    }
                    

以上得到的结果是,如果给定日期不计算到本月,那么将返回0。后续可以优化为如果结果是不计算到本月,则返回上一月的第几周和该周的起始时间。