Category Archives: 技术分享

解决CentOS下PHP system命令unoconv转PDF提示”Unable to connect or start own listener”

centos系统下,用php的system命令unoconv把word转pdf时提示Unable to connect or start own listene的解决办法

unoconv -o /foo/bar/public_html/upload/ -f pdf /foo/bar/public_html/upload/test.docx 2>&1
上面这个命令在shell 终端能执行成功,但是在php(Apache)中会报错:Unable to connect or start own listene

只需要先设置HOME变量即可:
passthru(‘export HOME=/foo/bar/public_html/upload/ && unoconv -o /foo/bar/public_html/upload/ -f pdf /foo/bar/public_html/upload/test.docx 2>&1’)

Keep-Alive中通过component多次加载同样的动态组件无法保持状态的解决办法

问题描述

项目功能上有需要动态添加组件的需求,比如tab标签功能,动态添加标签,同时添加后的标签在切换时需要保存状态,自然而然想到了keepalive,这就有了下面的代码:

一、tabPage 定义方式1:

通过components事先定义好所有会加载的组件:


tagPage
通过ref或computed的方式判断当前的标签的类型并返回:


这个时候
keep
alive是工作的,但这里的问题是:

动态创建的组件有多个是同一个组件,比如APIAdd,

由于keep alive的缓存机制是通过组件名称来缓存的,同一个组件被打开多次的话其实显示的还是第一次打开的那个,这和我们实际的应用场景不符合,不能缓存界面状态(比如表单中输入的内容)

二、tabPage 定义方式2

为了解决方式1中的同名组件只能加载一次的问题,需要同一个组件被加载多次,只是里面展示的内容不一样,所以tabPage通过defineAsyncComponent异步加载:


这里组件能加载成功,同名组件每次创建标签都会生成一个新的,但是这里的问题是:

没有起到keepalive的效果,已经加载的组件,在切换时又重新创建了组件, 状态自然也没有得到保存,

解决办法:

为了解决同一个组件可以被动态加载多次,同时需要能keepalive,解决的办法就是不用component,而是把所有动态添加的组件都各自放在一个keepalive中,根据条件切换显示即可:


这样每个组件都可以加载自己的数据,并且可以
keep
 alive保存状态:

Windows安装cygwin + swoole,并配置crontab定时任务

一、Windows安装cygwin

  • 安装包下载

自行搜索安装包进行下载,目前官网无法打开。官网地址:http://www.cygwin.com/

  • cygwin安装详细教程

1. 打开安装包:setup-x86_64.exe

2. 点击“下一页”,选择第一种方式后再点击“下一页”

3. 更改安装目录为D:\cygwin64后,点击“下一页”

4. 选择组件包的存放位置,设置为D:\cygwin64\package,然后点击“下一页”

5. 选择连接方式,选择第二种方式后点击“下一页”

6. 由于网络原因可能会出现以下情况,点击“确定”即可

7. 在User URL中输入http://mirrors.163.com/后点击“Add”,并选择它点击“下一页”

8. 进入下载包的页面,如下图所示。在Search中输入需要下载的包并选择版本,第三张图片展示了所需要的组件,将这些组件选中后点击“下一页”,如果遗漏了某一个组件也不用卸载cygwin,只需要再次打开安装包,按上述步骤执行到此处,进行搜索遗漏的组件进行选中,然后再次下载即可。

9. 最后选中创建快捷方式并点击“完成”

  • 配置环境变量

1. 在Windows系统下找到【编辑系统环境变量】,添加系统变量的路径

2. 添加到该安装文件夹中的bin文件夹下

  • 检验Cygwin是否安装成功

打开cygwin快捷方式(即命令行),输入cygcheck -c cygwin

测试gcc、gdb是否安装成功

  • 安装apt-cyg(安装后能够像Linux系统一样使用apt-get install/remove命令安装卸载软件)()

1. 下载之后解压文件

2. 打开Cygwin,输入apt-cyg install/remove vim即可安装/卸载

二、安装PHP swoole扩展

swoole 下载地址(官网下载的文件试过后不能安装,所以推荐下面):

https://gitee.com/swoole/swoole/tags

注意:5.0以上版本适用于PHP8

PHP7建议使用4.x系列的版本。

我这里下载的是swoole-v4.8.13

  • 将下载的swoole-v4.8.13解押后(也可以直接通过sourcetree克隆不用解押),放到C:\cygwin64\home文件夹中

  • 打开前面安装的 Cygwin64 Terminal 命令窗口

    进入到 D:\cygwin64\home\swoole位置

  • 打开Cygwin64安装程序,搜索php-devel后安装

  • 安装完成后,执行phpize

  • 编译./configure

  • 执行make

时间会比较长

如果出现以下错误:

则需要再打开Cygwin安装程序重新安装扩展libpcre2-devel、pcre2

  • 再次输入 make、make test、 make install 命令

  • 手动打开 “/etc/php.ini” ,添加扩展 ” extension=swoole.so”

 

  • 运行 php -m查看扩展是否开启

  • 测试运行:进入/home/swoole/examples/http目录下,执行php server.php运行 “server.php”,在浏览器中输入http://127.0.0.1:9501/,看到以下界面就表示Swoole已经运行成功了

 

三、配置crontab定时任务

  • 安装并配置crontab定时任务

1. 右键以管理员身份打开Cygwin,安装cron服务,执行以下命令

cygrunsrv -I cron -p /usr/sbin/cron -a -D

2. 安装完服务之后,需要运行以下命令启动服务(此处执行可能会有错误cygrunsrv -S cron 报错:error starting a service :QueryServiceStatus:Win32 error 1062.)

cygrunsrv -S cron

3. 执行cron-config 重新安装配置crontab

please enter the password for user ‘administrator’: (此时输入的密码(使用系统账户的密码)是看不到的,没关系直接输入;再reenter(重新输入)

4. 按win+R打开运行页面,输入services.msc后进入服务

5. 找到Cron daemon双击打开属性列表,选择“自动”并且启动该服务(这样做是防止该服务没有被启动)

6. 配置定时任务的命令介绍

crontab -e #编辑任务

crontab -l #查看任务列表

crontab -r #删除任务

cronevents #查看执行情况

7. 创建shell脚本vim /home/cron.sh

8. 使用crontab -e来创建定时任务

crontab设定时程表的格式说明:

执行crontab -e配置定时任务(每天凌晨1点执行home目录中的cron.sh脚本):00 01 * * * sh /home/cron.sh

10. 使用crontab -l来查看,如下图

11. 使用cronevents查看任务执行情况

macOS monterey 升级后安装php

macOS monterey已经完全移出了php,不再默认包含;升级后需要自行安装:

可以通过brew install 的方式安装php,但是通过该方法安装的php又无法和默认的apache配合使用,会包签名错误: No code signing authority for module at /opt/homebrew/Cellar/php/8.0.12/lib/httpd/modules/libphp.so specified in LoadModule directive.

当然可以采取对so代码自签名的方式,但实际上这不是最好的办法,因为brew install 安装的php和mac默认自带的apache之间会由于各种依赖库的问题无法跑起来

最好的办法就是停用默认的apache,然后apache和http完完全全都采用brew 来安装brew 会把依赖的各种包自行安装好

  1. sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist
  2. brew install php
  3. brew install httpd

注意brew 安装后的提示,相应的环境变量PATH都按安装后的提示设置,最好brew services start 对应的服务即可

gitlab 升级步骤

小版本升级,比如12.3.xx 升级到12.4.xx, 但是注意提示,如果升级不了会提示的:

gitlab preinstall: It seems you are upgrading from major version 13 to major version 14.

gitlab preinstall: It is required to upgrade to the latest 13.12.x version first before proceeding.

gitlab preinstall: Please follow the upgrade documentation at https://docs.gitlab.com/ee/update/index.html#upgrade-paths

  1. 下载rpm包,可以从这里下载https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ 根据自己的系统选择对应的版本
  2. gitlab-ctl stop unicorn
  3. gitlab-ctl stop sidekiq
  4. gitlab-ctl stop nginx
  5. rpm -Uvh gitlab-ce-10.8.7-ce.0.el7.x86_64.rpm
  6. gitlab-ctl restart
  7. 查看升级后的版本号 cat /opt/gitlab/embedded/service/gitlab-rails/VERSION

慎用json_decode的assoc参数

我们在工作中遇到的情况:

  1. vue 3前端界面 + php 后端 API
  2. vue 3采用typescript
  3. API数据采用json格式

出现的问题

当post api时提交的json数据中包含{}这种空JSON对象,比如style:{}, 后端php在处理过程中会变成[]并返回给前端,导致前端后续的功能出现bug,如这时再往style中设置值就不能正常工作了:style[‘foo’] = ‘bar’, 这时设置是不成功

问题的原因

原因1: typescript的强类型,如果是javascript,这点其实并不影响,JS数组可以直接设置值:var style = []; style[“foo”] = “bar”;这个操作是成功的。
原因2: 后端php在处理的过程中都是按数组格式处理:json_decode($data, true),无形中就把{}变成了php的空数组,然后返回给前端时json_encode就变成[]。

解决办法

修改后端json_decode总是按对象格式处理

Mac 11.0以上版本不能编译PHP的问题

在Mac 11.x版本编译php会提示php.h不存在,phpize也看不出php版本内容:

grep: /usr/include/php/main/php.h: No such file or directory
grep: /usr/include/php/Zend/zend_modules.h: No such file or directory
grep: /usr/include/php/Zend/zend_extensions.h: No such file or directory
Configuring for:
PHP Api Version:        
Zend Module Api No:     
Zend Extension Api No: 

这是因为新版本的mac 不在支持php了,后续可能会移除php, 通过php -v 可以看出

但实际上还没有完全移除PHP,可以查看/Library/Developer/CommandLineTools/SDKs目录下你系统版本对应的目录中usr/include/php里面的内容是否还存在,如果还存在说明php devl的头文件还在哪里,只是usr/bin/phpize找不到他们。

通过phpize的输出也不难看出,他是去usr/include/php里面找对应的头文件,那么我们建立软链接到对应的/Library/Developer/CommandLineTools/SDKs下面的php目录即可。但由于/usr/include目录是Read only的,不允许创建软链接,解决办法就是:

1. 把/usr/bin/phpize 和/usr/bin/php-config两个文件复制到/usr/local/bin,并修改如下两处内容,加上local

php-config中extension_dir也重新指定一个目录,并且把/etc/php.ini extension_dir中也同步调整:

2. 建立软连接 ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX11.1.sdk/usr/include/php /usr/local/include/php

然后使用phpize时指定全路径 /usr/local/bin/phpize

configure时指定我们修改后的php-config:/usr/local/bin/phpize ./configrue –with-php-config=/usr/local/bin/php-config

make, make install 最后把编译的so文件会拷贝到指定的extension_dir目录中


该问题解决后,可通过pear的方式来安装其他pecl 扩展了

1. 下载pear: https://pear.php.net/go-pear.phar
2. 安装: php go-pear.phar,在出现的页面中分别把1,4两步设置为如下图所示,这其实是让pecl命令在bin目录中
3. 然后就可以通过pecl按照扩展了,比如pecl install zip,会下载源码并编译,同上面的phpize & configure & make & make install

Mysql incorrect string value

这是由于mysql字段的存储字符集存储不了,比如utf8中存储不了一些表情符号,比如微信上的昵称:abc🍃,解决办法就是存储要修改对应的编码字符集,与数据库的通讯链接也要修改对应的编码字符集

  1. 把对应字段的字符集修改成utf8mb4
  2. 同时把代码中数据库链接驱动中的字符集也修改成utf8mb4,比如用pdo需要设置 :SET NAMES utf8mb4

两者少一个都不行

gitlab 备份、升级与迁移

备份

gitlab-rake gitlab:backup:create

如果是putty远程连接服务器执行该命令,可能由于某些git库太大导致putty迟迟没有反应而导致链接中断,链接中断后该命令也会终止执行,所以可以通过nohup 来把命令脱离命令行执行:

nohup gitlab-rake gitlab:backup:create 2>&1 &

通过在nohup.out 中可以查看输出日志

备份成功后在/var/opt/gitlab/backups中会产生一个类似于1610804990_gitlab_backup.tar的文件,一定要确保backup完成在copy该文件,上面的nohup.out中最后几行是下面情况时,说明备份完成了:

done
Dumping uploads …
done
Creating backup archive: 1610804990_gitlab_backup.tar … done
Uploading backup archive to remote storage … skipped
Deleting tmp directories … rake aborted!
Don’t know how to build task ‘/var/opt/backlog.log’

(See full trace by running task with –trace)
done
Deleting old backups … skipping

恢复

gitlab-rake gitlab:backup:restore BACKUP=/var/opt/gitlab/backups/1610804990

注意backup中的文件名不是完整的1610804990_gitlab_backup.tar,而只是_gitlab_backup.tar的前面部分

迁移

可以用scp把备份文件上传到目标服务器,在目标服务器上执行:scp src_username@src_ip:/var/opt/gitlab/backups/1481529483_gitlab_backup.tar /var/opt/gitlab/backups

升级

gitlab升级不能一次性跨大版本升级,比如不能6.x升级到13.x,只能在一个major版本升到最高级别后在升级到下一个major版本(版本号格式:major.minor),官方给出来的升级顺序是:

https://docs.gitlab.com/ee/update/#upgrade-paths

但我从7.6.x 升级到13.7并没有完全按照这个顺序,基本规则是升级到当前major版本的最后一个版本后,再升级到下一个major的第一个版本,一次类推直到最新版本

每个版本的镜像可以从这里下载:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/

每次升级前,先stop服务

sudo gitlab-ctl stop unicorn
sudo gitlab-ctl stop sidekiq
sudo gitlab-ctl stop nginx
数据库不要stop,在安装时是需要备份数据库的,所以不能停

wget 下载好对应的rpm包后执行 rpm -Uvh 安装包

安装包会备份数据库部分,安装新版本,删除旧版本,升级成功收gitlab-ctl restart即可