my blog my blog

Category: PHP
PHP7环境下使用OPcache提高WordPress网站性能8倍

奶牛一直以为自己的服务器都开了OPcache,但是后来发现只是编译了,但是没有启用,今天启用了PHP7的OPcache,来发一份儿体验报告。

配置OPcache

配置文件为/usr/local/php/etc/php.ini,添加内容

[zend opcache]
zend_extension="/usr/local/php/lib/php/extensions/no-debug-non-zts-20170718/opcache.so"
opcache.force_restart_timeout=3600
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable=1
opcache.enable_cli=1

其中的zend_extension为你服务器编译后opcache.so文件的位置。

OPcache性能测试

载入时间数据比较:

OPcache载入时间比较

性能比较:

OPcache性能比较

测试结论

经过奶牛的测试,在服务器未启用WordPress cache插件的时候,CPU的飙升是非常厉害的,严重影响服务器性能,因此无WordPress插件的情况下,并未完全遵从1000次测试,但是图表已经完全可以说明性能的比较了。

WordPress的cache插件对网站性能提升至关重要,OPcache的存在也能最大性能的提升WordPress服务器的性能,对比而言,OPcache可以提升PHP7约3倍的性能,WordPress的cache插件可以提升约4~5倍的性能,WordPress启用cache插件并且在PHP7下启用OPcache,性能提升8倍。

所以,奶牛强烈建议WordPress的用户使用PHP7并开启OPcache,并且为WordPress安装一款cache插件,保证服务器的性能最优。

Nginx服务器配置多域名指向同服务器

 

当我们用Nginx服务器添加新的虚拟主机的时候,都会生成一个vhost的conf文件,当我们把同一个域名的@和www两个地址都直接A解析到Nginx服务器的时候,会发现只有我们添加的vhost里面的那个域名会被正常解析,如果我们想把@和www两个地址都直接解析到这个vhost上,我们可以这样做。

  1. vim /usr/local/nginx/conf/vhost/www.nenew.net.conf 
  2. 修改字段server_name,比如如下方式 
  3. server_name nenew.net www.nenew.net; 

这样子可以直接将nenew.net和www.nenew.net都指向到这个vhost而不用什么301 302那种跳转,好久不搞linux了,奶牛打算弄个新站,重新拾起web。

设置完成后重启Nginx就搞定了。

Nginx为网站目录设置密码保护

 

在Nginx的nginx.conf里面有如下的字段

  1. server
  2.     {
  3.         listen 80 default_server;
  4.         #listen [::]:80 default_server ipv6only=on;
  5.         server_name www.nenew.net;
  6.         index index.html index.htm index.php;
  7.         root  /home/wwwroot/default;
  8.         #error_page   404   /404.html;
  9.         include enable-php.conf;
  10.         location /nginx_status
  11.         {
  12.             stub_status on;
  13.             access_log   off;
  14.         }
  15.         location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
  16.         {
  17.             expires      30d;
  18.         }
  19.         location ~ .*\.(js|css)?$
  20.         {
  21.             expires      12h;
  22.         }
  23.         location ~ /\.
  24.         {
  25.             deny all;
  26.         }
  27.         access_log  /home/wwwlogs/access.log  access;
  28.     }
  29. include vhost/*.conf;
  30. }

如果我们想在默认的目录添加密码保护,只保护对目录的访问,也就是登陆这个目录就会输入密码,则我们这样设置

  1. server
  2.     {
  3.         listen 80 default_server;
  4.         #listen [::]:80 default_server ipv6only=on;
  5.         server_name www.nenew.net;
  6.         index index.html index.htm index.php;
  7.         root  /home/wwwroot/default;
  8.         #error_page   404   /404.html;
  9.         include enable-php.conf;
  10.         location /nginx_status
  11.         {
  12.             stub_status on;
  13.             access_log   off;
  14.         }
  15.         location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
  16.         {
  17.             expires      30d;
  18.         }
  19.         location ~ .*\.(js|css)?$
  20.         {
  21.             expires      12h;
  22.         }
  23.         location ~ /\.
  24.         {
  25.             deny all;
  26.         }
  27.         location / 
  28.         {        
  29.   auth_basic “Restricted”;
  30. auth_basic_user_file pass_file;
  31. }
  32.         access_log  /home/wwwlogs/access.log  access;
  33.     }
  34. include vhost/*.conf;
  35. }

其中pass_file是密码文件的绝对路径,密码文件是由用户名和函数 crypt加密的密码组成,可以使htpasswd -c -d pass_file username 来生成。

Ubuntu下shadowsocks多用户后端manyuser+前端sspanel搭建教程

 

好吧,很多东西还是有个前端管理起来比较方便,奶牛今天也配了个,写下过程记录下。

安装shadowsocks支持

  1. apt-get install python-pip python-m2crypto
  2. pip install cymysql

安装LNMP

  1. wget -c http://soft.vpser.net/lnmp/lnmp1.2-full.tar.gz && tar zxf lnmp1.2-full.tar.gz && cd lnmp1.2-full && ./install.sh lnmp

后端安装配置

  1. git clone -b manyuser https://github.com/mengskysama/shadowsocks.git 
  2. cd ./shadowsocks/shadowsocks 
  3. vim Config.py 
  4.     #Config 
  5.     MYSQL_HOST = 'localhost' #这一行是服务器IP,127.0.0.1表示本机 
  6.     MYSQL_PORT = 3306 #数据库端口号 
  7.     MYSQL_USER = 'nenew' #数据库用户名 
  8.     MYSQL_PASS = 'nenew' #数据库密码 
  9.     MYSQL_DB = 'shadowsocks' #数据库名称 
  10.  
  11.     MANAGE_PASS = 'ss233333333' 
  12.     #if you want manage in other server you should set this value to global ip 
  13.     MANAGE_BIND_IP = '127.0.0.1' 
  14.     #make sure this port is idle 
  15.     MANAGE_PORT = 23333 
  16.  
  17. python server.py 

在mysql数据库中新建数据库shadowsocks,并添加用户nenew,导入manyuser中的sql文件,然后执行python server.py。如果没有异常,则表示已经安装成功后端。

前端安装:

  1. lnmp vhost add 

添加虚拟主机,然后进入虚拟主机目录

  1. wget https://github.com/orvice/ss-panel/archive/master.zip 
  2. unzip master.zip 
  3. rm master.zip 
  4. mv -f ss-panel-master/* ./ 
  5. mv lib/config-simple.php lib/config.php 
  6. vim lib/config.php 

编辑配置信息,然后将lib文件夹下的sql文件都导入到nenew数据库中。

添加守护进程supervisor:

  1. apt-get install supervisor 
  2. echo_supervisord_conf > /etc/supervisor/supervisord.conf 
  3. vim /etc/supervisor/supervisord.conf 

将文件最后添加

  1. [program:shadowsocks] 
  2. command=python /root/shadowsocks/shadowsocks/server.py -c /root/shadowsocks/shadowsocks/config.json 
  3. autorestart=true 
  4. user=root 

其中的目录自己根据实际情况设置,重启即可。

前端github:https://github.com/orvice/ss-panel

后端github:https://github.com/mengskysama/shadowsocks

顺带广告,ss服务器150元每年,需要者联系,联系方式见杂货铺。

wordpress主题制作去除wp_nav_menu()函数生成li标签教程

 

奶牛想要写一个wordpress主题,把Twenty Thirteen给做个大手术吧,换上自己需要的东西,今天开始。问题好多,php不熟,wp函数不熟,一个问题,查了半天,代码一行,搞定。

  1. <?php echo strip_tags(wp_nav_menu( array( 'container' => false,'echo' =>false,'items_wrap' => '%3$s','before'=>'<div class="element">','after'=>'</div>') ),"<div><a>"); ?> 

解析下,首先是wp_nav_menu的参数,container就是外面默认包裹的ul标签,这个直接去掉,echo这个参数是把函数的结果作为一个值返回而不是直接输出,items_wrap是单条链接的输出,直接输出即可,before和after这里可以用div来做包裹,自己根据个人需要来,最后就是strip_tags函数了,直接strip_tags("something","tag")将不需要剔除的标签保留,需要剔除的剔除。

php的preg_match_all函数手册

 

preg_match_all

(PHP 4, PHP 5)

preg_match_all执行一个全局正则表达式匹配

说明

int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )

搜索subject中所有匹配pattern给定正则表达式 的匹配结果并且将它们以flag指定顺序输出到matches中.

在第一个匹配找到后, 子序列继续从最后一次匹配位置搜索.

参数

pattern

要搜索的模式,字符串形式。

subject

输入字符串。

matches

多维数组,作为输出参数输出所有匹配结果, 数组排序通过flags指定。

flags

可以结合下面标记使用(注意不能同时使用PREG_PATTERN_ORDERPREG_SET_ORDER):

PREG_PATTERN_ORDER

结果排序为$matches[0]保存完整模式的所有匹配, $matches[1] 保存第一个子组的所有匹配,以此类推。

<?php
preg_match_all
("|<[^>]+>(.*)</[^>]+>|U",
    
"<b>example: </b><div align=left>this is a test</div>",
    
$outPREG_PATTERN_ORDER);
echo 
$out[0][0] . ", " $out[0][1] . "\n";
echo 
$out[1][0] . ", " $out[1][1] . "\n";
?>

以上例程会输出:

<b>example: </b>, <div align=left>this is a test</div>
example: , this is a test

因此, $out[0]是包含匹配完整模式的字符串的数组, $out[1]是包含闭合标签内的字符串的数组。

PREG_SET_ORDER

结果排序为$matches[0]包含第一次匹配得到的所有匹配(包含子组), $matches[1]是包含第二次匹配到的所有匹配(包含子组)的数组,以此类推。

<?php
preg_match_all
("|<[^>]+>(.*)</[^>]+>|U",
    
"<b>example: </b><div align=\"left\">this is a test</div>",
    
$outPREG_SET_ORDER);
echo 
$out[0][0] . ", " $out[0][1] . "\n";
echo 
$out[1][0] . ", " $out[1][1] . "\n";
?>

以上例程会输出:

<b>example: </b>, example:
<div align="left">this is a test</div>, this is a test
PREG_OFFSET_CAPTURE

如果这个标记被传递,每个发现的匹配返回时会增加它相对目标字符串的偏移量。 注意这会改变matches中的每一个匹配结果字符串元素,使其 成为一个第0个元素为匹配结果字符串,第1个元素为 匹配结果字符串在subject中的偏移量。

如果没有给定排序标记,假定设置为PREG_PATTERN_ORDER

offset

通常, 查找时从目标字符串的开始位置开始。可选参数offset用于 从目标字符串中指定位置开始搜索(单位是字节)。

Note:

使用 offset 参数不同于传递 substr($subject, $offset) 的 结果到 preg_match_all() 作为目标字符串,因为 pattern 可以包含断言比如^$ 或者 (?<=x) 。 示例查看 preg_match()

返回值

返回完整匹配次数(可能是0),或者如果发生错误返回FALSE

更新日志

版本说明
5.4.0参数matches成为可选的。
5.3.6如果 offset 大于 subject 的程度,将返回 FALSE
5.2.2子命名分组语法可以接受(?<name>)(?’name’)以及 (?P<name>)了。 之前版本仅接受(?P<name>)方式。
4.3.3增加了offset参数。
4.3.0增加了PREG_OFFSET_CAPTURE标记。

范例

Example #1 查找所有文本中的电话号码。

<?php
preg_match_all
("/\(?  (\d{3})?  \)?  (?(1)  [\-\s] ) \d{3}-\d{4}/x",
                
"Call 555-1212 or 1-800-555-1212"$phones);
?>

Example #2 查找匹配的HTML标签(贪婪)

<?php
//\\2是一个后向引用的示例. 这会告诉pcre它必须匹配正则表达式中第二个圆括号(这里是([\w]+))
//匹配到的结果. 这里使用两个反斜线是因为这里使用了双引号.
$html "<b>bold text</b><a href=howdy.html>click me</a>";

 

preg_match_all("/(<([\w]+)[^>]*>)(.*?)(<\/\\2>)/"$html$matchesPREG_SET_ORDER);

foreach ($matches as $val) {
    echo 
"matched: " $val[0] . "\n";
    echo 
"part 1: " $val[1] . "\n";
    echo 
"part 2: " $val[2] . "\n";
    echo 
"part 3: " $val[3] . "\n";
    echo 
"part 4: " $val[4] . "\n\n";
}
?>

以上例程会输出:

matched: <b>bold text</b>
part 1: <b>
part 2: b
part 3: bold text
part 4: </b>

matched: <a href=howdy.html>click me</a>
part 1: <a href=howdy.html>
part 2: a
part 3: click me
part 4: </a>

Example #3 使用子命名组

<?php

 

$str = <<<FOO
a: 1
b: 2
c: 3
FOO;

preg_match_all('/(?P<name>\w+): (?P<digit>\d+)/'$str$matches);

/* 下面代码在php 5.2.2(pcre 7.0)或更高版本下工作, 不过, 为了向后兼容
 * 推荐使用上面的方式. */
// preg_match_all('/(?<name>\w+): (?<digit>\d+)/', $str, $matches);

print_r($matches);

?>

以上例程会输出:

Array
(
    [0] => Array
        (
            [0] => a: 1
            [1] => b: 2
            [2] => c: 3
        )

    [name] => Array
        (
            [0] => a
            [1] => b
            [2] => c
        )

    [1] => Array
        (
            [0] => a
            [1] => b
            [2] => c
        )

    [digit] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [2] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

)