DiscuzX 固定顶部格子广告的列数

DiscuzX的顶部的格式广告的列数,是再3,4,5之间自动变化的.

具体的代码位于:

source/class/adv/adv_text.php, 从97行开始:

 
$advcount = count($adids);
if($advcount > 5) {
		$minfillpercent = 0;
		for($cols = 5; $cols >= 5; $cols--) {
			if(($remainder = $advcount % $cols) == 0) {
				$advcols = $cols;
			break;
		} elseif($remainder / $cols > $minfillpercent)  {
			$minfillpercent = $remainder / $cols;
			$advcols = $cols;
		}
	}
} else {
	$advcols = $advcount;
	}
因此我们可以看到格子广告的列数再3,4,5之间动态变化,如果要固定列数,只需要把for循环的两个5改成4或者3就可以了

ERROR 2006 (HY000): MySQL server has gone away

当你要导入一个比较大的mysql数据库的时候,可能会产生这个错误:

mysql> source file.sql
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 2
Current database: *** NONE ***

ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 3
Current database: *** NONE ***

这是因为max_allowed_packet设置的太小了,再/etc/my.cnf中,将这个参数设置为64M或者根据实际情况设为更大的值就可以了

max_allowed_packet=64M

mysql文档:

https://dev.mysql.com/doc/refman/5.5/en/replication-features-max-allowed-packet.html

 

Centos 7 Postfix使用第三方的smtp

参见前一篇文章,阿里云的ecs全部关闭了25端口,因此我们只能使用postfix来通过第三方的smtp服务发送一些系统邮件,比如说报警邮件.

这些第三方服务商一般提供25,587端口的smtp的服务,这里我们选择使用587端口

假设你的服务器的hostname是beta.iamhippo.com, 在/etc/aliases 中设定

root    [email protected]

表示所有发向root的邮件都转发到[email protected], 下面是详细的步骤:

1) 安装必须的library

centos/redhat/fedora:

yum install cyrus-sasl-plain

debian/ubuntu:

apt-get install libsasl2-modules

如果你不安装cyrus或者libsasl库,你会得到“no mechanism found error”

2) 设置smtp的用户名,密码

postfix的smtp的用户名和密码位于/etc/postfix/sasl_password

vi /etc/postfix/sasl_password

按照下面的格式添加验证信息:

[mail.isp.example]:587 username:password

我们需要hash一些这个文件来给postfix使用

postmap /etc/postfix/sasl_passwd

一切都正常的情况下,你会在这个目录/etc/postfix目录下看到sasl_passwd.db文件

必要的安全设置:

chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db

3) 设置generic map

如果我们是通过配置csf,让系统自动发送报警邮件,那么一般是来自于[email protected], 我们想在邮件中替换这个邮件的话,可以使用generic的功能,比如说我们想把[email protected] 改成[email protected], 那么可以这么写:

[email protected] [email protected]

然后和sasl_password 一样,我们需要hash 一下

postmap /etc/postfix/generic
chown root:root /etc/postfix/generic /etc/postfix/generic.db
chmod 0600 /etc/postfix/generic /etc/postfix/generic.db

4) 配置reply server

这个配置起来就比较简单了,直接打开/etc/postfix/main.cf文件,在最末尾添加:

# specify SMTP relay host
relayhost = [mail.isp.example]:587


# enable SASL authentication
smtp_sasl_auth_enable = yes
# disallow methods that allow anonymous authentication.
smtp_sasl_security_options = noanonymous
# where to find sasl_passwd
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
# Enable STARTTLS encryption
smtp_use_tls = yes
# where to find CA certificates
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
# where to find generic
smtp_generic_maps = hash:/etc/postfix/generic

保存配置,然后重启postfix

systemctl restart postfix

当然了,建议在重启之前先把postfix 中的queue mails 都删掉。。要不然积累了大量的邮件会一次性发出的

postsuper -d ALL

或者

postfix -f

或者

postfix flush

查看mail queue:

mailq

 

阿里云邮件推送的坑

国内的服务器一直在使用阿里云的,没有办法目前的情况下阿里云确实是国内的No.1

阿里云的ecs默认是关掉25端口的,就算是你申请解封25端口成功了,你也无法用25端口发信,他只允许你用25端口连接到其他的smtp服务器来发信.

使用阿里云的服务,自然而然的想到阿里云的邮件推送服务,而且他还赠送一部分免费的额度,对于我们这种只需要发送触发邮件的人来说,这是非常合适的.

但是这里的一个坑就是smtp协议下只支持25,80,465端口,而465端口一般用来支持STARTTLS, 这个协议比较老,国际标准化组织已经不再推荐,很多的程序例如iredmail默认已经不支持这个端口了。如果你使用的是debian,ubuntu的话,那么这是没有任何问题的,因为自带的postfix 的版本相对来说要新很多, 是3.0 的版本,支持465端口. 如果你使用的是centos7 并且使用的是自带的postfix的话,那么恭喜你,你获奖了。。。

centos7自带的postfix的版本相对来说要低很多,是2.10的版本。。。

而且postfix 的2.10的版本,对于465端口,也就是smtps并不是很支持,你需要使用的stunnel的转发smtps的请求. 详细请看这里:

http://www.postfix.org/TLS_README.html#client_smtps

网上铺天盖地的教程都是apt-get, 我想他们可以也没有想到在centos7 里面会出现问题,不值得花时间去演就演stunnel,那么多的提供标准服务的smtp服务商,舍弃阿里云推送就好了.

如果你的网站位于国外,那么你可以使用sendgrid或者mailgun,都是非常的方便

PHP7 兼容性检测

PHP 7 都出到7.4 了,是时候把手中的discuz论坛升级到PHP 7了,考虑了半天兼容性的问题,准备升级到php 7.3

discuz 的主程序已经升级到最新的discuz 20191201版本了,兼容PHP 7.3应该是没有问题,剩下的就是安装的那些插件的兼容性的问题.

检测PHP7 的兼容性,我们这里使用主流的PHPCompatibility 配合PHP Code_Sniffer

https://github.com/squizlabs/PHP_CodeSniffer
https://github.com/PHPCompatibility/PHPCompatibility

PHPCompatibility 是PHP Code_Sniffer 的插件,因此我们应该先安装PHP Code_Sniffer, 在github上有很多中的安装方式,这里我们选择最近的wget 或者curl下载二进制程序,然后把二进制程序放到全局去

# Download using curl
curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar

# Or download using wget
wget https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
wget https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar

# register as global commands
mv phpcs.phar phpcs
mv phpcbf.phar phpcbf
chmod 755 phpcs
chmod 755 phpcbf
mv phpcs /usr/local/bin/
mv phpcbf /usr/local/bin/

这样就安装完了phpcs,下一步我们需要下载PHPCompatibility这个插件,并且让phpcs使用这个插件

# Download PHPCompability
cd ~
wget https://github.com/PHPCompatibility/PHPCompatibility/archive/9.3.5.zip
unzip 9.3.5.zip
# path is /root/PHPCompability9.3.5
# config phpcs to use PHPCompatibility
phpcs --config-set installed_paths /root/PHPCompability9.3.5

这样phpcs就可以使用PHPCompatibility9.3.5了,当然了也可以使用git的形式来下载,这样更新PHPCompatibility比较方便

加入说我们需要检查的文件folder 是/home/plugin, 那么我们就可以用

phpcs -p --standard=PHPCompatibility --runtime-set testVersion 7.3 --report-full=/home/php.log /home/plugin

-p: 打印progress到console上面

–standard: 表示使用哪个标准

–runtime-set testVersion 7.3 : 表示用PHP7.3的标准来检查

–report-full: 表示将结果输出到某一文件

 

检查完毕,删掉了不兼容php7.3 的插件,然后就开始准备升级discuz到7.3了

AWS Lightsail Singapore Benchmark

AWS对于IO的限制,配置越高,限制越少,这里我们benchmark 一下80刀的这一款,4 cores,16GB RAM, 320GB SSD

测试使用的程序:

wget -qO- bench.sh | bash

下面是结果:

----------------------------------------------------------------------
CPU model : Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz
Number of cores : 4
CPU frequency : 2399.858 MHz
Total size of Disk : 320.0 GB (1.1 GB Used)
Total amount of Mem : 15883 MB (171 MB Used)
Total amount of Swap : 0 MB (0 MB Used)
System uptime : 0 days, 0 hour 9 min
Load average : 0.15, 0.15, 0.09
OS : CentOS 7.6.1810
Arch : x86_64 (64 Bit)
Kernel : 3.10.0-957.1.3.el7.x86_64
----------------------------------------------------------------------
I/O speed(1st run) : 134 MB/s
I/O speed(2nd run) : 130 MB/s
I/O speed(3rd run) : 130 MB/s
Average I/O speed : 131.3 MB/s
----------------------------------------------------------------------

测试了几次,基本都是这个IO速度

 

PHP SimpleXMLElement 对象

今天在用RedbeanPHP 写数据库接口的时候,发现从SimpleXMLElement对象里面出来的值,按理说都是string, 怎么也不能赋值给RedbeanPHP, 用var_dump看了一下,发现SimpleXMLElement对象比较有意思,里面嵌套的对象以及property 的type 都是object,而且都是SimpleXMLElement 对象,在google上搜了一下发现问这个问题的不少。

https://stackoverflow.com/questions/416548/forcing-a-simplexml-object-to-a-string-regardless-of-context

比如说XML是这样的:

<channel>
<item>
<title>This is title 1</title>
</item>
</channel>

下面这样确实能够输出string:

$xml = simplexml_load_string($xmlstring);
echo $xml->channel->item->title;

但是除了echo 以外,下面这样就不能被当成string了

$foo = array( $xml->channel->item->title );

这是因为$XML->channel->item->title 的type 其实仍然为SimpleXMLElement的对象

我们可以用typecast来解决这个问题:

$foo = array( (string) $xml->channel->item->title );

The above code internally calls __toString() on the SimpleXMLObject. This method is not publicly available, as it interferes with the mapping scheme of the SimpleXMLObject, but it can still be invoked in the above manner.

另外看到有人这么写也可以:

$foo = array( $xml->channel->item->title.'' );

通过gettype查看确实变成了string,具体原理不知道